Add pwn challenges
This commit is contained in:
parent
9fc78dc013
commit
55a9ec93f2
BIN
pwn/35-shades-of-wasm/35ShadesOfWasm.tar.gz
Normal file
BIN
pwn/35-shades-of-wasm/35ShadesOfWasm.tar.gz
Normal file
Binary file not shown.
16
pwn/35-shades-of-wasm/35ShadesOfWasm/Dockerfile
Normal file
16
pwn/35-shades-of-wasm/35ShadesOfWasm/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
FROM debian:bookworm-slim@sha256:ea5ad531efe1ac11ff69395d032909baf423b8b88e9aade07e11b40b2e5a1338
|
||||||
|
|
||||||
|
EXPOSE 1337
|
||||||
|
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive; \
|
||||||
|
apt -y update; \
|
||||||
|
apt -y install socat
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY chall/chall app
|
||||||
|
COPY chall/flag.txt flag.txt
|
||||||
|
|
||||||
|
CMD socat -T 60 \
|
||||||
|
TCP-LISTEN:1337,nodelay,reuseaddr,fork \
|
||||||
|
EXEC:"stdbuf -i0 -o0 -e0 /app/app",stderr
|
8
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/Makefile
Normal file
8
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
build: wasm_host/src/main.rs
|
||||||
|
cd wasm_host && cargo build --release && cd ..
|
||||||
|
cp wasm_host/target/release/wasm_host chall
|
||||||
|
|
||||||
|
debug: wasm_host/src/main.rs
|
||||||
|
cd wasm_host && cargo build && cd ..
|
||||||
|
|
||||||
|
all: build
|
BIN
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/chall
Executable file
BIN
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/chall
Executable file
Binary file not shown.
1
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/flag.txt
Normal file
1
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/flag.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
gctf{NotTheFlag}
|
1940
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/wasm_host/Cargo.lock
generated
Normal file
1940
pwn/35-shades-of-wasm/35ShadesOfWasm/chall/wasm_host/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "wasm_host"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.75"
|
||||||
|
base64 = "0.21.5"
|
||||||
|
wasmtime = "=6.0.0"
|
||||||
|
wasmtime-wasi = "=6.0.0"
|
||||||
|
cranelift-codegen = "=0.93.0"
|
||||||
|
cranelift-codegen-meta = "=0.93.0"
|
||||||
|
cranelift-codegen-shared = "=0.93.0"
|
@ -0,0 +1,55 @@
|
|||||||
|
use anyhow::anyhow;
|
||||||
|
use base64::{engine::general_purpose as base64_engine, Engine as _};
|
||||||
|
use wasmtime::*;
|
||||||
|
use wasmtime_wasi::sync::WasiCtxBuilder;
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
let mut config = Config::new();
|
||||||
|
|
||||||
|
config.debug_info(false);
|
||||||
|
config.cranelift_debug_verifier(false);
|
||||||
|
|
||||||
|
config.strategy(Strategy::Cranelift);
|
||||||
|
config.cranelift_opt_level(OptLevel::SpeedAndSize);
|
||||||
|
|
||||||
|
config.static_memory_forced(true);
|
||||||
|
|
||||||
|
let engine = Engine::new(&config)?;
|
||||||
|
let mut linker = Linker::new(&engine);
|
||||||
|
|
||||||
|
wasmtime_wasi::add_to_linker(&mut linker, |s| s)?;
|
||||||
|
|
||||||
|
let wasi = WasiCtxBuilder::new().inherit_stdio().build();
|
||||||
|
|
||||||
|
let mut store = Store::new(&engine, wasi);
|
||||||
|
|
||||||
|
println!("Enter your module in base64:");
|
||||||
|
let user_module_wat = {
|
||||||
|
let stdin = std::io::stdin();
|
||||||
|
let mut user_module_wat = String::new();
|
||||||
|
stdin.read_line(&mut user_module_wat)?;
|
||||||
|
|
||||||
|
let user_module_wat = user_module_wat
|
||||||
|
.strip_suffix("\n")
|
||||||
|
.unwrap_or(&user_module_wat);
|
||||||
|
|
||||||
|
match base64_engine::STANDARD.decode(&user_module_wat) {
|
||||||
|
Ok(user_module_wat) => user_module_wat,
|
||||||
|
Err(_) => return Err(anyhow!("invalid base64")),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let user_module = match Module::new(&engine, user_module_wat) {
|
||||||
|
Ok(user_module) => user_module,
|
||||||
|
Err(_) => return Err(anyhow!("invalid module")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = linker.module(&mut store, "module", &user_module)?;
|
||||||
|
|
||||||
|
linker
|
||||||
|
.get_default(&mut store, "module")?
|
||||||
|
.typed::<(), ()>(&store)?
|
||||||
|
.call(&mut store, ())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
20
pwn/35-shades-of-wasm/35ShadesOfWasm/docker-compose.yml
Normal file
20
pwn/35-shades-of-wasm/35ShadesOfWasm/docker-compose.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Read the comments, they are actually helpful. (like this one)
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
# Challenge related options
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- 1337:1337
|
||||||
|
# Uncomment this block during development
|
||||||
|
# Every time you rebuild your file you can immeditately test it
|
||||||
|
# volumes:
|
||||||
|
# - ./chall:/app
|
||||||
|
|
||||||
|
# Security releated options
|
||||||
|
user: 1337:1337
|
||||||
|
privileged: false
|
||||||
|
read_only: true
|
||||||
|
cap_add: [] # See "man 7 capabilities" for a full list
|
||||||
|
cap_drop: [] # See "man 7 capabilities" for a full list
|
@ -0,0 +1,8 @@
|
|||||||
|
wasi-sdk=/opt/wasi-sdk
|
||||||
|
|
||||||
|
payload: payload.c
|
||||||
|
$(wasi-sdk)/bin/clang payload.c --target=wasm32-unknown-wasi --sysroot $(wasi-sdk)/share/wasi-sysroot/ \
|
||||||
|
-O0 -g -o payload.wasm
|
||||||
|
base64 payload.wasm -w 0 > payload.wasm.base64
|
||||||
|
|
||||||
|
all: payload
|
@ -0,0 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char ** argv) {
|
||||||
|
printf("Hello Wasi\n");
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
# Example
|
||||||
|
This example uses [wasi-sdk](https://github.com/WebAssembly/wasi-sdk).
|
||||||
|
You have to install it and then you might need to modify the wasi-sdk variable in the Makefile.
|
||||||
|
|
||||||
|
Of course this challenge can be solved in any language that has a wasm+wasi target.
|
7
pwn/35-shades-of-wasm/README.md
Normal file
7
pwn/35-shades-of-wasm/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
My friend hosts this wasm runtime that uses an outdated version of wasmtime. We pwned it and left a flag there. Can you get it?
|
||||||
|
|
||||||
|
author: PaideiaDilemma
|
||||||
|
|
||||||
|
```
|
||||||
|
nc chall.glacierctf.com 13389
|
||||||
|
```
|
8
pwn/flipper/README.md
Normal file
8
pwn/flipper/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
Our OS professor keeps talking about Rowhammer, and how dangerous it is. I don't believe him, so you even get 3 bitflips to try and steal the flag from my kernel!
|
||||||
|
|
||||||
|
Base repo is https://github.com/IAIK/sweb (commit ad1b59a5c2acbd4bff346bdf282a4d5e21bd9cb1) Build instructions at here
|
||||||
|
|
||||||
|
author: hweissi
|
||||||
|
```
|
||||||
|
nc chall.glacierctf.com 13371
|
||||||
|
```
|
BIN
pwn/flipper/chall.zip
Normal file
BIN
pwn/flipper/chall.zip
Normal file
Binary file not shown.
173
pwn/flipper/challenge.diff
Normal file
173
pwn/flipper/challenge.diff
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
diff --git a/common/include/kernel/Scheduler.h b/common/include/kernel/Scheduler.h
|
||||||
|
index c8fa74bf..dd7a9b45 100644
|
||||||
|
--- a/common/include/kernel/Scheduler.h
|
||||||
|
+++ b/common/include/kernel/Scheduler.h
|
||||||
|
@@ -26,7 +26,6 @@ class Scheduler
|
||||||
|
bool isCurrentlyCleaningUp();
|
||||||
|
void incTicks();
|
||||||
|
size_t getTicks();
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* NEVER EVER EVER CALL THIS METHOD OUTSIDE OF AN INTERRUPT CONTEXT
|
||||||
|
* this is the method that decides which threads will be scheduled next
|
||||||
|
@@ -34,6 +33,7 @@ class Scheduler
|
||||||
|
* and changes the global variables currentThread and currentThreadRegisters
|
||||||
|
*/
|
||||||
|
void schedule();
|
||||||
|
+ int flipped_already; // Here to have it in a singleton
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class IdleThread;
|
||||||
|
diff --git a/common/include/kernel/Syscall.h b/common/include/kernel/Syscall.h
|
||||||
|
index 8088db19..f0656a69 100644
|
||||||
|
--- a/common/include/kernel/Syscall.h
|
||||||
|
+++ b/common/include/kernel/Syscall.h
|
||||||
|
@@ -15,7 +15,7 @@ class Syscall
|
||||||
|
static size_t close(size_t fd);
|
||||||
|
static size_t open(size_t path, size_t flags);
|
||||||
|
static void pseudols(const char *pathname, char *buffer, size_t size);
|
||||||
|
-
|
||||||
|
+ static int flipBit(char* address, int bitnum);
|
||||||
|
static size_t createprocess(size_t path, size_t sleep);
|
||||||
|
static void trace();
|
||||||
|
};
|
||||||
|
diff --git a/common/include/kernel/syscall-definitions.h b/common/include/kernel/syscall-definitions.h
|
||||||
|
index dd99d197..88525f9b 100644
|
||||||
|
--- a/common/include/kernel/syscall-definitions.h
|
||||||
|
+++ b/common/include/kernel/syscall-definitions.h
|
||||||
|
@@ -17,3 +17,5 @@
|
||||||
|
#define sc_createprocess 191
|
||||||
|
#define sc_trace 252
|
||||||
|
|
||||||
|
+#define sc_flip_bit 69
|
||||||
|
+
|
||||||
|
diff --git a/common/include/kernel/user_progs.h b/common/include/kernel/user_progs.h
|
||||||
|
index 65617274..79e5b2a2 100644
|
||||||
|
--- a/common/include/kernel/user_progs.h
|
||||||
|
+++ b/common/include/kernel/user_progs.h
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
// DO NOT CHANGE THE NAME OR THE TYPE OF THE user_progs VARIABLE!
|
||||||
|
char const *user_progs[] = {
|
||||||
|
// for reasons of automated testing
|
||||||
|
- "/usr/shell.sweb",
|
||||||
|
+ "/usr/exploit.sweb",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/common/source/kernel/Scheduler.cpp b/common/source/kernel/Scheduler.cpp
|
||||||
|
index 31ef1da9..2148b991 100644
|
||||||
|
--- a/common/source/kernel/Scheduler.cpp
|
||||||
|
+++ b/common/source/kernel/Scheduler.cpp
|
||||||
|
@@ -28,6 +28,7 @@ Scheduler *Scheduler::instance()
|
||||||
|
|
||||||
|
Scheduler::Scheduler()
|
||||||
|
{
|
||||||
|
+ flipped_already = 0;
|
||||||
|
block_scheduling_ = 0;
|
||||||
|
ticks_ = 0;
|
||||||
|
addNewThread(&cleanup_thread_);
|
||||||
|
diff --git a/common/source/kernel/Syscall.cpp b/common/source/kernel/Syscall.cpp
|
||||||
|
index 964cd5b4..9c161cad 100644
|
||||||
|
--- a/common/source/kernel/Syscall.cpp
|
||||||
|
+++ b/common/source/kernel/Syscall.cpp
|
||||||
|
@@ -7,6 +7,9 @@
|
||||||
|
#include "ProcessRegistry.h"
|
||||||
|
#include "File.h"
|
||||||
|
#include "Scheduler.h"
|
||||||
|
+#include "ArchMemory.h"
|
||||||
|
+#include "Loader.h"
|
||||||
|
+
|
||||||
|
|
||||||
|
size_t Syscall::syscallException(size_t syscall_number, size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5)
|
||||||
|
{
|
||||||
|
@@ -49,6 +52,10 @@ size_t Syscall::syscallException(size_t syscall_number, size_t arg1, size_t arg2
|
||||||
|
case sc_pseudols:
|
||||||
|
pseudols((const char*) arg1, (char*) arg2, arg3);
|
||||||
|
break;
|
||||||
|
+ case sc_flip_bit:
|
||||||
|
+ return_value = flipBit((char*) arg1, (int) arg2);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
return_value = -1;
|
||||||
|
kprintf("Syscall::syscallException: Unimplemented Syscall Number %zd\n", syscall_number);
|
||||||
|
@@ -56,6 +63,24 @@ size_t Syscall::syscallException(size_t syscall_number, size_t arg1, size_t arg2
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int Syscall::flipBit(char* address, int bitnum)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ if(bitnum > 7 || bitnum < 0)
|
||||||
|
+ {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ if(Scheduler::instance()->flipped_already != 0)
|
||||||
|
+ {
|
||||||
|
+ return -2;
|
||||||
|
+ }
|
||||||
|
+ Scheduler::instance()->flipped_already = 0xfff;
|
||||||
|
+ char mask = (1 << bitnum);
|
||||||
|
+ *address ^= mask;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void Syscall::pseudols(const char *pathname, char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
if(buffer && ((size_t)buffer >= USER_BREAK || (size_t)buffer + size > USER_BREAK))
|
||||||
|
diff --git a/common/source/kernel/main.cpp b/common/source/kernel/main.cpp
|
||||||
|
index f7957074..c51fef8b 100644
|
||||||
|
--- a/common/source/kernel/main.cpp
|
||||||
|
+++ b/common/source/kernel/main.cpp
|
||||||
|
@@ -28,6 +28,8 @@
|
||||||
|
|
||||||
|
extern void* kernel_end_address;
|
||||||
|
|
||||||
|
+const char* flag = "gctf{TEST_FLAG_NOT_REAL_HF}";
|
||||||
|
+
|
||||||
|
uint8 boot_stack[0x4000] __attribute__((aligned(0x4000)));
|
||||||
|
SystemState system_state;
|
||||||
|
FileSystemInfo* default_working_dir;
|
||||||
|
diff --git a/userspace/libc/include/nonstd.h b/userspace/libc/include/nonstd.h
|
||||||
|
index 3f341b55..cc5dd694 100644
|
||||||
|
--- a/userspace/libc/include/nonstd.h
|
||||||
|
+++ b/userspace/libc/include/nonstd.h
|
||||||
|
@@ -15,7 +15,7 @@ extern "C" {
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
extern int createprocess(const char* path, int sleep);
|
||||||
|
-
|
||||||
|
+extern int flipBit(const void* address, int bit_num);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
diff --git a/userspace/libc/src/nonstd.c b/userspace/libc/src/nonstd.c
|
||||||
|
index b9ec3d11..043a2466 100644
|
||||||
|
--- a/userspace/libc/src/nonstd.c
|
||||||
|
+++ b/userspace/libc/src/nonstd.c
|
||||||
|
@@ -8,6 +8,12 @@ int createprocess(const char* path, int sleep)
|
||||||
|
return __syscall(sc_createprocess, (long) path, sleep, 0x00, 0x00, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int flipBit(const void* address, int bit_num)
|
||||||
|
+{
|
||||||
|
+ return __syscall(sc_flip_bit, (long) address, bit_num, 0, 0, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
extern int main();
|
||||||
|
|
||||||
|
void _start()
|
||||||
|
diff --git a/utils/images/menu.lst b/utils/images/menu.lst
|
||||||
|
index cf7fd93d..f230876e 100644
|
||||||
|
--- a/utils/images/menu.lst
|
||||||
|
+++ b/utils/images/menu.lst
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
|
||||||
|
default 0
|
||||||
|
-
|
||||||
|
+timeout=0
|
||||||
|
title = Sweb
|
||||||
|
root (hd0,0)
|
||||||
|
kernel = /boot/kernel.x
|
255
pwn/flipper/dist/CMakeLists.txt
vendored
Normal file
255
pwn/flipper/dist/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||||
|
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||||
|
|
||||||
|
# Include custom CMake modules from the cmake/ subdirectory
|
||||||
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
|
set(HDD_IMAGE_RAW "SWEB-flat.vmdk")
|
||||||
|
set(HDD_IMAGE "SWEB.qcow2")
|
||||||
|
|
||||||
|
|
||||||
|
set (ARCH "x86/64")
|
||||||
|
|
||||||
|
MESSAGE("-- Target architecture: ${ARCH}")
|
||||||
|
|
||||||
|
unset(CMAKE_CROSSCOMPILING)
|
||||||
|
if(APPLE OR WIN32)
|
||||||
|
set(CMAKE_CROSSCOMPILING 1)
|
||||||
|
MESSAGE("-- Cross-Compiling on Apple/Windows")
|
||||||
|
endif(APPLE OR WIN32)
|
||||||
|
|
||||||
|
# add-dbg for userspace binaries
|
||||||
|
include(AddDebugInfo)
|
||||||
|
|
||||||
|
# include(arch/${ARCH}/CMakeLists.compiler)
|
||||||
|
|
||||||
|
project(sweb
|
||||||
|
LANGUAGES C CXX ASM)
|
||||||
|
|
||||||
|
string(REPLACE "/" ";" ARCH_LIST ${ARCH})
|
||||||
|
string(REPLACE "/" "_" ARCH_ESC ${ARCH})
|
||||||
|
string(TOUPPER ${ARCH_ESC} ARCH_ESC)
|
||||||
|
|
||||||
|
add_definitions(-DCMAKE_${ARCH_ESC}=1)
|
||||||
|
|
||||||
|
list(LENGTH ARCH_LIST ARCH_DEPTH)
|
||||||
|
|
||||||
|
#Find program executables needed during compilation
|
||||||
|
find_program(LD_EXECUTABLE gcc)
|
||||||
|
find_program(OBJCOPY_EXECUTABLE objcopy)
|
||||||
|
find_program(DOXYGEN_EXECUTABLE doxygen)
|
||||||
|
find_program(STAT_EXECUTABLE stat)
|
||||||
|
|
||||||
|
set(ColourReset "")
|
||||||
|
set(BoldRed "")
|
||||||
|
if(NOT WIN32)
|
||||||
|
string(ASCII 27 Esc)
|
||||||
|
set(ColourReset "${Esc}[m")
|
||||||
|
set(BoldRed "${Esc}[1;31m")
|
||||||
|
endif()
|
||||||
|
# set(TMPFS_CHECK "none")
|
||||||
|
# execute_process(COMMAND ${STAT_EXECUTABLE} --file-system --format=%T ${PROJECT_BINARY_DIR}
|
||||||
|
# OUTPUT_VARIABLE TMPFS_CHECK
|
||||||
|
# OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
# if(NOT("${TMPFS_CHECK}" STREQUAL "tmpfs"))
|
||||||
|
# MESSAGE("-- ${BoldRed}WARNING: build folder is not tmpfs - compilation will be slow and bad for the hard disk${ColourReset}")
|
||||||
|
# endif(NOT("${TMPFS_CHECK}" STREQUAL "tmpfs"))
|
||||||
|
|
||||||
|
set(NOPIEFLAG -no-pie)
|
||||||
|
execute_process(COMMAND ${LD_EXECUTABLE} ${NOPIEFLAG}
|
||||||
|
ERROR_VARIABLE PIE_CHECK
|
||||||
|
ERROR_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if("${PIE_CHECK}" MATCHES ".*unrecognized.*")
|
||||||
|
set(NOPIEFLAG )
|
||||||
|
endif()
|
||||||
|
set(NOPICFLAG -fno-PIC)
|
||||||
|
execute_process(COMMAND ${CMAKE_C_COMPILER} ${NOPICFLAG}
|
||||||
|
ERROR_VARIABLE PIC_CHECK
|
||||||
|
ERROR_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if("${PIC_CHECK}" MATCHES ".*unrecognized.*")
|
||||||
|
set(NOPICFLAG )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#Initialize CMake output directories
|
||||||
|
set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib")
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}")
|
||||||
|
|
||||||
|
include(arch/${ARCH}/CMakeLists.include)
|
||||||
|
include(arch/${ARCH}/CMakeLists.userspace)
|
||||||
|
string (REPLACE ";" " " KERNEL_CMAKE_C_FLAGS_STR "${KERNEL_CMAKE_C_FLAGS}")
|
||||||
|
set(CMAKE_ASM_FLAGS ${KERNEL_CMAKE_C_FLAGS_STR})
|
||||||
|
|
||||||
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
set(CMAKE_CROSS_COMPILE_FLAGS -G "Unix Makefiles")
|
||||||
|
else(CMAKE_CROSSCOMPILING) # not cross compiling
|
||||||
|
set(CMAKE_CROSS_COMPILE_FLAGS )
|
||||||
|
endif(CMAKE_CROSSCOMPILING)
|
||||||
|
|
||||||
|
# if ("${DEBUG}" STREQUAL "1")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG=1")
|
||||||
|
# endif()
|
||||||
|
|
||||||
|
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/kernel.x
|
||||||
|
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
|
||||||
|
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/kernel64.x
|
||||||
|
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
|
||||||
|
# Searches for asm, c and cpp files and adds the library
|
||||||
|
function(ADD_PROJECT_LIBRARY LIBRARY_NAME)
|
||||||
|
arch2obj(archobj_libname ${LIBRARY_NAME})
|
||||||
|
|
||||||
|
file(GLOB source_files ${SOURCE_WILDCARDS})
|
||||||
|
|
||||||
|
set(library_files)
|
||||||
|
|
||||||
|
if(source_files)
|
||||||
|
set(library_files ${source_files})
|
||||||
|
endif(source_files)
|
||||||
|
|
||||||
|
if(archobj_libname)
|
||||||
|
set(library_files ${library_files} $<TARGET_OBJECTS:${archobj_libname}>)
|
||||||
|
endif(archobj_libname)
|
||||||
|
|
||||||
|
if(library_files)
|
||||||
|
add_library(${LIBRARY_NAME} ${library_files})
|
||||||
|
|
||||||
|
if(archobj_libname)
|
||||||
|
add_dependencies(${LIBRARY_NAME} ${archobj_libname})
|
||||||
|
endif(archobj_libname)
|
||||||
|
|
||||||
|
target_compile_options(${LIBRARY_NAME} PRIVATE
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:${KERNEL_CMAKE_CXX_FLAGS}>
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:${KERNEL_CMAKE_C_FLAGS}>
|
||||||
|
)
|
||||||
|
|
||||||
|
set(ENV{LIBRARY_NAMES} "$ENV{LIBRARY_NAMES};${LIBRARY_NAME}")
|
||||||
|
endif(library_files)
|
||||||
|
endfunction(ADD_PROJECT_LIBRARY)
|
||||||
|
|
||||||
|
set (SOURCE_WILDCARDS *.cpp *.c *.S)
|
||||||
|
|
||||||
|
set(LIBRARY_FILENAMES)
|
||||||
|
|
||||||
|
#Initialize global (environment) variables
|
||||||
|
set(ENV{LIBRARY_NAMES})
|
||||||
|
|
||||||
|
#Create target for userspace libc (Need to to that here because some files (e.g. syscall.c) are all over the place)
|
||||||
|
add_library(userspace_libc "")
|
||||||
|
target_compile_options(userspace_libc PUBLIC ${ARCH_USERSPACE_COMPILE_OPTIONS})
|
||||||
|
|
||||||
|
#Add the source directories
|
||||||
|
add_subdirectory(arch)
|
||||||
|
# add_subdirectory(common)
|
||||||
|
add_subdirectory(utils)
|
||||||
|
add_subdirectory(userspace)
|
||||||
|
|
||||||
|
|
||||||
|
#FINAL_LIB_NAMES should contain the names of all libraries
|
||||||
|
#these names can be used to link the kernel, no unpacking of *.a files is needed anymore
|
||||||
|
set(FINAL_LIB_NAMES $ENV{LIBRARY_NAMES})
|
||||||
|
|
||||||
|
#Name of the executables of the userspace, needed for dependency checking
|
||||||
|
set(FINAL_USERSPACE_NAMES $ENV{USERSPACE_NAMES})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Build the Linker command
|
||||||
|
set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} -g -u entry -Wl,-T ${CMAKE_SOURCE_DIR}/arch/${ARCH}/utils/kernel-ld-script.ld)
|
||||||
|
set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} -o ${PROJECT_BINARY_DIR}/kernel.x)
|
||||||
|
#set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} -Wl,-Map -Wl,${PROJECT_BINARY_DIR}/kernel.map)
|
||||||
|
|
||||||
|
set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} -Wl,--start-group)
|
||||||
|
foreach(libfile ${FINAL_LIB_NAMES})
|
||||||
|
set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} ${LIBRARY_OUTPUT_PATH}/lib${libfile}.a)
|
||||||
|
endforeach(libfile)
|
||||||
|
set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} -Wl,--end-group)
|
||||||
|
set(KERNEL_LD_ARGUMENT ${KERNEL_LD_ARGUMENT} ${ARCH_APPEND_LD_ARGUMENTS})
|
||||||
|
|
||||||
|
#Build userspace exe2minixfs command
|
||||||
|
set(MINIXFS_ARGUMENT "")
|
||||||
|
foreach(file $ENV{USERSPACE_NAMES_EXE2MINIX})
|
||||||
|
list(APPEND MINIXFS_ARGUMENT ${file})
|
||||||
|
endforeach(file)
|
||||||
|
|
||||||
|
file(GLOB userspace_data userspace/data/*)
|
||||||
|
foreach(file ${userspace_data})
|
||||||
|
get_filename_component(datafile ${file} NAME)
|
||||||
|
list(APPEND MINIXFS_ARGUMENT ${file} ${datafile})
|
||||||
|
endforeach(file)
|
||||||
|
|
||||||
|
#Custom Target: hdd_image
|
||||||
|
#Creates the hd image and copies all files to it
|
||||||
|
add_custom_target (hdd_image ALL
|
||||||
|
DEPENDS kernel_to_image userspace_to_image
|
||||||
|
COMMAND qemu-img convert -f raw -O qcow2 ${HDD_IMAGE_RAW} ${HDD_IMAGE}
|
||||||
|
)
|
||||||
|
|
||||||
|
#Custom Command: invoke exe2minixfs and copy boot files to our hd image
|
||||||
|
add_custom_target (kernel_to_image
|
||||||
|
DEPENDS blank_hdd_image exe2minixfs
|
||||||
|
|
||||||
|
# x86/32 doesn't generate kernel.dbg
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch "./kernel.dbg"
|
||||||
|
COMMAND ./exe2minixfs ${HDD_IMAGE_RAW} 32256 "${CMAKE_SOURCE_DIR}/utils/images/menu.lst" boot/grub/menu.lst
|
||||||
|
./kernel.x boot/kernel.x
|
||||||
|
./kernel.dbg boot/kernel.dbg
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
COMMENT "Copying kernel files to image..."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Custom Command: invoke exe2minixfs and copy all userspace programs to our hd image second partition
|
||||||
|
add_custom_target (userspace_to_image
|
||||||
|
DEPENDS blank_hdd_image ${FINAL_USERSPACE_NAMES} exe2minixfs
|
||||||
|
COMMAND mkdir -p userspace/data
|
||||||
|
COMMAND cp -f ${CMAKE_SOURCE_DIR}/userspace/data/* ${PROJECT_BINARY_DIR}/userspace/data
|
||||||
|
COMMAND ./exe2minixfs ${HDD_IMAGE_RAW} 10321920 ${MINIXFS_ARGUMENT}
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
COMMENT "Copying userspace programs to image..."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#Custom target: make bochs
|
||||||
|
#Run bochs in non debugging mode
|
||||||
|
add_custom_target(bochs
|
||||||
|
COMMAND ${BOCHS_PATH} -q -f ${PROJECT_SOURCE_DIR}/utils/bochsrc
|
||||||
|
COMMENT "Going to ${BOCHS_PATH} -f ${PROJECT_SOURCE_DIR}/utils/bochsrc"
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
#Custom target: make bochsgdb
|
||||||
|
#Run bochs in debugging mode
|
||||||
|
add_custom_target(bochsgdb
|
||||||
|
COMMAND ${BOCHS_PATH} -q -f '${PROJECT_SOURCE_DIR}/utils/bochsrc' "gdbstub: enabled=1, port=1234"
|
||||||
|
COMMENT "Going to ${BOCHS_PATH} -f ${PROJECT_SOURCE_DIR}/utils/bochsrc \"gdbstub: enabled=1, port=1234\""
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
#Custom target: make emu
|
||||||
|
#Run qemu in emu mode
|
||||||
|
add_custom_target(emu
|
||||||
|
COMMAND cat '${PROJECT_SOURCE_DIR}/utils/emu.txt'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Define the "make ${ARCH}" targets
|
||||||
|
include(MakeArchTarget)
|
||||||
|
|
||||||
|
MAKE_ARCH_TARGET(x86_32 x86/32 "")
|
||||||
|
MAKE_ARCH_TARGET(x86_32_pae x86/32/pae "")
|
||||||
|
MAKE_ARCH_TARGET(x86_64 x86/64 "")
|
||||||
|
|
||||||
|
MAKE_ARCH_TARGET(arm_icp arm/integratorcp "")
|
||||||
|
MAKE_ARCH_TARGET(arm_rpi2 arm/rpi2 "")
|
||||||
|
MAKE_ARCH_TARGET(armv8_rpi3 armv8/rpi3 "-DVIRTUALIZED_QEMU=1")
|
||||||
|
MAKE_ARCH_TARGET(armv8_rpi3_hardware armv8/rpi3 "")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
6
pwn/flipper/dist/README.md
vendored
Normal file
6
pwn/flipper/dist/README.md
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Notes
|
||||||
|
|
||||||
|
This is a setup to run a fixed kernel with new userspace.
|
||||||
|
Please read the instructions [here](https://www.iaik.tugraz.at/teaching/materials/os/tutorials/prerequisites-installation/) to find out how to compile and run.
|
||||||
|
|
||||||
|
The same instructions also work for the source code at https://github.com/iaik/sweb, which is probably easier for debugging.
|
4
pwn/flipper/dist/arch/CMakeLists.txt
vendored
Normal file
4
pwn/flipper/dist/arch/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
include(${ARCH}/CMakeLists.subfolders)
|
||||||
|
|
0
pwn/flipper/dist/arch/x86/64/.keep
vendored
Normal file
0
pwn/flipper/dist/arch/x86/64/.keep
vendored
Normal file
14
pwn/flipper/dist/arch/x86/64/CMakeLists.compiler
vendored
Normal file
14
pwn/flipper/dist/arch/x86/64/CMakeLists.compiler
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
INCLUDE(CMakeForceCompiler)
|
||||||
|
|
||||||
|
SET(CMAKE_SYSTEM_NAME Generic)
|
||||||
|
SET(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||||
|
|
||||||
|
find_program(CMAKE_ASM_COMPILER x86_64-linux-gnu-gcc)
|
||||||
|
find_program(CMAKE_C_COMPILER x86_64-linux-gnu-gcc)
|
||||||
|
find_program(CMAKE_CXX_COMPILER x86_64-linux-gnu-g++)
|
||||||
|
|
||||||
|
find_program(LD_EXECUTABLE x86_64-linux-gnu-gcc)
|
||||||
|
find_program(OBJCOPY_EXECUTABLE x86_64-linux-gnu-objcopy)
|
||||||
|
|
||||||
|
endif(CMAKE_CROSSCOMPILING)
|
67
pwn/flipper/dist/arch/x86/64/CMakeLists.include
vendored
Normal file
67
pwn/flipper/dist/arch/x86/64/CMakeLists.include
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
set(KERNEL_BINARY kernel64.x)
|
||||||
|
|
||||||
|
if (CMAKE_COMPILER_IS_GNUCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8))
|
||||||
|
set(FCF_PROTECTION_FLAG -fcf-protection=none)
|
||||||
|
else()
|
||||||
|
set(FCF_PROTECTION_FLAG )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ARCH_X86_64_KERNEL_CFLAGS -m64 -O0 -gdwarf-2 -Wall -Wextra -Werror -Wno-error=format -Wno-nonnull-compare -nostdinc -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-exceptions -fno-stack-protector -ffreestanding -mcmodel=kernel -mno-red-zone -mgeneral-regs-only -mno-mmx -mno-sse2 -mno-sse3 -mno-3dnow ${FCF_PROTECTION_FLAG} ${NOPICFLAG})
|
||||||
|
|
||||||
|
set(KERNEL_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=gnu++17 -nostdinc++ -fno-rtti ${ARCH_X86_64_KERNEL_CFLAGS})
|
||||||
|
set(KERNEL_CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -std=gnu11 ${ARCH_X86_64_KERNEL_CFLAGS})
|
||||||
|
|
||||||
|
set(ARCH_LD_ARGUMENTS -m64 -Wl,--build-id=none -Wl,-z,max-page-size=0x1000 -Wl,-melf_x86_64 -nostdinc -nostdlib -nodefaultlibs)
|
||||||
|
set(KERNEL_LD_ARGUMENT ${ARCH_LD_ARGUMENTS} -mcmodel=kernel ${NOPIEFLAG})
|
||||||
|
set(ARCH_APPEND_LD_ARGUMENTS )
|
||||||
|
|
||||||
|
|
||||||
|
function(ARCH2OBJ ARCHOBJ_LIBNAME LIBRARY_NAME)
|
||||||
|
file(GLOB arch_files "*.32.C")
|
||||||
|
|
||||||
|
if(arch_files)
|
||||||
|
set(ARCHOBJS_TARGET ${LIBRARY_NAME}_archobjs)
|
||||||
|
|
||||||
|
add_library(${ARCHOBJS_TARGET} OBJECT ${arch_files})
|
||||||
|
|
||||||
|
target_compile_options(${ARCHOBJS_TARGET} PRIVATE
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:${KERNEL_CMAKE_CXX_FLAGS}>
|
||||||
|
$<$<COMPILE_LANGUAGE:C>:${KERNEL_CMAKE_C_FLAGS}>
|
||||||
|
-m32 -g0 -mcmodel=32 -mgeneral-regs-only -momit-leaf-frame-pointer -Wa,--64 -fno-toplevel-reorder ${FCF_PROTECTION_FLAG}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(${ARCHOBJ_LIBNAME} ${ARCHOBJS_TARGET} PARENT_SCOPE)
|
||||||
|
endif(arch_files)
|
||||||
|
endfunction(ARCH2OBJ)
|
||||||
|
|
||||||
|
set(KERNEL_IMAGE_OBJCOPY COMMAND ${OBJCOPY_EXECUTABLE} ${PROJECT_BINARY_DIR}/kernel.x --strip-unneeded ${PROJECT_BINARY_DIR}/kernel.x)
|
||||||
|
if ("${DEBUG}" STREQUAL "1")
|
||||||
|
set(KERNEL_IMAGE_OBJCOPY )
|
||||||
|
endif()
|
||||||
|
set(KERNEL_IMAGE_OBJCOPY
|
||||||
|
COMMAND ${PROJECT_BINARY_DIR}/add-dbg ${PROJECT_BINARY_DIR}/kernel.x ${PROJECT_BINARY_DIR}/kernel.dbg
|
||||||
|
${KERNEL_IMAGE_OBJCOPY}
|
||||||
|
COMMAND mv ${PROJECT_BINARY_DIR}/kernel.x ${PROJECT_BINARY_DIR}/kernel64.x && ${OBJCOPY_EXECUTABLE} -O elf32-i386 ${PROJECT_BINARY_DIR}/kernel64.x ${PROJECT_BINARY_DIR}/kernel.x
|
||||||
|
)
|
||||||
|
|
||||||
|
set(AVAILABLE_MEMORY 8M)
|
||||||
|
|
||||||
|
set(QEMU_BIN qemu-system-x86_64)
|
||||||
|
set(QEMU_FLAGS_COMMON -m ${AVAILABLE_MEMORY} -drive file=${HDD_IMAGE},index=0,media=disk -debugcon stdio -no-reboot)
|
||||||
|
string(REPLACE ";" " " QEMU_FLAGS_COMMON_STR "${QEMU_FLAGS_COMMON}")
|
||||||
|
|
||||||
|
# qemu: Run qemu in non debugging mode
|
||||||
|
add_custom_target(qemu
|
||||||
|
COMMAND ${QEMU_BIN} ${QEMU_FLAGS_COMMON} -cpu qemu64 | tee output.log
|
||||||
|
COMMENT "Executing `${QEMU_BIN} ${QEMU_FLAGS_COMMON_STR} -cpu qemu64`"
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
COMMAND reset -I
|
||||||
|
)
|
||||||
|
|
||||||
|
# qemugdb: Run qemu in debugging mode
|
||||||
|
add_custom_target(qemugdb
|
||||||
|
COMMAND ${QEMU_BIN} ${QEMU_FLAGS_COMMON} -s -S | tee output.log
|
||||||
|
COMMENT "Executing `gdb ${QEMU_BIN} ${QEMU_FLAGS_COMMON_STR} -s -S on localhost:1234`"
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
COMMAND reset -I
|
||||||
|
)
|
3
pwn/flipper/dist/arch/x86/64/CMakeLists.subfolders
vendored
Normal file
3
pwn/flipper/dist/arch/x86/64/CMakeLists.subfolders
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
add_subdirectory(x86)
|
||||||
|
add_subdirectory(x86/64)
|
||||||
|
|
1
pwn/flipper/dist/arch/x86/64/CMakeLists.txt
vendored
Normal file
1
pwn/flipper/dist/arch/x86/64/CMakeLists.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(userspace)
|
2
pwn/flipper/dist/arch/x86/64/CMakeLists.userspace
vendored
Normal file
2
pwn/flipper/dist/arch/x86/64/CMakeLists.userspace
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
set(ARCH_USERSPACE_COMPILE_OPTIONS -Wall -Werror -std=gnu11 -g -O0 -m64 -static -nostdinc -fno-builtin -nostdlib -nodefaultlibs -fno-stack-protector -fno-common -Werror=implicit-function-declaration -fno-stack-clash-protection)
|
||||||
|
set(ARCH_USERSPACE_LINKER_OPTIONS -static)
|
5
pwn/flipper/dist/arch/x86/64/userspace/CMakeLists.txt
vendored
Normal file
5
pwn/flipper/dist/arch/x86/64/userspace/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
FILE(GLOB userspace_libc_SOURCES ${CMAKE_CURRENT_LIST_DIR}/*.c)
|
||||||
|
|
||||||
|
target_sources(userspace_libc
|
||||||
|
PRIVATE
|
||||||
|
${userspace_libc_SOURCES})
|
8
pwn/flipper/dist/arch/x86/64/userspace/syscalls.c
vendored
Normal file
8
pwn/flipper/dist/arch/x86/64/userspace/syscalls.c
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
size_t __syscall(size_t arg1, size_t arg2, size_t arg3, size_t arg4, size_t arg5,
|
||||||
|
size_t arg6)
|
||||||
|
{
|
||||||
|
asm("int $0x80\n" : "=a"(arg1) : "a"(arg1), "b"(arg2), "c"(arg3), "d"(arg4), "S"(arg5), "D"(arg6));
|
||||||
|
return arg1;
|
||||||
|
}
|
1
pwn/flipper/dist/arch/x86/CMakeLists.txt
vendored
Normal file
1
pwn/flipper/dist/arch/x86/CMakeLists.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
18
pwn/flipper/dist/cmake/AddDebugInfo.cmake
vendored
Normal file
18
pwn/flipper/dist/cmake/AddDebugInfo.cmake
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# This macro adds a post-build hook to the specified target in order to attach
|
||||||
|
# SWEB-readable debug info.
|
||||||
|
|
||||||
|
function(ADD_DEBUG_INFO TARGET)
|
||||||
|
set(dbg_binary $<TARGET_FILE:${TARGET}>)
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${TARGET}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND "${CMAKE_BINARY_DIR}/add-dbg" "${dbg_binary}" "${dbg_binary}.dbg"
|
||||||
|
COMMAND "${OBJCOPY_EXECUTABLE}" --remove-section .swebdbg "${dbg_binary}"
|
||||||
|
COMMAND "${OBJCOPY_EXECUTABLE}" --add-section .swebdbg="${dbg_binary}.dbg"
|
||||||
|
--set-section-flags .swebdbg=noload,readonly "${dbg_binary}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove -f "${dbg_binary}.dbg"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Requires add-dbg to be built first.
|
||||||
|
add_dependencies(${TARGET} add-dbg)
|
||||||
|
endfunction(ADD_DEBUG_INFO)
|
12
pwn/flipper/dist/cmake/MakeArchTarget.cmake
vendored
Normal file
12
pwn/flipper/dist/cmake/MakeArchTarget.cmake
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Macro for defining the "make ${ARCH}" targets
|
||||||
|
#
|
||||||
|
# If you want to add a target with multiple variable definitions, this is how you do it:
|
||||||
|
# MAKE_ARCH_TARGET(my_arch my/arch "-DVAR1=VALUE1;-DVAR2=VALUE2;...")
|
||||||
|
|
||||||
|
function(MAKE_ARCH_TARGET TARGET_NAME ARCH_NAME EXTRA_FLAGS)
|
||||||
|
add_custom_target(${TARGET_NAME}
|
||||||
|
COMMAND ${PROJECT_SOURCE_DIR}/utils/prompt.sh "rm -fR ${PROJECT_BINARY_DIR}/*: remove all arguments recursively [Y/n]? "
|
||||||
|
COMMAND rm -fR ${PROJECT_BINARY_DIR}/* || true
|
||||||
|
COMMAND cmake -DARCH="${ARCH_NAME}" ${EXTRA_FLAGS} ${PROJECT_SOURCE_DIR} ${CMAKE_CROSS_COMPILE_FLAGS}
|
||||||
|
)
|
||||||
|
endfunction(MAKE_ARCH_TARGET)
|
0
pwn/flipper/dist/common/.keep
vendored
Normal file
0
pwn/flipper/dist/common/.keep
vendored
Normal file
18
pwn/flipper/dist/common/CMakeLists.txt
vendored
Normal file
18
pwn/flipper/dist/common/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
include_directories(
|
||||||
|
include
|
||||||
|
../arch/common/include
|
||||||
|
../arch/${ARCH}/include
|
||||||
|
../arch/${ARCH}/common/include
|
||||||
|
../arch/${ARCH}/../common/include
|
||||||
|
../arch/${ARCH}/../../common/include
|
||||||
|
include/kernel
|
||||||
|
include/fs
|
||||||
|
include/fs/devicefs
|
||||||
|
include/fs/minixfs
|
||||||
|
include/fs/pseudofs
|
||||||
|
include/fs/ramfs
|
||||||
|
include/util
|
||||||
|
include/ustl
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(source)
|
0
pwn/flipper/dist/common/include/.keep
vendored
Normal file
0
pwn/flipper/dist/common/include/.keep
vendored
Normal file
88
pwn/flipper/dist/common/include/console/debug.h
vendored
Normal file
88
pwn/flipper/dist/common/include/console/debug.h
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "kprintf.h"
|
||||||
|
|
||||||
|
enum AnsiColor
|
||||||
|
{
|
||||||
|
Ansi_Red = 31,
|
||||||
|
Ansi_Green = 32,
|
||||||
|
Ansi_Yellow = 33,
|
||||||
|
Ansi_Blue = 34,
|
||||||
|
Ansi_Magenta = 35,
|
||||||
|
Ansi_Cyan = 36,
|
||||||
|
Ansi_White = 37,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OUTPUT_ENABLED 0x80000000
|
||||||
|
#define OUTPUT_ADVANCED 0x70000000
|
||||||
|
#define OUTPUT_FLAGS (OUTPUT_ENABLED | OUTPUT_ADVANCED)
|
||||||
|
|
||||||
|
#ifndef NOCOLOR
|
||||||
|
#define DEBUG_FORMAT_STRING "\033[1;%zum[%-11s]\033[0;39m"
|
||||||
|
#define COLOR_PARAM(flag) (flag & ~OUTPUT_FLAGS), #flag
|
||||||
|
#else
|
||||||
|
#define DEBUG_FORMAT_STRING "[%-11s]"
|
||||||
|
#define COLOR_PARAM(flag) #flag
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXE2MINIXFS
|
||||||
|
#define debug(flag, ...) do { if (flag & OUTPUT_ENABLED) { kprintfd(DEBUG_FORMAT_STRING, COLOR_PARAM(flag)); kprintfd(__VA_ARGS__); } } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//group Block Device
|
||||||
|
const size_t BD_MANAGER = Ansi_Yellow;
|
||||||
|
const size_t BD_VIRT_DEVICE = Ansi_Yellow;
|
||||||
|
|
||||||
|
//group Console
|
||||||
|
const size_t KPRINTF = Ansi_Yellow;
|
||||||
|
|
||||||
|
//group kernel
|
||||||
|
const size_t LOCK = Ansi_Yellow | OUTPUT_ENABLED;
|
||||||
|
const size_t LOADER = Ansi_White | OUTPUT_ENABLED;
|
||||||
|
const size_t SCHEDULER = Ansi_Yellow | OUTPUT_ENABLED;
|
||||||
|
const size_t SYSCALL = Ansi_Blue | OUTPUT_ENABLED;
|
||||||
|
const size_t MAIN = Ansi_Red | OUTPUT_ENABLED;
|
||||||
|
const size_t THREAD = Ansi_Magenta | OUTPUT_ENABLED;
|
||||||
|
const size_t USERPROCESS = Ansi_Cyan | OUTPUT_ENABLED;
|
||||||
|
const size_t PROCESS_REG = Ansi_Yellow | OUTPUT_ENABLED;
|
||||||
|
const size_t BACKTRACE = Ansi_Cyan | OUTPUT_ENABLED;
|
||||||
|
const size_t USERTRACE = Ansi_Red | OUTPUT_ENABLED;
|
||||||
|
|
||||||
|
//group memory management
|
||||||
|
const size_t PM = Ansi_Green | OUTPUT_ENABLED;
|
||||||
|
const size_t PAGEFAULT = Ansi_Green | OUTPUT_ENABLED;
|
||||||
|
const size_t CPU_ERROR = Ansi_Red | OUTPUT_ENABLED;
|
||||||
|
const size_t KMM = Ansi_Yellow;
|
||||||
|
|
||||||
|
//group driver
|
||||||
|
const size_t DRIVER = Ansi_Yellow;
|
||||||
|
const size_t ATA_DRIVER = Ansi_Yellow;
|
||||||
|
const size_t IDE_DRIVER = Ansi_Yellow;
|
||||||
|
const size_t MMC_DRIVER = Ansi_Yellow;
|
||||||
|
|
||||||
|
//group arch
|
||||||
|
const size_t A_BOOT = Ansi_Yellow | OUTPUT_ENABLED;
|
||||||
|
const size_t A_COMMON = Ansi_Yellow;
|
||||||
|
const size_t A_MEMORY = Ansi_Yellow;
|
||||||
|
const size_t A_SERIALPORT = Ansi_Yellow;
|
||||||
|
const size_t A_KB_MANAGER = Ansi_Yellow;
|
||||||
|
const size_t A_INTERRUPTS = Ansi_Yellow;
|
||||||
|
|
||||||
|
//group file system
|
||||||
|
const size_t FS = Ansi_Yellow;
|
||||||
|
const size_t RAMFS = Ansi_White;
|
||||||
|
const size_t DENTRY = Ansi_Blue;
|
||||||
|
const size_t INODE = Ansi_Blue;
|
||||||
|
const size_t PATHWALKER = Ansi_Yellow;
|
||||||
|
const size_t PSEUDOFS = Ansi_Yellow;
|
||||||
|
const size_t VFSSYSCALL = Ansi_Yellow;
|
||||||
|
const size_t VFS = Ansi_Yellow | OUTPUT_ENABLED;
|
||||||
|
const size_t VFS_FILE = Ansi_Yellow;
|
||||||
|
const size_t SUPERBLOCK = Ansi_Yellow;
|
||||||
|
|
||||||
|
//group minix
|
||||||
|
const size_t M_STORAGE_MANAGER = Ansi_Yellow;
|
||||||
|
const size_t M_INODE = Ansi_Yellow;
|
||||||
|
const size_t M_SB = Ansi_Yellow;
|
||||||
|
const size_t M_ZONE = Ansi_Yellow;
|
75
pwn/flipper/dist/common/include/fs/BDManager.h
vendored
Normal file
75
pwn/flipper/dist/common/include/fs/BDManager.h
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ulist.h>
|
||||||
|
|
||||||
|
class BDRequest;
|
||||||
|
class BDVirtualDevice;
|
||||||
|
|
||||||
|
class BDManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BDManager();
|
||||||
|
~BDManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns singleton instance
|
||||||
|
* @return the block device manager instance
|
||||||
|
*/
|
||||||
|
static BDManager *getInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detects all devices present
|
||||||
|
*/
|
||||||
|
void doDeviceDetection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds the given device to the manager
|
||||||
|
* @param dev the device to add
|
||||||
|
*/
|
||||||
|
void addVirtualDevice(BDVirtualDevice *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the device with the given number
|
||||||
|
* @param dev_num the device number
|
||||||
|
* @return the device
|
||||||
|
*/
|
||||||
|
BDVirtualDevice *getDeviceByNumber(uint32 dev_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the device with the given name
|
||||||
|
* @param dev_name the device name
|
||||||
|
* @return the device
|
||||||
|
*/
|
||||||
|
BDVirtualDevice *getDeviceByName(const char *dev_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the number of devices in the bd manager
|
||||||
|
* @return the number of devices
|
||||||
|
*/
|
||||||
|
uint32 getNumberOfDevices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds the given request to the device given in the request
|
||||||
|
* @param bdr the request
|
||||||
|
*/
|
||||||
|
void addRequest(BDRequest *bdr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calls seviceIRQ on the device the irq with the given number is on
|
||||||
|
* after that probeIRQ is false
|
||||||
|
* @param irq_num the irq number
|
||||||
|
*/
|
||||||
|
void serviceIRQ(uint32 irq_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets false when the irq is serviced
|
||||||
|
*/
|
||||||
|
bool probeIRQ;
|
||||||
|
|
||||||
|
ustl::list<BDVirtualDevice *> device_list_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static BDManager *instance_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
101
pwn/flipper/dist/common/include/fs/BDVirtualDevice.h
vendored
Normal file
101
pwn/flipper/dist/common/include/fs/BDVirtualDevice.h
vendored
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ulist.h"
|
||||||
|
#include "ustring.h"
|
||||||
|
|
||||||
|
class BDDriver;
|
||||||
|
class BDRequest;
|
||||||
|
|
||||||
|
class BDDriver;
|
||||||
|
class BDRequest;
|
||||||
|
|
||||||
|
class BDVirtualDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BDVirtualDevice(BDDriver *driver, uint32 offset, uint32 num_sectors, uint32 sector_size, const char *name,
|
||||||
|
bool writable);
|
||||||
|
|
||||||
|
void addRequest(BDRequest *command);
|
||||||
|
|
||||||
|
uint32 getBlockSize() const
|
||||||
|
{
|
||||||
|
return block_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getDeviceNumber() const
|
||||||
|
{
|
||||||
|
return dev_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
BDDriver *getDriver()
|
||||||
|
{
|
||||||
|
return driver_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *getName()
|
||||||
|
{
|
||||||
|
return name_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getNumBlocks()
|
||||||
|
{
|
||||||
|
return num_sectors_ / (block_size_ / sector_size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the data from the inode on the current device
|
||||||
|
* @param offset where to start to read
|
||||||
|
* @param size number of bytes that should be read
|
||||||
|
* @param buffer to save the data that has been read
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual int32 readData(uint32 offset, uint32 size, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the data from the inode on the current device
|
||||||
|
* @param offset where to start to write
|
||||||
|
* @param size number of bytes that should be written
|
||||||
|
* @param buffer data, that should be written
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual int32 writeData(uint32 offset, uint32 size, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the PartitionType is a 8bit field in the PartitionTable of a MBR
|
||||||
|
* it specifies the FileSystem which is installed on the partition
|
||||||
|
* @param part_type partition type value to be applied to the Device
|
||||||
|
*/
|
||||||
|
void setPartitionType(uint8 part_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getting the PartitionType of this Device (value of the 8bit field
|
||||||
|
* in Partition Table of the MBR)
|
||||||
|
* @return the partition type
|
||||||
|
*/
|
||||||
|
uint8 getPartitionType(void) const;
|
||||||
|
|
||||||
|
void setDeviceNumber(uint32 number)
|
||||||
|
{
|
||||||
|
dev_number_ = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBlockSize(uint32 block_size)
|
||||||
|
{
|
||||||
|
assert(block_size % sector_size_ == 0);
|
||||||
|
block_size_ = block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BDVirtualDevice();
|
||||||
|
uint32 dev_number_;
|
||||||
|
uint32 offset_;
|
||||||
|
uint32 num_sectors_;
|
||||||
|
uint32 sector_size_;
|
||||||
|
uint32 block_size_;
|
||||||
|
bool writable_;
|
||||||
|
BDDriver* driver_;
|
||||||
|
uint8 partition_type_;
|
||||||
|
ustl::string name_;
|
||||||
|
};
|
||||||
|
|
165
pwn/flipper/dist/common/include/fs/Dentry.h
vendored
Normal file
165
pwn/flipper/dist/common/include/fs/Dentry.h
vendored
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include <ulist.h>
|
||||||
|
#include "kstring.h"
|
||||||
|
#include <ualgo.h>
|
||||||
|
#include "ustring.h"
|
||||||
|
|
||||||
|
class Inode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The VFS layer does all management of path names of files, and converts them
|
||||||
|
* into entries in the dentry before passing allowing the underlying
|
||||||
|
* file-system to see them. The dentry object associates the component to its
|
||||||
|
* corresponding inode.
|
||||||
|
*/
|
||||||
|
class Dentry
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
friend class MinixFSInode;
|
||||||
|
friend class VfsSyscall;
|
||||||
|
/**
|
||||||
|
* The pointer to the inode related to this name.
|
||||||
|
*/
|
||||||
|
Inode *d_inode_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will point to the parent dentry. For the root of a file-system, or
|
||||||
|
* for an anonymous entry like that for a file, this points back to the
|
||||||
|
* containing dentry itself.
|
||||||
|
*/
|
||||||
|
Dentry *d_parent_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This list_head is used to link together all the children of the dentry.
|
||||||
|
*/
|
||||||
|
ustl::list<Dentry*> d_child_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a directory that has had a file-system mounted on it, this points to
|
||||||
|
* the mount point of that current file-system. For other dentries, this
|
||||||
|
* points back to the dentry itself.
|
||||||
|
*/
|
||||||
|
Dentry *d_mounts_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the inode to the dentry
|
||||||
|
* @param inode the inode to set
|
||||||
|
*/
|
||||||
|
void setInode(Inode *inode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* release the inode to the dentry
|
||||||
|
*/
|
||||||
|
void releaseInode()
|
||||||
|
{
|
||||||
|
d_inode_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the inode to dentry
|
||||||
|
* @return the inode
|
||||||
|
*/
|
||||||
|
Inode* getInode()
|
||||||
|
{
|
||||||
|
return d_inode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the parent of the dentry
|
||||||
|
* @return the dentry
|
||||||
|
*/
|
||||||
|
Dentry* getParent()
|
||||||
|
{
|
||||||
|
return d_parent_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the parent dentry
|
||||||
|
* @param parent the parent dentry to set
|
||||||
|
*/
|
||||||
|
void setParent(Dentry *parent)
|
||||||
|
{
|
||||||
|
d_parent_ = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the mount_point of the current file-system
|
||||||
|
* @return the dentry of the mount point
|
||||||
|
*/
|
||||||
|
Dentry* getMountedRoot()
|
||||||
|
{
|
||||||
|
return d_mounts_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the mount point
|
||||||
|
* @param mount_point the dentry to set the mount point to
|
||||||
|
*/
|
||||||
|
void setMountedRoot(Dentry *mount_point)
|
||||||
|
{
|
||||||
|
d_mounts_ = mount_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the child to the dentry
|
||||||
|
* @param dentry the child dentry to set
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int32 setChild(Dentry *dentry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check the existance of the child-list
|
||||||
|
* @return true is empty
|
||||||
|
*/
|
||||||
|
bool emptyChild();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the number of the child
|
||||||
|
* @return the number of childs
|
||||||
|
*/
|
||||||
|
uint32 getNumChild();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the child of the child-list
|
||||||
|
* @param indes the index of the child to get
|
||||||
|
* @return the found child dentry
|
||||||
|
*/
|
||||||
|
Dentry* getChild(uint32 index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the name of the dentry
|
||||||
|
* @return the dentry's name
|
||||||
|
*/
|
||||||
|
const char* getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should compare the name with the all names of the d_child_ list.
|
||||||
|
* It should return the Dentry if it exists the same name in the list,
|
||||||
|
* @return the dentry found, 0 if doesn't exist.
|
||||||
|
*/
|
||||||
|
virtual Dentry* checkName(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a child_dentry from the d_child_ list.
|
||||||
|
* @param child_dentry the child dentry of the curent dentry.
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 childRemove(Dentry *child_dentry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert a child dentry to the d_child_ list.
|
||||||
|
* @param child_dentry the child dentry of the current dentry.
|
||||||
|
*/
|
||||||
|
virtual void childInsert(Dentry *child_dentry);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Dentry(Inode* inode); // root dentry
|
||||||
|
Dentry(Inode* inode, Dentry* parent, const ustl::string& name); // named dentry
|
||||||
|
virtual ~Dentry();
|
||||||
|
ustl::string d_name_;
|
||||||
|
};
|
||||||
|
|
6
pwn/flipper/dist/common/include/fs/Dirent.h
vendored
Normal file
6
pwn/flipper/dist/common/include/fs/Dirent.h
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Dirent
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
178
pwn/flipper/dist/common/include/fs/File.h
vendored
Normal file
178
pwn/flipper/dist/common/include/fs/File.h
vendored
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ulist.h"
|
||||||
|
|
||||||
|
class Superblock;
|
||||||
|
class Inode;
|
||||||
|
class Dentry;
|
||||||
|
class FileDescriptor;
|
||||||
|
|
||||||
|
#define O_RDONLY 0x0001
|
||||||
|
#define O_WRONLY 0x0002
|
||||||
|
#define O_RDWR 0x0004
|
||||||
|
#define O_CREAT 0x0008
|
||||||
|
#define O_APPEND 0x0010
|
||||||
|
#define O_EXCL 0x0020
|
||||||
|
#define O_NONBLOCK 0x0040
|
||||||
|
#define O_TRUNC 0x0080
|
||||||
|
#define O_SYNC 0x0100
|
||||||
|
#define O_DSYNC 0x0200
|
||||||
|
#define O_RSYNC O_SYNC
|
||||||
|
|
||||||
|
#ifndef SEEK_SET
|
||||||
|
#define SEEK_SET 0
|
||||||
|
#endif
|
||||||
|
#ifndef SEEK_CUR
|
||||||
|
#define SEEK_CUR 1
|
||||||
|
#endif
|
||||||
|
#ifndef SEEK_END
|
||||||
|
#define SEEK_END 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint32 uid;
|
||||||
|
uint32 gid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* interna version number.
|
||||||
|
*/
|
||||||
|
uint32 version;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The superblock pointing to this file
|
||||||
|
*/
|
||||||
|
Superblock* f_superblock_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inode associated to the file.
|
||||||
|
*/
|
||||||
|
Inode* f_inode_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dentry pointing to this file/
|
||||||
|
*/
|
||||||
|
Dentry* f_dentry_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The flags specified when the file was opened
|
||||||
|
*/
|
||||||
|
uint32 flag_;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current offset in the file
|
||||||
|
*/
|
||||||
|
l_off_t offset_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of open file descriptors
|
||||||
|
*/
|
||||||
|
ustl::list<FileDescriptor*> f_fds_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* returns the files flag
|
||||||
|
* @return the flag
|
||||||
|
*/
|
||||||
|
uint32 getFlag()
|
||||||
|
{
|
||||||
|
return flag_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Constructor
|
||||||
|
* @param inode the files inode
|
||||||
|
* @param dentry the files dentry
|
||||||
|
* @param flag the files flag
|
||||||
|
*/
|
||||||
|
File(Inode* inode, Dentry* dentry, uint32 flag);
|
||||||
|
|
||||||
|
virtual ~File();
|
||||||
|
|
||||||
|
virtual FileDescriptor* openFd();
|
||||||
|
virtual int closeFd(FileDescriptor* fd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dentry* getDentry()
|
||||||
|
{
|
||||||
|
return f_dentry_;
|
||||||
|
}
|
||||||
|
Inode* getInode()
|
||||||
|
{
|
||||||
|
return f_inode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file position relative to the start of the file, the end of the
|
||||||
|
* file or the current file position.
|
||||||
|
* @param offset is the offset to set.
|
||||||
|
* @param origin is the on off SEEK_SET, SEEK_CUR and SEEK_END.
|
||||||
|
* @returns the offset from the start off the file or -1 on failure.
|
||||||
|
*/
|
||||||
|
l_off_t lseek(l_off_t offset, uint8 origin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented here
|
||||||
|
* reads from the file
|
||||||
|
* @param buffer is the buffer where the data is written to
|
||||||
|
* @param count is the number of bytes to read.
|
||||||
|
* @param offset is the offset to read from counted from the current file position.
|
||||||
|
*/
|
||||||
|
virtual int32 read(char */*buffer*/, size_t /*count*/, l_off_t /*offset*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented here
|
||||||
|
* write to the file
|
||||||
|
* @param buffer is the buffer where the data is read from
|
||||||
|
* @param count is the number of bytes to write.
|
||||||
|
* @param offset is the offset to write from counted from the current file position
|
||||||
|
*/
|
||||||
|
virtual int32 write(const char */*buffer*/, size_t /*count*/, l_off_t /*offset*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the file
|
||||||
|
* @param inode is the inode the read the file from.
|
||||||
|
*/
|
||||||
|
virtual int32 open(uint32)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented here
|
||||||
|
* Close the file
|
||||||
|
* @param inode is close, the superblock has the information, that this
|
||||||
|
* inode is not use anymore.
|
||||||
|
*/
|
||||||
|
virtual int32 close()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* not implemented here
|
||||||
|
* Flush all off the file's write operations. The File will be written to disk.
|
||||||
|
* @return is the error code of the flush operation.
|
||||||
|
*/
|
||||||
|
virtual int32 flush()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint32 getSize();
|
||||||
|
};
|
42
pwn/flipper/dist/common/include/fs/FileDescriptor.h
vendored
Normal file
42
pwn/flipper/dist/common/include/fs/FileDescriptor.h
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ulist.h"
|
||||||
|
#include "umap.h"
|
||||||
|
#include "Mutex.h"
|
||||||
|
|
||||||
|
class File;
|
||||||
|
class FileDescriptor;
|
||||||
|
class FileDescriptorList;
|
||||||
|
|
||||||
|
class FileDescriptor
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
size_t fd_;
|
||||||
|
File* file_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileDescriptor ( File* file );
|
||||||
|
virtual ~FileDescriptor();
|
||||||
|
uint32 getFd() { return fd_; }
|
||||||
|
File* getFile() { return file_; }
|
||||||
|
|
||||||
|
friend File;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileDescriptorList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileDescriptorList();
|
||||||
|
~FileDescriptorList();
|
||||||
|
|
||||||
|
int add(FileDescriptor* fd);
|
||||||
|
int remove(FileDescriptor* fd);
|
||||||
|
FileDescriptor* getFileDescriptor(uint32 fd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ustl::list<FileDescriptor*> fds_;
|
||||||
|
Mutex fd_lock_;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FileDescriptorList global_fd_list;
|
70
pwn/flipper/dist/common/include/fs/FileSystemInfo.h
vendored
Normal file
70
pwn/flipper/dist/common/include/fs/FileSystemInfo.h
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ustring.h"
|
||||||
|
#include "Path.h"
|
||||||
|
|
||||||
|
class Dentry;
|
||||||
|
class VfsMount;
|
||||||
|
|
||||||
|
class FileSystemInfo
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* File system root
|
||||||
|
*/
|
||||||
|
Path root_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current working directory
|
||||||
|
*/
|
||||||
|
Path pwd_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileSystemInfo();
|
||||||
|
~FileSystemInfo();
|
||||||
|
FileSystemInfo(const FileSystemInfo& fsi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the ROOT-info to the class
|
||||||
|
* @param root the root path to set
|
||||||
|
*/
|
||||||
|
void setRoot(const Path& path)
|
||||||
|
{
|
||||||
|
root_ = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the PWD-info to the class (PWD: print working directory)
|
||||||
|
* @param path the current path to set
|
||||||
|
*/
|
||||||
|
void setPwd(const Path& path)
|
||||||
|
{
|
||||||
|
pwd_ = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the ROOT-info (ROOT-directory) from the class
|
||||||
|
* @return the root path
|
||||||
|
*/
|
||||||
|
Path& getRoot()
|
||||||
|
{
|
||||||
|
return root_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the PWD-info (PWD-directory) from the class
|
||||||
|
* @return the path of the current directory
|
||||||
|
*/
|
||||||
|
Path& getPwd()
|
||||||
|
{
|
||||||
|
return pwd_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FileSystemInfo* default_working_dir;
|
||||||
|
// you use a different getcwd() method depending on where your cpp is being compiled
|
||||||
|
// (it can come either from Thread.cpp or from exe2minixfs.cpp)
|
||||||
|
FileSystemInfo* getcwd();
|
||||||
|
|
54
pwn/flipper/dist/common/include/fs/FileSystemType.h
vendored
Normal file
54
pwn/flipper/dist/common/include/fs/FileSystemType.h
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class Superblock;
|
||||||
|
class Dentry;
|
||||||
|
|
||||||
|
#define FS_REQUIRES_DEV 0x0001 // located on a physical disk device
|
||||||
|
#define FS_NOMOUNT 0x0010 // Filesystem has no mount point
|
||||||
|
|
||||||
|
#define MAX_FILE_SYSTEM_TYPES 16
|
||||||
|
|
||||||
|
class FileSystemType
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *fs_name_;
|
||||||
|
int32 fs_flags_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileSystemType(const char *fs_name);
|
||||||
|
virtual ~FileSystemType();
|
||||||
|
|
||||||
|
FileSystemType const &operator =(FileSystemType const &instance)
|
||||||
|
{
|
||||||
|
fs_name_ = instance.fs_name_;
|
||||||
|
fs_flags_ = instance.fs_flags_;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* getFSName() const;
|
||||||
|
void setFSName(const char* fs_name);
|
||||||
|
int32 getFSFlags() const;
|
||||||
|
void setFSFlags(int32 fs_flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the superblock from the device.
|
||||||
|
* @param superblock is the superblock to fill with data.
|
||||||
|
* @param data is the data given to the mount system call.
|
||||||
|
* @return is a pointer to the resulting superblock.
|
||||||
|
*/
|
||||||
|
virtual Superblock *readSuper(Superblock *superblock, void *data) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Superblock object for the actual file system type.
|
||||||
|
* @param s_dev a valid device number or -1 if no block device is available
|
||||||
|
* (e.g. for pseudo file systems)
|
||||||
|
* @return a pointer to the Superblock object, 0 if wasn't possible to
|
||||||
|
* create a Superblock with the given device number
|
||||||
|
*/
|
||||||
|
virtual Superblock *createSuper(uint32 s_dev) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
283
pwn/flipper/dist/common/include/fs/Inode.h
vendored
Normal file
283
pwn/flipper/dist/common/include/fs/Inode.h
vendored
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include <ulist.h>
|
||||||
|
#include <uatomic.h>
|
||||||
|
#include "Dentry.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
class File;
|
||||||
|
class Superblock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* three possible inode state bits:
|
||||||
|
*/
|
||||||
|
#define I_UNUSED 0 // the unused inode state
|
||||||
|
#define I_DIRTY 1 // Dirty inodes are on the per-super-block s_dirty_ list, and
|
||||||
|
// will be written next time a sync is requested.
|
||||||
|
#define I_LOCK 2 //state not implemented
|
||||||
|
|
||||||
|
#define A_READABLE 0x0001
|
||||||
|
#define A_WRITABLE 0x0002
|
||||||
|
#define A_EXECABLE 0x0004
|
||||||
|
|
||||||
|
/**
|
||||||
|
* five possible inode type bits:
|
||||||
|
*/
|
||||||
|
#define I_FILE 0
|
||||||
|
#define I_DIR 1
|
||||||
|
#define I_LNK 2
|
||||||
|
#define I_CHARDEVICE 3
|
||||||
|
#define I_BLOCKDEVICE 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The per-inode flags:
|
||||||
|
*/
|
||||||
|
#define MS_NODEV 2 // If this inode is a device special file, it cannot be
|
||||||
|
// opend.
|
||||||
|
#define INODE_DEAD 666
|
||||||
|
|
||||||
|
class Inode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
ustl::list<Dentry*> i_dentrys_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The (open) file of this inode.
|
||||||
|
*/
|
||||||
|
ustl::list<File*> i_files_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the number of Dentry links to this inode.
|
||||||
|
*/
|
||||||
|
uint32 i_nlink_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the number of runtime references to this inode (loaded Dentrys, open files, ...)
|
||||||
|
*/
|
||||||
|
uint32 i_refcount_;
|
||||||
|
|
||||||
|
Superblock *superblock_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current file size in bytes
|
||||||
|
*/
|
||||||
|
uint32 i_size_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inode type: I_FILE, I_DIR, I_LNK, ...
|
||||||
|
*/
|
||||||
|
uint32 i_type_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There are three possible inode state bits: I_DIRTY, I_LOCK, I_UNUSED.
|
||||||
|
*/
|
||||||
|
uint32 i_state_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inodes permission flag
|
||||||
|
*/
|
||||||
|
uint32 i_mode_;
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* contructor
|
||||||
|
* @param super_block the superblock to create the inode on
|
||||||
|
* @param inode_type the inode type
|
||||||
|
*/
|
||||||
|
Inode(Superblock *super_block, uint32 inode_type);
|
||||||
|
|
||||||
|
virtual ~Inode();
|
||||||
|
|
||||||
|
uint32 incRefCount();
|
||||||
|
uint32 decRefCount();
|
||||||
|
uint32 numRefs();
|
||||||
|
|
||||||
|
uint32 incLinkCount();
|
||||||
|
uint32 decLinkCount();
|
||||||
|
uint32 numLinks();
|
||||||
|
|
||||||
|
void addDentry(Dentry* dentry);
|
||||||
|
void removeDentry(Dentry* dentry);
|
||||||
|
bool hasDentry(Dentry* dentry);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lookup should check if that name (given by the char-array) exists in the
|
||||||
|
* directory (I_DIR inode) and should return the Dentry if it does.
|
||||||
|
* This involves finding and loading the inode. If the lookup failed to find
|
||||||
|
* anything, this is indicated by returning NULL-pointer.
|
||||||
|
* @param name the name to look for
|
||||||
|
* @return the dentry found
|
||||||
|
*/
|
||||||
|
virtual Dentry* lookup(const char* /*name*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a file is opened
|
||||||
|
*/
|
||||||
|
virtual File* open(Dentry* /*dentry*/, uint32 /*flag*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the last reference to a file is closed
|
||||||
|
*/
|
||||||
|
virtual int32 release(File* /*file*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This should create a symbolic link in the given directory with the given
|
||||||
|
* name having the given value. It should d_instantiate the new inode into
|
||||||
|
* the dentry on success.
|
||||||
|
* @param inode the inode to link to
|
||||||
|
* @param dentry yhe dentry to create the link in
|
||||||
|
* @param link_name the name of the link to create
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 symlink(Inode */*inode*/, Dentry */*dentry*/, const char */*link_name*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a directory with the given dentry.
|
||||||
|
* @param the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 mkdir(Dentry *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file with the given dentry.
|
||||||
|
* @param dentry the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 mkfile(Dentry */*dentry*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a special file with the given dentry.
|
||||||
|
* @param the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 mknod(Dentry*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a hard link with the given dentry.
|
||||||
|
* @param the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 link(Dentry*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink the given dentry from the inode.
|
||||||
|
* @param the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 unlink(Dentry*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the named directory (if empty).
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 rmdir(Dentry*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* change the name to new_name
|
||||||
|
* @param new name the new name
|
||||||
|
* @retunr 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 rename(const char* /*new_name*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The symbolic link referred to by the dentry is read and the value is
|
||||||
|
* copied into the user buffer (with copy_to_user) with a maximum length
|
||||||
|
* given by the integer.
|
||||||
|
* @param dentry the dentry
|
||||||
|
* @param max_length the maximum length
|
||||||
|
* @return the number of bytes read
|
||||||
|
*/
|
||||||
|
virtual int32 readlink(Dentry */*dentry*/, char*, int32 /*max_length*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the directory (parent dentry) have a directory and a name within that
|
||||||
|
* directory (child dentry) then the obvious result of following the name
|
||||||
|
* from the directory would arrive at the child dentry. (for symlink)
|
||||||
|
* @param prt_dentry the parent dentry
|
||||||
|
* @param chd_dentry the child dentry
|
||||||
|
* @return the dentry
|
||||||
|
*/
|
||||||
|
virtual Dentry* followLink(Dentry */*prt_dentry*/, Dentry */*chd_dentry*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read the data from the inode
|
||||||
|
* @param offset the offset from where to start
|
||||||
|
* @param size the number of bytes to read
|
||||||
|
* @param buffer where to store the read data
|
||||||
|
* @return the number of bytes read
|
||||||
|
*/
|
||||||
|
virtual int32 readData(uint32 /*offset*/, uint32 /*size*/, char */*buffer*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write the data to the inode
|
||||||
|
* @param offset the offset from where to start writing
|
||||||
|
* @param size the number of bytes to write
|
||||||
|
* @param buffer where to write the data to
|
||||||
|
* @return number of bytes written
|
||||||
|
*/
|
||||||
|
virtual int32 writeData(uint32 /*offset*/, uint32 /*size*/, const char*/*buffer*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Superblock* getSuperblock()
|
||||||
|
{
|
||||||
|
return superblock_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSuperBlock(Superblock * sb)
|
||||||
|
{
|
||||||
|
superblock_ = sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getType()
|
||||||
|
{
|
||||||
|
return i_type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ustl::list<Dentry*>& getDentrys()
|
||||||
|
{
|
||||||
|
return i_dentrys_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getNumOpenedFile()
|
||||||
|
{
|
||||||
|
return i_files_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getSize()
|
||||||
|
{
|
||||||
|
return i_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getMode()
|
||||||
|
{
|
||||||
|
return i_mode_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 flush()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
28
pwn/flipper/dist/common/include/fs/Path.h
vendored
Normal file
28
pwn/flipper/dist/common/include/fs/Path.h
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ustring.h"
|
||||||
|
|
||||||
|
class Dentry;
|
||||||
|
class VfsMount;
|
||||||
|
|
||||||
|
class Path
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Path() = default;
|
||||||
|
Path(Dentry* dentry, VfsMount* mnt);
|
||||||
|
Path(const Path&) = default;
|
||||||
|
Path& operator=(const Path&) = default;
|
||||||
|
bool operator==(const Path&) const;
|
||||||
|
|
||||||
|
Path parent(const Path* global_root = nullptr) const;
|
||||||
|
int child(const ustl::string& name, Path& out) const;
|
||||||
|
|
||||||
|
ustl::string getAbsolutePath(const Path* global_root = nullptr) const;
|
||||||
|
|
||||||
|
bool isGlobalRoot(const Path* global_root = nullptr) const;
|
||||||
|
bool isMountRoot() const;
|
||||||
|
|
||||||
|
Dentry* dentry_;
|
||||||
|
VfsMount* mnt_;
|
||||||
|
};
|
76
pwn/flipper/dist/common/include/fs/PathWalker.h
vendored
Normal file
76
pwn/flipper/dist/common/include/fs/PathWalker.h
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ustring.h"
|
||||||
|
|
||||||
|
class Dentry;
|
||||||
|
class VfsMount;
|
||||||
|
class Path;
|
||||||
|
class FileSystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum Type of the last component on LOOKUP_PARENT
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The last component is a regular filename
|
||||||
|
*/
|
||||||
|
LAST_NORM,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last component is "."
|
||||||
|
*/
|
||||||
|
LAST_DOT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last component is ".."
|
||||||
|
*/
|
||||||
|
LAST_DOTDOT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum Error Codes for the path walk
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PW_SUCCESS = 0,
|
||||||
|
/**
|
||||||
|
* The path was not found
|
||||||
|
*/
|
||||||
|
PW_ENOTFOUND,
|
||||||
|
/**
|
||||||
|
* The path to look up is invalid
|
||||||
|
*/
|
||||||
|
PW_EINVALID
|
||||||
|
};
|
||||||
|
|
||||||
|
class PathWalker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a file system lookup
|
||||||
|
* @param pathname File pathname to be resolved
|
||||||
|
* @param pwd Start directory of the file system walk
|
||||||
|
* @param root Root directory for the file system walk
|
||||||
|
* @param out Output parameter: Found file path
|
||||||
|
* @param parent Optional output parameter: Parent directory
|
||||||
|
* @return Returns 0 on success, != 0 on error
|
||||||
|
*/
|
||||||
|
static int32 pathWalk(const char* pathname, const Path& pwd, const Path& root, Path& out, Path* parent = nullptr);
|
||||||
|
|
||||||
|
static int32 pathWalk(const char* pathname, FileSystemInfo* fs_info, Path& out, Path* parent_dir = nullptr);
|
||||||
|
|
||||||
|
static ustl::string pathPrefix(const ustl::string& path);
|
||||||
|
static ustl::string lastPathSegment(const ustl::string& path, bool ignore_separator_at_end = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static size_t getNextPartLen(const char* path);
|
||||||
|
static int pathSegmentType(const char* segment);
|
||||||
|
|
||||||
|
PathWalker();
|
||||||
|
~PathWalker();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
162
pwn/flipper/dist/common/include/fs/Superblock.h
vendored
Normal file
162
pwn/flipper/dist/common/include/fs/Superblock.h
vendored
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include <ulist.h>
|
||||||
|
|
||||||
|
class Iattr;
|
||||||
|
class Statfs;
|
||||||
|
class WaitQueue;
|
||||||
|
class FileSystemType;
|
||||||
|
class VirtualFileSystem;
|
||||||
|
class FileDescriptor;
|
||||||
|
|
||||||
|
class Dentry;
|
||||||
|
class Inode;
|
||||||
|
class File;
|
||||||
|
|
||||||
|
class Superblock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
friend class VirtualFileSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This records an identification number that has been read from the device
|
||||||
|
* to confirm that the data on the device corresponds to the file-system
|
||||||
|
*/
|
||||||
|
uint64 s_magic_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const FileSystemType *s_type_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The device that this file-system is mounted on.
|
||||||
|
*/
|
||||||
|
size_t s_dev_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a list of flags which are logically with the flags in each
|
||||||
|
* inode to detemine certain behaviours. There is one flag which applies
|
||||||
|
* only to the whole file-system.
|
||||||
|
* exp: MS_RDONLY
|
||||||
|
* A file-system with the flag set has been mounted read-only. No writing
|
||||||
|
* be permitted, and no indirect modification, such as mount time in the
|
||||||
|
* super-block or access times on files, will be made.
|
||||||
|
*/
|
||||||
|
uint64 s_flags_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Dentry refers the root of the file-system. It is normally created by
|
||||||
|
* loading the root inode from the file-system.
|
||||||
|
*/
|
||||||
|
Dentry *s_root_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The old Dentry of the mount point of a mounted file system
|
||||||
|
*/
|
||||||
|
Dentry *s_mountpoint_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of dirty inodes.
|
||||||
|
*/
|
||||||
|
ustl::list<Inode*> dirty_inodes_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of used inodes. It is only used to open-file.
|
||||||
|
*/
|
||||||
|
ustl::list<Inode*> used_inodes_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inodes of the superblock.
|
||||||
|
*/
|
||||||
|
ustl::list<Inode*> all_inodes_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a list of files (linked on f_list) of open files on this
|
||||||
|
* file-system. It is used, for example, to check if there are any files
|
||||||
|
* open for write before remounting the file-system as read-only.
|
||||||
|
*/
|
||||||
|
ustl::list<File*> s_files_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param s_dev the device number of the new filesystem
|
||||||
|
*/
|
||||||
|
Superblock(FileSystemType* fs_type, size_t s_dev);
|
||||||
|
|
||||||
|
virtual ~Superblock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new Inode of the superblock
|
||||||
|
* @param dentry the dentry to create the inode with
|
||||||
|
* @param type the inode type
|
||||||
|
* @return the created inode
|
||||||
|
*/
|
||||||
|
virtual Inode* createInode(uint32 type) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called to read a specific inode from a mounted
|
||||||
|
* file-system.
|
||||||
|
* @param inode the inode to read
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 readInode(Inode* /*inode*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called to write a specific inode to a mounted file-system,
|
||||||
|
* and gets called on inodes which have been marked dirty.
|
||||||
|
* @param inode the inode to write
|
||||||
|
*/
|
||||||
|
virtual void writeInode(Inode* /*inode*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called whenever the reference count on an inode reaches 0,
|
||||||
|
* and it is found that the link count (i_nlink= is also zero. It si
|
||||||
|
* presumed that the file-system will deal with this situation be
|
||||||
|
* invalidating the inode in the file-system and freeing up any resourses
|
||||||
|
* used.
|
||||||
|
* @param inode the inode to delete
|
||||||
|
*/
|
||||||
|
virtual void deleteInode(Inode* /*inode*/);
|
||||||
|
|
||||||
|
|
||||||
|
virtual int fileOpened(File* file);
|
||||||
|
virtual int fileReleased(File* file);
|
||||||
|
|
||||||
|
virtual void releaseAllOpenFiles();
|
||||||
|
virtual void deleteAllInodes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the root Dentry of the Superblock
|
||||||
|
* @return the root dentry
|
||||||
|
*/
|
||||||
|
Dentry *getRoot();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mount point Dentry of the Superblock
|
||||||
|
* @return the superblocks mount point dentry
|
||||||
|
*/
|
||||||
|
Dentry *getMountPoint();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the mount point Dentry of the Superblock
|
||||||
|
*/
|
||||||
|
void setMountPoint(Dentry* mountpoint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the File System Type of the Superblock
|
||||||
|
* @return the file system type
|
||||||
|
*/
|
||||||
|
FileSystemType *getFSType();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
108
pwn/flipper/dist/common/include/fs/VfsMount.h
vendored
Normal file
108
pwn/flipper/dist/common/include/fs/VfsMount.h
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "VirtualFileSystem.h"
|
||||||
|
|
||||||
|
class Superblock;
|
||||||
|
class Dentry;
|
||||||
|
|
||||||
|
extern VirtualFileSystem vfs;
|
||||||
|
|
||||||
|
// Mount flags
|
||||||
|
// Only MS_RDONLY is supported by now.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mount the Filesystem read-only
|
||||||
|
*/
|
||||||
|
#define MS_RDONLY 1
|
||||||
|
|
||||||
|
class VfsMount
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to the parent filesystem on which this filesystem is mounted on.
|
||||||
|
*/
|
||||||
|
VfsMount *mnt_parent_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to the Dentry of the mount directory of this filesystem.
|
||||||
|
*/
|
||||||
|
Dentry *mnt_mountpoint_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to the Dentry of the root directory of this filesystem.
|
||||||
|
*/
|
||||||
|
Dentry *mnt_root_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to the superblock object of this filesystem.
|
||||||
|
*/
|
||||||
|
Superblock *mnt_sb_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mnt_flags_ field of the descriptor stores the value of several flags
|
||||||
|
* that specify how some kinds of files in the mounted filesystem are
|
||||||
|
* handled.
|
||||||
|
*/
|
||||||
|
int32 mnt_flags_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VfsMount();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param parent the parent dentry of the mount point
|
||||||
|
* @param mountpoint the mount points dentry
|
||||||
|
* @param root the root dentry
|
||||||
|
* @param superblock the superblock mounted
|
||||||
|
* @param flags the flags
|
||||||
|
*/
|
||||||
|
VfsMount(VfsMount* parent, Dentry * mountpoint, Dentry* root,
|
||||||
|
Superblock* superblock, int32 flags);
|
||||||
|
|
||||||
|
virtual ~VfsMount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the parent-VfsMount of the VfsMount
|
||||||
|
* @return the parent-VfsMount
|
||||||
|
*/
|
||||||
|
VfsMount *getParent() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the mount-point of the VfsMount
|
||||||
|
* @return the mount point dentry
|
||||||
|
*/
|
||||||
|
Dentry *getMountPoint() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the ROOT-directory of the VfsMount
|
||||||
|
* @return the root dentry
|
||||||
|
*/
|
||||||
|
Dentry *getRoot() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the superblock fo the VfsMount
|
||||||
|
* @return the superblock
|
||||||
|
*/
|
||||||
|
Superblock *getSuperblock() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the flags
|
||||||
|
* @return the flags
|
||||||
|
*/
|
||||||
|
int32 getFlags() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE: only used as workaround
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
|
bool isRootMount() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
150
pwn/flipper/dist/common/include/fs/VfsSyscall.h
vendored
Normal file
150
pwn/flipper/dist/common/include/fs/VfsSyscall.h
vendored
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class Dirent;
|
||||||
|
class Dentry;
|
||||||
|
class VfsMount;
|
||||||
|
class FileDescriptor;
|
||||||
|
class VfsSyscall;
|
||||||
|
class Path;
|
||||||
|
class FileSystemInfo;
|
||||||
|
|
||||||
|
class VfsSyscall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make a new directory.
|
||||||
|
* i.e. im the path "/file/test/" create a new directory with the name
|
||||||
|
* "dir". => the new_dir ist "/file/test/dir"
|
||||||
|
* @param pathname the new directory.
|
||||||
|
* @param type the permission.
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 mkdir(const char* pathname, int32 /*type*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The readdir() displays or saves the names from all childs into buffer and returns a pointer
|
||||||
|
* to a Dirent.
|
||||||
|
* @param pathname the destination-directory.
|
||||||
|
* @param buffer the buffer the output is saved to
|
||||||
|
* @param size the size of buffer in bytes
|
||||||
|
* @return the dirent
|
||||||
|
*/
|
||||||
|
static Dirent* readdir(const char* pathname, char* buffer = 0, size_t size = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* chdir() changes the current directory to the specified directory.
|
||||||
|
* @param dir the destination-directory.
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 chdir(const char* pathname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete a directory, which must be empty.
|
||||||
|
* @param pathname the removed directory
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 rmdir(const char* pathname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a directory (which must be empty) or a file
|
||||||
|
* @param pathname the removed directory or file
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 rm(const char* pathname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The open() is used to convert a pathname into a file descriptor, if the
|
||||||
|
* pathname does not exist, create a new file.
|
||||||
|
* @param pathname the file pathname
|
||||||
|
* @param flag specified when the file was opened
|
||||||
|
* @return On success, file descriptor is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 open(const char* pathname, uint32 flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The close() closes a file descriptor.
|
||||||
|
* @param fd the file descriptor
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 close(uint32 fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The read() attempts to read up to count bytes from file descriptor fd
|
||||||
|
* into the buffer starting at buffter.
|
||||||
|
* @param fd the file descriptor
|
||||||
|
* @param buffer the buffer that to read the date
|
||||||
|
* @param count the size of the byte
|
||||||
|
* @return On success, the number of bytes read is returned (zero indicates
|
||||||
|
* end of file), and the file position is advanced by this number.
|
||||||
|
* On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
static int32 read(uint32 fd, char* buffer, uint32 count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file position relative to the start of the file, the end of the
|
||||||
|
* file or the current file position.
|
||||||
|
* @param fd the file descriptor
|
||||||
|
* @param offset is the offset to set.
|
||||||
|
* @param origin is the on off SEEK_SET, SEEK_CUR and SEEK_END.
|
||||||
|
* @returns the offset from the start off the file or -1 on failure.
|
||||||
|
*/
|
||||||
|
static l_off_t lseek(uint32 fd, l_off_t offset, uint8 origin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write writes up to count bytes to the file referenced by the file
|
||||||
|
* descriptor fd from the buffer starting at buf.
|
||||||
|
* @param fd the file descriptor
|
||||||
|
* @param buffer the buffer that to store the date
|
||||||
|
* @param count the size of the byte
|
||||||
|
* @return On success, the number of bytes written are returned (zero
|
||||||
|
* indicates nothing was written). On error, -1 is returned
|
||||||
|
*/
|
||||||
|
static int32 write(uint32 fd, const char *buffer, uint32 count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flushes the file with the given file descriptor to the disc
|
||||||
|
* so that changes in the system are written to disc
|
||||||
|
* @param fd the file descriptor
|
||||||
|
* @return 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
static int32 flush(uint32 fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mounts a file system
|
||||||
|
* @param device_name the device name i.e. ida
|
||||||
|
* @param dir_name the directory name where to mount the filesystem
|
||||||
|
* @param file_system_name the file system name i.e. minixfs
|
||||||
|
* @param flag the flag indicates if mounted readonly etc.
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
static int32 mount(const char *device_name, const char *dir_name, const char *file_system_name, int32 flag);
|
||||||
|
|
||||||
|
/** unmounts a filesystem
|
||||||
|
* @param dir_name the directory where the filesystem to unmount is mounted
|
||||||
|
* @param flag not used
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
static int32 umount(const char *dir_name, int32 flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the size of a file
|
||||||
|
* @param fd the file looking for
|
||||||
|
* @return the size
|
||||||
|
*/
|
||||||
|
static uint32 getFileSize(uint32 fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the File descriptor object from the global variable
|
||||||
|
* @param the fd int
|
||||||
|
* @return the file descriptor object
|
||||||
|
*/
|
||||||
|
static FileDescriptor* getFileDescriptor(uint32 fd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
VfsSyscall();
|
||||||
|
~VfsSyscall();
|
||||||
|
};
|
||||||
|
|
106
pwn/flipper/dist/common/include/fs/VirtualFileSystem.h
vendored
Normal file
106
pwn/flipper/dist/common/include/fs/VirtualFileSystem.h
vendored
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include <ustl/ulist.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File system flag indicating if the system in question requires an device.
|
||||||
|
*/
|
||||||
|
#define FS_REQUIRES_DEV 0x0001 // located on a physical disk device
|
||||||
|
#define FS_NOMOUNT 0x0010 // Filesystem has no mount point
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximal number of file system types.
|
||||||
|
*/
|
||||||
|
#define MAX_FILE_SYSTEM_TYPES 16
|
||||||
|
|
||||||
|
class Superblock;
|
||||||
|
class FileSystemType;
|
||||||
|
class VfsMount;
|
||||||
|
class Dentry;
|
||||||
|
class FileSystemInfo;
|
||||||
|
|
||||||
|
class VirtualFileSystem
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
ustl::list<Superblock*> superblocks_;
|
||||||
|
ustl::list<VfsMount*> mounts_;
|
||||||
|
ustl::list<FileSystemType*> file_system_types_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void initialize();
|
||||||
|
VirtualFileSystem();
|
||||||
|
~VirtualFileSystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register the file-system-type to the vfs
|
||||||
|
* @param file_system_type the file system type to register
|
||||||
|
* @return 0 on success, -1 if a file-system-type with that name has
|
||||||
|
* already been registered
|
||||||
|
*/
|
||||||
|
int32 registerFileSystem(FileSystemType *file_system_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unregister the file-system-typt to the vfs
|
||||||
|
* @param file_system_type the file system type to unregister
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
int32 unregisterFileSystem(FileSystemType *file_system_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The getFsType function receives a filesystem name as its parameter, scans
|
||||||
|
* the list of registered filesystems looking at the fs_name field of their
|
||||||
|
* descriptors, and returns a pointer to the corresponding FileSystemType
|
||||||
|
* object, if is present.
|
||||||
|
* @param fs_name the name of the filesystem
|
||||||
|
* @return the file system type
|
||||||
|
*/
|
||||||
|
FileSystemType *getFsType(const char* fs_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* found the VfsMount from mounts_ list with given dentry.
|
||||||
|
* @param dentry the mount-point-dentry or root-dentry
|
||||||
|
* @param is_mount_point if it is false, check with root-dentry,
|
||||||
|
* else mount-point-dentry
|
||||||
|
*/
|
||||||
|
VfsMount *getVfsMount(const Dentry* dentry, bool is_root = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mount the dev_name (device name) to the directory specified by dir_name.
|
||||||
|
* @param dev_name the device file name of the block device storing the
|
||||||
|
* filesystem. Shall be a empty string to mount pseudo
|
||||||
|
* file sytems.
|
||||||
|
* @param dir_name the mount pointer directory
|
||||||
|
* @param fs_name the name of the type of filesystem to be mounted
|
||||||
|
* @param flags the mount flags
|
||||||
|
* @param data contain arbitray fs-dependent information (or be NULL)
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
int32 mount(const char* dev_name, const char* dir_name, const char* fs_name, uint32 flags/*, void *data*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unmount the filesystem
|
||||||
|
* @param dir_name the mount pointer direcotry or (block devie block filename)
|
||||||
|
* @param flags the umount flags
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
int32 umount(const char* dir_name, uint32 flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mount the ROOT to the VFS. (special of the mount)
|
||||||
|
* @param fs_name the name of the type of filesystem to be mounted
|
||||||
|
* @param flags the mount flags
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
FileSystemInfo *rootMount(const char* fs_name, uint32 flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* umount the ROOT from the VFS (special of the umount)
|
||||||
|
* @return On success, zero is returned. On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
int32 rootUmount();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern VirtualFileSystem vfs;
|
||||||
|
|
44
pwn/flipper/dist/common/include/fs/devicefs/DeviceFSSuperblock.h
vendored
Normal file
44
pwn/flipper/dist/common/include/fs/devicefs/DeviceFSSuperblock.h
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/Superblock.h"
|
||||||
|
#include "fs/ramfs/RamFSSuperblock.h"
|
||||||
|
|
||||||
|
class Inode;
|
||||||
|
class Superblock;
|
||||||
|
class CharacterDevice;
|
||||||
|
class DeviceFSType;
|
||||||
|
|
||||||
|
class DeviceFSSuperBlock : public RamFSSuperblock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char ROOT_NAME[];
|
||||||
|
static const char DEVICE_ROOT_NAME[];
|
||||||
|
|
||||||
|
virtual ~DeviceFSSuperBlock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addsa new device to the superblock
|
||||||
|
* @param inode the inode of the device to add
|
||||||
|
* @param node_name the device name
|
||||||
|
*/
|
||||||
|
void addDevice(Inode* inode, const char* node_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access method to the singleton instance
|
||||||
|
*/
|
||||||
|
static DeviceFSSuperBlock* getInstance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param s_root the root Dentry of the new Filesystem
|
||||||
|
* @param s_dev the device number of the new Filesystem
|
||||||
|
*/
|
||||||
|
DeviceFSSuperBlock(DeviceFSType* fs_type, uint32 s_dev);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static DeviceFSSuperBlock* instance_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
34
pwn/flipper/dist/common/include/fs/devicefs/DeviceFSType.h
vendored
Normal file
34
pwn/flipper/dist/common/include/fs/devicefs/DeviceFSType.h
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/FileSystemType.h"
|
||||||
|
#include "fs/ramfs/RamFSType.h"
|
||||||
|
|
||||||
|
class DeviceFSType : public RamFSType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DeviceFSType();
|
||||||
|
|
||||||
|
virtual ~DeviceFSType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the superblock from the device.
|
||||||
|
* @param superblock is the superblock to fill with data.
|
||||||
|
* @param data is the data given to the mount system call.
|
||||||
|
* @return is a pointer to the resulting superblock.
|
||||||
|
*/
|
||||||
|
virtual Superblock *readSuper(Superblock *superblock, void *data) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Superblock object for the actual file system type.
|
||||||
|
* @param root the root dentry of the new superblock
|
||||||
|
* @param s_dev the device number of the new superblock
|
||||||
|
* @return a pointer to the Superblock object
|
||||||
|
*/
|
||||||
|
virtual Superblock *createSuper(uint32 s_dev);
|
||||||
|
|
||||||
|
static DeviceFSType* getInstance();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static DeviceFSType* instance_;
|
||||||
|
};
|
||||||
|
|
43
pwn/flipper/dist/common/include/fs/minixfs/MinixFSFile.h
vendored
Normal file
43
pwn/flipper/dist/common/include/fs/minixfs/MinixFSFile.h
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "File.h"
|
||||||
|
|
||||||
|
class MinixFSFile : public File
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param inode the inode of the file
|
||||||
|
* @param dentry the dentry
|
||||||
|
* @param flag the flag i.e. readonly
|
||||||
|
*/
|
||||||
|
MinixFSFile(Inode* inode, Dentry* dentry, uint32 flag);
|
||||||
|
|
||||||
|
virtual ~MinixFSFile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads from the file
|
||||||
|
* @param buffer the buffer where the data is written to
|
||||||
|
* @param count the number of bytes to read
|
||||||
|
* @param offset the offset to read from counted from the current file position
|
||||||
|
* @return the number of bytes read
|
||||||
|
*/
|
||||||
|
virtual int32 read(char *buffer, size_t count, l_off_t offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes to the file
|
||||||
|
* @param buffer the buffer where the data is read from
|
||||||
|
* @param count the number of bytes to write
|
||||||
|
* @param offset the offset to write from counted from the current file position
|
||||||
|
* @return the number of bytes written
|
||||||
|
*/
|
||||||
|
virtual int32 write(const char *buffer, size_t count, l_off_t offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes all data to disc
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 flush();
|
||||||
|
};
|
||||||
|
|
141
pwn/flipper/dist/common/include/fs/minixfs/MinixFSInode.h
vendored
Normal file
141
pwn/flipper/dist/common/include/fs/minixfs/MinixFSInode.h
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "kstring.h"
|
||||||
|
#include "Inode.h"
|
||||||
|
#include "MinixFSZone.h"
|
||||||
|
#include <ulist.h>
|
||||||
|
|
||||||
|
class MinixFSInode : public Inode
|
||||||
|
{
|
||||||
|
friend class MinixFSSuperblock;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the zones storing the addresses of memory of this inode
|
||||||
|
*/
|
||||||
|
MinixFSZone *i_zones_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the inode number (the first inode has the i_num 1 on a minix file system)
|
||||||
|
*/
|
||||||
|
uint32 i_num_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads all the inode's children from disc and creates their objects
|
||||||
|
*/
|
||||||
|
virtual void loadChildren();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* basic constructor
|
||||||
|
* @param super_block the superblock the inode is on
|
||||||
|
* @param inode_type the inode type (I_FILE, I_DIR)
|
||||||
|
*/
|
||||||
|
MinixFSInode(Superblock *super_block, uint32 inode_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor of an inode existing on disc with all data given
|
||||||
|
* @param super_block the superblock the inode is on
|
||||||
|
* @param i_mode the mode containing the rights and the inode type (I_FILE, I_DIR)
|
||||||
|
* @param i_size the inodes size
|
||||||
|
* @param i_nlinks the number of links to this inode
|
||||||
|
* @param i_zones the first 9 zone addresses
|
||||||
|
* @param i_num the inode number
|
||||||
|
*/
|
||||||
|
MinixFSInode(Superblock *super_block, uint16 i_mode, uint32 i_size, uint16 i_nlinks, uint32* i_zones, uint32 i_num);
|
||||||
|
virtual ~MinixFSInode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lookup checks if that name (given by the char-array) exists in the
|
||||||
|
* directory (I_DIR inode) and returns the Dentry if it does.
|
||||||
|
* This involves finding and loading the inode. If the lookup failed to find
|
||||||
|
* anything, this is indicated by returning NULL-pointer.
|
||||||
|
* @param name the name to look for
|
||||||
|
* @return the dentry found or NULL otherwise
|
||||||
|
*/
|
||||||
|
virtual Dentry* lookup(const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a file is opened
|
||||||
|
*/
|
||||||
|
virtual File* open(Dentry* dentry, uint32 /*flag*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a directory with the given dentry. It is only used to with directory.
|
||||||
|
* @param dentry the dentry to create with
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 mkdir(Dentry *dentry);
|
||||||
|
|
||||||
|
virtual int32 link(Dentry* dentry);
|
||||||
|
virtual int32 unlink(Dentry* dentry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes the directory (if it is empty)
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 rmdir(Dentry* dentry);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a directory with the given dentry.
|
||||||
|
* @param dentry the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 mknod(Dentry *dentry); // no dir no file
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a file with the given dentry.
|
||||||
|
* @param dentry the dentry
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 mkfile(Dentry *dentry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read the data from the inode
|
||||||
|
* @param offset offset byte
|
||||||
|
* @param size the size of data that read from this inode
|
||||||
|
* @param buffer the dest char-array to store the data
|
||||||
|
* @return the number of bytes read
|
||||||
|
*/
|
||||||
|
virtual int32 readData(uint32 offset, uint32 size, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write the data to the inode
|
||||||
|
* @param offset offset byte
|
||||||
|
* @param size the size of data that write to this inode (data_)
|
||||||
|
* @param buffer the src char-array
|
||||||
|
* @return the number of bytes written
|
||||||
|
*/
|
||||||
|
virtual int32 writeData(uint32 offset, uint32 size, const char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flushes the inode to the file system
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 flush();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* writes the inode dentry to disc
|
||||||
|
* @param dest_i_num the inode number to write the dentry to
|
||||||
|
* @param src_i_num the inode number to write
|
||||||
|
* @param name the name to write there
|
||||||
|
*/
|
||||||
|
void writeDentry(uint32 dest_i_num, uint32 src_i_num, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finding the position of the dentry of the given inode in this inode
|
||||||
|
* @param i_num the inode number to look for
|
||||||
|
* @return the dentry position
|
||||||
|
*/
|
||||||
|
int32 findDentry(uint32 i_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if the inodes children are allready loaded
|
||||||
|
*/
|
||||||
|
bool children_loaded_;
|
||||||
|
};
|
201
pwn/flipper/dist/common/include/fs/minixfs/MinixFSSuperblock.h
vendored
Normal file
201
pwn/flipper/dist/common/include/fs/minixfs/MinixFSSuperblock.h
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Superblock.h"
|
||||||
|
#include "MinixStorageManager.h"
|
||||||
|
#include "umap.h"
|
||||||
|
|
||||||
|
class Inode;
|
||||||
|
class MinixFSInode;
|
||||||
|
class Superblock;
|
||||||
|
class MinixFSType;
|
||||||
|
|
||||||
|
class MinixFSSuperblock : public Superblock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend class MinixFSInode;
|
||||||
|
friend class MinixFSZone;
|
||||||
|
friend class MinixStorageManager;
|
||||||
|
|
||||||
|
MinixFSSuperblock(MinixFSType* fs_type, size_t s_dev, uint64 offset);
|
||||||
|
virtual ~MinixFSSuperblock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates one new inode of the superblock
|
||||||
|
* @param type the file type of the new inode (I_DIR, I_FILE)
|
||||||
|
* @return the new inode
|
||||||
|
*/
|
||||||
|
virtual Inode* createInode(uint32 type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads one inode from the mounted file system
|
||||||
|
* @param inode the inode to read
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 readInode(Inode* inode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the inode from the mounted file system
|
||||||
|
* @param inode the inode to write
|
||||||
|
*/
|
||||||
|
virtual void writeInode(Inode* inode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes one inode from the file system and frees all its resources
|
||||||
|
* @param inode the inode to delete
|
||||||
|
*/
|
||||||
|
virtual void deleteInode(Inode* inode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add an inode to the all_inodes_ data structures
|
||||||
|
* @param inode to add
|
||||||
|
*/
|
||||||
|
void all_inodes_add_inode(Inode* inode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove an inode to the all_inodes_ data structures
|
||||||
|
* @param inode to remove
|
||||||
|
*/
|
||||||
|
void all_inodes_remove_inode(Inode* inode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* allocates one zone on the file system
|
||||||
|
* @return the zone index
|
||||||
|
*/
|
||||||
|
virtual uint16 allocateZone();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* frees zone on the file system
|
||||||
|
* @param index the zone index
|
||||||
|
*/
|
||||||
|
virtual void freeZone(uint16 index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates an Inode object with the given number from the file system
|
||||||
|
* @param i_num the inode number
|
||||||
|
* @return the Inode object
|
||||||
|
*/
|
||||||
|
MinixFSInode *getInode(uint16 i_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates an Inode object with the given number from the file system
|
||||||
|
* this overloaded version should be used; directories usually have
|
||||||
|
* "." and ".." entries, which are pointing to already loaded inodes!!!
|
||||||
|
* by now this method is only called from MinixFSInode::loadChildren
|
||||||
|
* @param i_num the inode number
|
||||||
|
* @param is_already_loaded should be set to true if already loaded
|
||||||
|
* @return the Inode object
|
||||||
|
*/
|
||||||
|
MinixFSInode *getInode(uint16 i_num, bool &is_already_loaded);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads one Zone from the file system to the given buffer
|
||||||
|
* @param zone the zone index to read
|
||||||
|
* @param buffer the buffer to write in
|
||||||
|
*/
|
||||||
|
void readZone(uint16 zone, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the given number of blocks from the file system to the given buffer
|
||||||
|
* @param block the index of the block to start reading
|
||||||
|
* @param num_blocks the number of blcoks to read
|
||||||
|
* @param buffer the buffer to write in
|
||||||
|
*/
|
||||||
|
void readBlocks(uint16 block, uint32 num_blocks, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes one zone from the given buffer to the file system
|
||||||
|
* @param zone the zone index to write
|
||||||
|
* @param buffer the buffer to write
|
||||||
|
*/
|
||||||
|
void writeZone(uint16 zone, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the given number of blcoks to the file system from the given buffer
|
||||||
|
* @param block the index of the first block to write
|
||||||
|
* @param num_blocks the number of blocks to write
|
||||||
|
* @param buffer the buffer to write
|
||||||
|
*/
|
||||||
|
void writeBlocks(uint16 block, uint32 num_blocks, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes the given number of bytes to the filesystem
|
||||||
|
* the bytes must be on one block
|
||||||
|
* @param block the block to write to
|
||||||
|
* @param offset the offset on the block
|
||||||
|
* @param size the number of bytes to write
|
||||||
|
* @param buffer the buffer with the bytes to write
|
||||||
|
* @return the number of bytes written
|
||||||
|
*/
|
||||||
|
int32 writeBytes(uint32 block, uint32 offset, uint32 size, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the given number of bytes from the disc
|
||||||
|
* the bytes must be on one block
|
||||||
|
* @param block the block to read from
|
||||||
|
* @param offset the offset on the block
|
||||||
|
* @param size the number of bytes to read
|
||||||
|
* @param buffer the buffer to write to
|
||||||
|
* @return the number of bytes read
|
||||||
|
*/
|
||||||
|
int32 readBytes(uint32 block, uint32 offset, uint32 size, char *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the fs header
|
||||||
|
*/
|
||||||
|
void readHeader();
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the root inode and its children from the filesystem
|
||||||
|
*/
|
||||||
|
void initInodes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # usable inodes on the minor device
|
||||||
|
*/
|
||||||
|
uint32 s_num_inodes_;
|
||||||
|
/**
|
||||||
|
* # of blocks used by inode bit map
|
||||||
|
*/
|
||||||
|
uint16 s_num_inode_bm_blocks_;
|
||||||
|
/**
|
||||||
|
* # of blocks used by zone bit map
|
||||||
|
*/
|
||||||
|
uint16 s_num_zone_bm_blocks_;
|
||||||
|
/**
|
||||||
|
* number of first datazone
|
||||||
|
*/
|
||||||
|
uint16 s_1st_datazone_;
|
||||||
|
/**
|
||||||
|
* log2 of blocks/zone
|
||||||
|
*/
|
||||||
|
uint16 s_log_zone_size_;
|
||||||
|
/**
|
||||||
|
* maximum file size on this device
|
||||||
|
*/
|
||||||
|
uint32 s_max_file_size_;
|
||||||
|
|
||||||
|
uint32 s_zones_;
|
||||||
|
|
||||||
|
uint16 s_block_size_;
|
||||||
|
|
||||||
|
uint8 s_disk_version_;
|
||||||
|
|
||||||
|
MinixStorageManager* storage_manager_;
|
||||||
|
|
||||||
|
|
||||||
|
ustl::map<uint32, Inode*> all_inodes_set_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pointer to self for compatability
|
||||||
|
*/
|
||||||
|
Superblock* superblock_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* offset in the image file (in image util)
|
||||||
|
*/
|
||||||
|
uint64 offset_;
|
||||||
|
};
|
||||||
|
|
26
pwn/flipper/dist/common/include/fs/minixfs/MinixFSType.h
vendored
Normal file
26
pwn/flipper/dist/common/include/fs/minixfs/MinixFSType.h
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FileSystemType.h"
|
||||||
|
|
||||||
|
class MinixFSType : public FileSystemType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MinixFSType();
|
||||||
|
virtual ~MinixFSType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads the superblock from the device
|
||||||
|
* @param superblock a pointer to the resulting superblock
|
||||||
|
* @param data the data given to the mount system call
|
||||||
|
* @return the superblock
|
||||||
|
*/
|
||||||
|
virtual Superblock *readSuper(Superblock *superblock, void *data) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates an Superblock object for the actual file system type
|
||||||
|
* @param root the root dentry
|
||||||
|
* @param s_dev the device number
|
||||||
|
*/
|
||||||
|
virtual Superblock *createSuper(uint32 s_dev);
|
||||||
|
};
|
||||||
|
|
39
pwn/flipper/dist/common/include/fs/minixfs/MinixFSZone.h
vendored
Normal file
39
pwn/flipper/dist/common/include/fs/minixfs/MinixFSZone.h
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class MinixFSSuperblock;
|
||||||
|
|
||||||
|
class MinixFSZone
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param superblock the superblock
|
||||||
|
* @param zones the zone array from the file system
|
||||||
|
*/
|
||||||
|
MinixFSZone(MinixFSSuperblock *superblock, uint32 *zones);
|
||||||
|
~MinixFSZone();
|
||||||
|
uint32 getZone(uint32 index);
|
||||||
|
void setZone(uint32 index, uint32 zone);
|
||||||
|
void addZone(uint32 zone);
|
||||||
|
uint32 getNumZones()
|
||||||
|
{
|
||||||
|
return num_zones_;
|
||||||
|
}
|
||||||
|
void flush(uint32 inode_num);
|
||||||
|
void freeZones();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MinixFSSuperblock *superblock_;
|
||||||
|
uint32 direct_zones_[10];
|
||||||
|
uint32 *indirect_zones_;
|
||||||
|
uint32 *double_indirect_linking_zone_;
|
||||||
|
uint32 **double_indirect_zones_;
|
||||||
|
|
||||||
|
uint32 num_zones_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
45
pwn/flipper/dist/common/include/fs/minixfs/MinixStorageManager.h
vendored
Normal file
45
pwn/flipper/dist/common/include/fs/minixfs/MinixStorageManager.h
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "StorageManager.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "minix_fs_consts.h"
|
||||||
|
|
||||||
|
class MinixFSSuperblock;
|
||||||
|
|
||||||
|
class MinixStorageManager : public StorageManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param bm_buffer the buffer with the inode and zone bitmaps from disc
|
||||||
|
* @param num_inode_bm_blocks the number of blocks used for the inode bitmap
|
||||||
|
* @param num_zone_bm_blocks the number of blocks used for the zone bitmap
|
||||||
|
* @param num_inodes the max number of inodes
|
||||||
|
* @param num_zones the max number of zones
|
||||||
|
*/
|
||||||
|
MinixStorageManager(char *bm_buffer, uint16 num_inode_bm_blocks, uint16 num_zone_bm_blocks, uint16 num_inodes,
|
||||||
|
uint16 num_zones);
|
||||||
|
|
||||||
|
virtual ~MinixStorageManager();
|
||||||
|
|
||||||
|
virtual size_t allocZone();
|
||||||
|
virtual size_t allocInode();
|
||||||
|
virtual void freeZone(size_t index);
|
||||||
|
virtual void freeInode(size_t index);
|
||||||
|
virtual bool isInodeSet(size_t index);
|
||||||
|
virtual uint32 getNumUsedInodes();
|
||||||
|
void flush(MinixFSSuperblock *superblock);
|
||||||
|
void printBitmap();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
size_t curr_zone_pos_;
|
||||||
|
size_t curr_inode_pos_;
|
||||||
|
|
||||||
|
uint32 num_inode_bm_blocks_;
|
||||||
|
uint32 num_zone_bm_blocks_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
44
pwn/flipper/dist/common/include/fs/minixfs/StorageManager.h
vendored
Normal file
44
pwn/flipper/dist/common/include/fs/minixfs/StorageManager.h
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Bitmap.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class StorageManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param num_inodes the max number of inodes
|
||||||
|
* @param num_zones the max number of zones
|
||||||
|
*/
|
||||||
|
StorageManager(uint16 num_inodes, uint16 num_zones);
|
||||||
|
|
||||||
|
virtual ~StorageManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* frees the zone at the given index
|
||||||
|
* @param index the zone index
|
||||||
|
*/
|
||||||
|
virtual void freeZone(size_t index) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* frees the inode at the given index
|
||||||
|
* @param index the inode index
|
||||||
|
*/
|
||||||
|
virtual void freeInode(size_t index) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if inode is set
|
||||||
|
* @param index the inode index
|
||||||
|
* @return true if the inode is set
|
||||||
|
*/
|
||||||
|
virtual bool isInodeSet(size_t index) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Bitmap inode_bitmap_;
|
||||||
|
Bitmap zone_bitmap_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
16
pwn/flipper/dist/common/include/fs/minixfs/minix_fs_consts.h
vendored
Normal file
16
pwn/flipper/dist/common/include/fs/minixfs/minix_fs_consts.h
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define V3_OFFSET ((superblock_->s_magic_==MINIX_V3) ? 1 : 0)
|
||||||
|
#define V3_ARRAY(PTR,IDX) ((superblock_->s_magic_==MINIX_V3) ? ((uint32*)(PTR))[(IDX)] : ((uint16*)(PTR))[(IDX)])
|
||||||
|
#define SET_V3_ARRAY(PTR,IDX,VAL) do { if (superblock_->s_magic_==MINIX_V3) ((uint32*)(PTR))[(IDX)] = VAL; else ((uint16*)(PTR))[(IDX)] = VAL; } while (0)
|
||||||
|
#define NUM_ZONE_ADDRESSES ((superblock_->s_magic_==MINIX_V3) ? 256 : 512)
|
||||||
|
#define ZONE_SIZE 1024U
|
||||||
|
#define BLOCK_SIZE 1024U
|
||||||
|
#define INODE_BYTES ((superblock_->s_magic_==MINIX_V3) ? 4 : 2)
|
||||||
|
#define INODE_SIZE ((superblock_->s_magic_==MINIX_V3) ? 64 : 32)
|
||||||
|
#define INODES_PER_BLOCK ((superblock_->s_magic_==MINIX_V3) ? 16 : 32)
|
||||||
|
#define DENTRY_SIZE ((superblock_->s_magic_==MINIX_V3) ? 64 : 32)
|
||||||
|
#define MAX_NAME_LENGTH ((superblock_->s_magic_==MINIX_V3) ? 60 : 30)
|
||||||
|
#define NUM_ZONES ((superblock_->s_magic_==MINIX_V3) ? 10 : 9)
|
||||||
|
#define MINIX_V3 0x4d5a
|
||||||
|
|
61
pwn/flipper/dist/common/include/fs/ramfs/RamFSFile.h
vendored
Normal file
61
pwn/flipper/dist/common/include/fs/ramfs/RamFSFile.h
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/File.h"
|
||||||
|
|
||||||
|
|
||||||
|
class RamFSFile: public File
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RamFSFile ( Inode* inode, Dentry* dentry, uint32 flag );
|
||||||
|
|
||||||
|
virtual ~RamFSFile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the file position relative to the start of the file, the end of
|
||||||
|
* the file or the current file position.
|
||||||
|
* @param offset is the offset to set.
|
||||||
|
* @param origin is the on off SEEK_SET, SEEK_CUR and SEEK_END.
|
||||||
|
* @return the offset from the start off the file or -1 on failure.
|
||||||
|
*/
|
||||||
|
l_off_t llSeek ( l_off_t offset, uint8 origin );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads from the file
|
||||||
|
* @param buffer is the buffer where the data is written to
|
||||||
|
* @param count is the number of bytes to read.
|
||||||
|
* @param offset is the offset to read from counted from the start of the file.
|
||||||
|
* @return the number of bytes read
|
||||||
|
*/
|
||||||
|
virtual int32 read ( char *buffer, size_t count, l_off_t offset );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes to the file
|
||||||
|
* @param buffer is the buffer where the data is read from
|
||||||
|
* @param count is the number of bytes to write.
|
||||||
|
* @param offset is the offset to write from counted from the start of the file.
|
||||||
|
* @return the number of bytes written
|
||||||
|
*/
|
||||||
|
virtual int32 write ( const char *buffer, size_t count, l_off_t offset );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the file
|
||||||
|
* @param flag how to open the file
|
||||||
|
* @return the filedescriptor
|
||||||
|
*/
|
||||||
|
virtual int32 open ( uint32 flag );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the file
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes all off the file's write operations. The File will be written to disk.
|
||||||
|
* @return is the error code of the flush operation.
|
||||||
|
*/
|
||||||
|
virtual int32 flush();
|
||||||
|
};
|
||||||
|
|
40
pwn/flipper/dist/common/include/fs/ramfs/RamFSInode.h
vendored
Normal file
40
pwn/flipper/dist/common/include/fs/ramfs/RamFSInode.h
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "fs/Inode.h"
|
||||||
|
|
||||||
|
class RamFSInode : public Inode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
char* data_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param super_block the superblock to create the inode on
|
||||||
|
* @param inode_type the inode type
|
||||||
|
*/
|
||||||
|
RamFSInode ( Superblock *super_block, uint32 inode_type );
|
||||||
|
virtual ~RamFSInode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a file is opened
|
||||||
|
*/
|
||||||
|
virtual File* open(Dentry* dentry, uint32 /*flag*/);
|
||||||
|
|
||||||
|
/// read the data from the inode
|
||||||
|
/// @param offset offset byte
|
||||||
|
/// @param size the size of data that read from this inode
|
||||||
|
/// @buffer the dest char-array to store the data
|
||||||
|
/// @return On successe, return 0. On error, return -1.
|
||||||
|
virtual int32 readData ( uint32 offset, uint32 size, char *buffer );
|
||||||
|
|
||||||
|
/// write the data to the inode
|
||||||
|
/// @param offset offset byte
|
||||||
|
/// @param size the size of data that write to this inode (data_)
|
||||||
|
/// @buffer the src char-array
|
||||||
|
/// @return On successe, return 0. On error, return -1.
|
||||||
|
virtual int32 writeData ( uint32 offset, uint32 size, const char *buffer );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
53
pwn/flipper/dist/common/include/fs/ramfs/RamFSSuperblock.h
vendored
Normal file
53
pwn/flipper/dist/common/include/fs/ramfs/RamFSSuperblock.h
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/Superblock.h"
|
||||||
|
|
||||||
|
class Inode;
|
||||||
|
class Superblock;
|
||||||
|
class RamFSType;
|
||||||
|
|
||||||
|
class RamFSSuperblock : public Superblock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* constructor
|
||||||
|
* @param s_root the root dentry of the new filesystem
|
||||||
|
* @param s_dev the device number of the new filesystem
|
||||||
|
*/
|
||||||
|
RamFSSuperblock (RamFSType* type, uint32 s_dev );
|
||||||
|
virtual ~RamFSSuperblock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new Inode of the superblock, mknod with dentry, add in the list.
|
||||||
|
* @param dentry the dentry to create the new inode with
|
||||||
|
* @param type the inode type
|
||||||
|
* @return the inode
|
||||||
|
*/
|
||||||
|
virtual Inode* createInode (uint32 type );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called to read a specific inode from a mounted file-system.
|
||||||
|
* @param inode the inode to read
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
virtual int32 readInode ( Inode* inode );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called to write a specific inode to a mounted file-system,
|
||||||
|
* and gets called on inodes which have been marked dirty.
|
||||||
|
* @param inode the inode to write
|
||||||
|
*/
|
||||||
|
virtual void writeInode ( Inode* inode );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called whenever the reference count on an inode reaches 0,
|
||||||
|
* and it is found that the link count (i_nlink= is also zero. It is
|
||||||
|
* presumed that the file-system will deal with this situation be
|
||||||
|
* invalidating the inode in the file-system and freeing up any resourses
|
||||||
|
* used.
|
||||||
|
* @param inode the inode to delete
|
||||||
|
*/
|
||||||
|
virtual void deleteInode ( Inode* inode );
|
||||||
|
};
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
25
pwn/flipper/dist/common/include/fs/ramfs/RamFSType.h
vendored
Normal file
25
pwn/flipper/dist/common/include/fs/ramfs/RamFSType.h
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/FileSystemType.h"
|
||||||
|
|
||||||
|
class RamFSType : public FileSystemType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RamFSType();
|
||||||
|
virtual ~RamFSType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the superblock from the device.
|
||||||
|
* @param superblock is the superblock to fill with data.
|
||||||
|
* @param data is the data given to the mount system call.
|
||||||
|
* @return is a pointer to the resulting superblock.
|
||||||
|
*/
|
||||||
|
virtual Superblock *readSuper(Superblock *superblock, void *data) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Superblock object for the actual file system type.
|
||||||
|
* @return a pointer to the Superblock object
|
||||||
|
*/
|
||||||
|
virtual Superblock *createSuper(uint32 s_dev);
|
||||||
|
};
|
||||||
|
|
0
pwn/flipper/dist/common/include/kernel/.keep
vendored
Normal file
0
pwn/flipper/dist/common/include/kernel/.keep
vendored
Normal file
21
pwn/flipper/dist/common/include/kernel/syscall-definitions.h
vendored
Normal file
21
pwn/flipper/dist/common/include/kernel/syscall-definitions.h
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define fd_stdin 0
|
||||||
|
#define fd_stdout 1
|
||||||
|
#define fd_stderr 2
|
||||||
|
|
||||||
|
#define sc_exit 1
|
||||||
|
#define sc_fork 2
|
||||||
|
#define sc_read 3
|
||||||
|
#define sc_write 4
|
||||||
|
#define sc_open 5
|
||||||
|
#define sc_close 6
|
||||||
|
#define sc_lseek 19
|
||||||
|
#define sc_pseudols 43
|
||||||
|
#define sc_outline 105
|
||||||
|
#define sc_sched_yield 158
|
||||||
|
#define sc_createprocess 191
|
||||||
|
#define sc_trace 252
|
||||||
|
|
||||||
|
#define sc_flip_bit 69
|
||||||
|
|
24
pwn/flipper/dist/common/include/ustl/LICENSE
vendored
Normal file
24
pwn/flipper/dist/common/include/ustl/LICENSE
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
License for the USTL, forked from https://github.com/msharov/ustl
|
||||||
|
|
||||||
|
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
98
pwn/flipper/dist/common/include/ustl/cmemlink.h
vendored
Normal file
98
pwn/flipper/dist/common/include/ustl/cmemlink.h
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "assert.h"
|
||||||
|
#include "ualgobase.h"
|
||||||
|
|
||||||
|
/// The ustl namespace contains all ustl classes and algorithms.
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class istream;
|
||||||
|
class ostream;
|
||||||
|
class ostringstream;
|
||||||
|
|
||||||
|
/// \class cmemlink cmemlink.h ustl.h
|
||||||
|
/// \ingroup MemoryManagement
|
||||||
|
///
|
||||||
|
/// \brief A read-only pointer to a sized block of memory.
|
||||||
|
///
|
||||||
|
/// Use this class the way you would a const pointer to an allocated unstructured block.
|
||||||
|
/// The pointer and block size are available through member functions and cast operator.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
///
|
||||||
|
/// \code
|
||||||
|
/// void* p = malloc (46721);
|
||||||
|
/// cmemlink a, b;
|
||||||
|
/// a.link (p, 46721);
|
||||||
|
/// assert (a.size() == 46721));
|
||||||
|
/// b = a;
|
||||||
|
/// assert (b.size() == 46721));
|
||||||
|
/// assert (b.DataAt(34) == a.DataAt(34));
|
||||||
|
/// assert (0 == memcmp (a, b, 12));
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
class cmemlink {
|
||||||
|
public:
|
||||||
|
typedef char value_type;
|
||||||
|
typedef const value_type* pointer;
|
||||||
|
typedef const value_type* const_pointer;
|
||||||
|
typedef value_type reference;
|
||||||
|
typedef value_type const_reference;
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef uint32_t written_size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef const_pointer const_iterator;
|
||||||
|
typedef const_iterator iterator;
|
||||||
|
typedef const cmemlink& rcself_t;
|
||||||
|
public:
|
||||||
|
inline cmemlink (void) : _data (nullptr), _size (0) { }
|
||||||
|
inline cmemlink (const void* p, size_type n) : _data (const_pointer(p)), _size (n) { assert (p || !n); }
|
||||||
|
inline cmemlink (const cmemlink& l) : _data (l._data), _size (l._size) {}
|
||||||
|
inline virtual ~cmemlink (void) noexcept {}
|
||||||
|
void link (const void* p, size_type n);
|
||||||
|
inline void link (const cmemlink& l) { link (l.begin(), l.size()); }
|
||||||
|
inline void link (const void* first, const void* last) { link (first, distance (first, last)); }
|
||||||
|
inline void relink (const void* p, size_type n);
|
||||||
|
virtual void unlink (void) noexcept { _data = nullptr; _size = 0; }
|
||||||
|
inline rcself_t operator= (const cmemlink& l) { link (l); return *this; }
|
||||||
|
bool operator== (const cmemlink& l) const noexcept;
|
||||||
|
inline void swap (cmemlink& l) { ::ustl::swap (_data, l._data); ::ustl::swap (_size, l._size); }
|
||||||
|
inline size_type size (void) const { return _size; }
|
||||||
|
inline size_type max_size (void) const { return size(); }
|
||||||
|
inline size_type readable_size (void) const { return size(); }
|
||||||
|
inline bool empty (void) const { return !size(); }
|
||||||
|
inline const_pointer data (void) const { return _data; }
|
||||||
|
inline const_pointer cdata (void) const { return _data; }
|
||||||
|
inline iterator begin (void) const { return iterator (cdata()); }
|
||||||
|
inline iterator iat (size_type i) const { assert (i <= size()); return begin() + i; }
|
||||||
|
inline iterator end (void) const { return iat (size()); }
|
||||||
|
inline void resize (size_type n) { _size = n; }
|
||||||
|
inline void read (istream&) { assert (!"ustl::cmemlink is a read-only object."); }
|
||||||
|
void write (ostream& os) const;
|
||||||
|
size_type stream_size (void) const noexcept;
|
||||||
|
void text_write (ostringstream& os) const;
|
||||||
|
void write_file (const char* filename, int mode = 0644) const;
|
||||||
|
private:
|
||||||
|
const_pointer _data; ///< Pointer to the data block (const)
|
||||||
|
size_type _size; ///< size of the data block
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// A fast alternative to link which can be used when relinking to the same block (i.e. when it is resized)
|
||||||
|
inline void cmemlink::relink (const void* p, size_type n)
|
||||||
|
{
|
||||||
|
_data = reinterpret_cast<const_pointer>(p);
|
||||||
|
_size = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Use with cmemlink-derived classes to link to a static array
|
||||||
|
#define static_link(v) link (VectorBlock(v))
|
||||||
|
|
||||||
|
} // namespace ustl
|
261
pwn/flipper/dist/common/include/ustl/config.h
vendored
Normal file
261
pwn/flipper/dist/common/include/ustl/config.h
vendored
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// config.h - Generated from config.h.in by configure.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Define to the one symbol short name of this package.
|
||||||
|
#define USTL_NAME "ustl"
|
||||||
|
// Define to the full name and version of this package.
|
||||||
|
// More or less. Was manually merged and updated from version ustl v2.2-3-gf0abf84 with SWEB specific changes. config.h file was mostly left as it is and not updated
|
||||||
|
// Based on ustl upstream commit c19d8291a471c47c808b5ef303f163df166cd388
|
||||||
|
#define USTL_STRING "ustl v2.6-2-gc19d829"
|
||||||
|
// Define to the version of this package.
|
||||||
|
#define USTL_VERSION 0x260
|
||||||
|
// Define to the address where bug reports for this package should be sent.
|
||||||
|
#define USTL_BUGREPORT "Mike Sharov <msharov@users.sourceforge.net>"
|
||||||
|
|
||||||
|
/// Define to 1 if you want stream operations to throw exceptions on
|
||||||
|
/// insufficient data or insufficient space. All these errors should
|
||||||
|
/// be preventable in output code; the input code should verify the
|
||||||
|
/// data in a separate step. It slows down stream operations a lot,
|
||||||
|
/// but it is your decision. By default only debug builds throw.
|
||||||
|
///
|
||||||
|
#define WANT_STREAM_BOUNDS_CHECKING 0
|
||||||
|
|
||||||
|
/// Define to 1 if you want backtrace symbols demangled.
|
||||||
|
/// This adds some 15k to the library size, and requires that you link it and
|
||||||
|
/// any executables you make with the -rdynamic flag (increasing library size
|
||||||
|
/// even more). By default only the debug build does this.
|
||||||
|
#undef WANT_NAME_DEMANGLING
|
||||||
|
|
||||||
|
/// Define to 1 if you want to build without libstdc++
|
||||||
|
#define WITHOUT_LIBSTDCPP 1
|
||||||
|
|
||||||
|
/// Define GNU extensions if unavailable.
|
||||||
|
#ifndef __GNUC__
|
||||||
|
/// GCC (and some other compilers) define '__attribute__'; ustl is using this
|
||||||
|
/// macro to alert the compiler to flag inconsistencies in printf/scanf-like
|
||||||
|
/// function calls. Just in case '__attribute__' is undefined, make a dummy.
|
||||||
|
///
|
||||||
|
#ifndef __attribute__
|
||||||
|
#define __attribute__(p)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define WEAKALIAS(sym) __attribute__((weak,alias(sym)))
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define DLL_EXPORT __attribute__((visibility("default")))
|
||||||
|
#define DLL_LOCAL __attribute__((visibility("hidden")))
|
||||||
|
#define INLINE __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define DLL_EXPORT
|
||||||
|
#define DLL_LOCAL
|
||||||
|
#define INLINE
|
||||||
|
#endif
|
||||||
|
#if __cplusplus >= 201103L && (!__GNUC__ || (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
|
||||||
|
#define HAVE_CPP11 1
|
||||||
|
#if __cplusplus >= 201402
|
||||||
|
#define HAVE_CPP14 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if !HAVE_CPP11
|
||||||
|
#define constexpr
|
||||||
|
#define override
|
||||||
|
#define final
|
||||||
|
#define nullptr NULL
|
||||||
|
#define noexcept throw()
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ >= 3 && (__i386__ || __x86_64__)
|
||||||
|
/// GCC 3+ supports the prefetch directive, which some CPUs use to improve caching
|
||||||
|
#define prefetch(p,rw,loc) __builtin_prefetch(p,rw,loc)
|
||||||
|
#else
|
||||||
|
#define prefetch(p,rw,loc)
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ < 3
|
||||||
|
/// __alignof__ returns the recommended alignment for the type
|
||||||
|
#define __alignof__(v) min(sizeof(v), sizeof(void*))
|
||||||
|
/// This macro returns 1 if the value of x is known at compile time.
|
||||||
|
#ifndef __builtin_constant_p
|
||||||
|
#define __builtin_constant_p(x) 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define to empty if 'const' does not conform to ANSI C.
|
||||||
|
#undef const
|
||||||
|
// Define as '__inline' if that is what the C compiler calls it
|
||||||
|
#undef inline
|
||||||
|
// Define to 'long' if <sys/types.h> does not define.
|
||||||
|
#undef off_t
|
||||||
|
// Define to 'unsigned' if <sys/types.h> does not define.
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/// gcc has lately decided that inline is just a suggestion
|
||||||
|
/// Define to 1 if when you say 'inline' you mean it!
|
||||||
|
#undef WANT_ALWAYS_INLINE
|
||||||
|
#if WANT_ALWAYS_INLINE
|
||||||
|
#define inline INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <assert.h> header file.
|
||||||
|
#undef HAVE_ASSERT_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <ctype.h> header file.
|
||||||
|
#undef HAVE_CTYPE_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <errno.h> header file.
|
||||||
|
#undef HAVE_ERRNO_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <fcntl.h> header file.
|
||||||
|
#undef HAVE_FCNTL_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <float.h> header file.
|
||||||
|
#undef HAVE_FLOAT_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <inttypes.h> header file.
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <limits.h> header file.
|
||||||
|
#undef HAVE_LIMITS_H
|
||||||
|
|
||||||
|
/// Define to 1 if you have the <locale.h> header file.
|
||||||
|
#undef HAVE_LOCALE_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <alloca.h> header file.
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <signal.h> header file.
|
||||||
|
#undef HAVE_SIGNAL_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the __va_copy function
|
||||||
|
#define HAVE_VA_COPY 1
|
||||||
|
|
||||||
|
// Define to 1 if you have the <stdarg.h> header file.
|
||||||
|
#undef HAVE_STDARG_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <stddef.h> header file.
|
||||||
|
#undef HAVE_STDDEF_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <stdint.h> header file.
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <stdio.h> header file.
|
||||||
|
#undef HAVE_STDIO_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <stdlib.h> header file.
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <string.h> header file.
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the 'strrchr' function.
|
||||||
|
#define HAVE_STRRCHR 1
|
||||||
|
|
||||||
|
// Define to 1 if you have the 'strsignal' function.
|
||||||
|
#define HAVE_STRSIGNAL 1
|
||||||
|
|
||||||
|
// Define to 1 if you have the <sys/stat.h> header file.
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <sys/types.h> header file.
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <sys/mman.h> header file.
|
||||||
|
#undef HAVE_SYS_MMAN_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <time.h> header file.
|
||||||
|
#undef HAVE_TIME_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <unistd.h> header file.
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <math.h> header file.
|
||||||
|
#undef HAVE_MATH_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <execinfo.h> header file.
|
||||||
|
#undef HAVE_EXECINFO_H
|
||||||
|
|
||||||
|
// Define to 1 if you have the <cxxabi.h> header file.
|
||||||
|
#if __GNUC__ >= 3
|
||||||
|
#define HAVE_CXXABI_H 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define to 1 if you have the rintf function. Will use rint otherwise.
|
||||||
|
#undef HAVE_RINTF
|
||||||
|
|
||||||
|
// STDC_HEADERS is defined to 1 on sane systems.
|
||||||
|
#if HAVE_ASSERT_H && HAVE_CTYPE_H && HAVE_ERRNO_H && HAVE_FLOAT_H &&\
|
||||||
|
HAVE_LIMITS_H && HAVE_LOCALE_H && HAVE_MATH_H && HAVE_SIGNAL_H &&\
|
||||||
|
HAVE_STDARG_H && HAVE_STDDEF_H && HAVE_STDIO_H && HAVE_STDLIB_H &&\
|
||||||
|
HAVE_STRING_H && HAVE_TIME_H
|
||||||
|
#define STDC_HEADERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// STDC_HEADERS is defined to 1 on unix systems.
|
||||||
|
#if HAVE_FCNTL_H && HAVE_SYS_STAT_H && HAVE_UNISTD_H
|
||||||
|
#define STDUNIX_HEADERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define to 1 if your compiler treats char as a separate type along with
|
||||||
|
// signed char and unsigned char. This will create overloads for char.
|
||||||
|
#undef HAVE_THREE_CHAR_TYPES
|
||||||
|
|
||||||
|
// Define to 1 if you have 64 bit types available
|
||||||
|
#undef HAVE_INT64_T
|
||||||
|
|
||||||
|
// Define to 1 if you have the long long type
|
||||||
|
#undef HAVE_LONG_LONG
|
||||||
|
|
||||||
|
// Define to 1 if you want unrolled specializations for fill and copy
|
||||||
|
#define WANT_UNROLLED_COPY 1
|
||||||
|
|
||||||
|
// Define to 1 if you want to use MMX/SSE/3dNow! processor instructions
|
||||||
|
#define WANT_MMX 0
|
||||||
|
|
||||||
|
// Define to byte sizes of types
|
||||||
|
#undef SIZE_OF_CHAR
|
||||||
|
#undef SIZE_OF_SHORT
|
||||||
|
#undef SIZE_OF_INT
|
||||||
|
#undef SIZE_OF_LONG
|
||||||
|
#undef SIZE_OF_LONG_LONG
|
||||||
|
#undef SIZE_OF_POINTER
|
||||||
|
#undef SIZE_OF_SIZE_T
|
||||||
|
#undef SIZE_OF_BOOL
|
||||||
|
#undef SIZE_T_IS_LONG
|
||||||
|
|
||||||
|
// Byte order macros, converted in utypes.h
|
||||||
|
#define USTL_LITTLE_ENDIAN 4321
|
||||||
|
#define USTL_BIG_ENDIAN 1234
|
||||||
|
#define USTL_BYTE_ORDER USTL_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
#if __i386__ || __x86_64__
|
||||||
|
#define __x86__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Extended CPU capabilities
|
||||||
|
#undef CPU_HAS_FPU
|
||||||
|
#undef CPU_HAS_EXT_DEBUG
|
||||||
|
#undef CPU_HAS_TIMESTAMPC
|
||||||
|
#undef CPU_HAS_MSR
|
||||||
|
#undef CPU_HAS_CMPXCHG8
|
||||||
|
#undef CPU_HAS_APIC
|
||||||
|
#undef CPU_HAS_SYSCALL
|
||||||
|
#undef CPU_HAS_MTRR
|
||||||
|
#undef CPU_HAS_CMOV
|
||||||
|
#undef CPU_HAS_FCMOV
|
||||||
|
#if WANT_MMX
|
||||||
|
#undef CPU_HAS_MMX
|
||||||
|
#undef CPU_HAS_FXSAVE
|
||||||
|
#undef CPU_HAS_SSE
|
||||||
|
#undef CPU_HAS_SSE2
|
||||||
|
#undef CPU_HAS_SSE3
|
||||||
|
#undef CPU_HAS_EXT_3DNOW
|
||||||
|
#undef CPU_HAS_3DNOW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GCC vector extensions
|
||||||
|
#if (CPU_HAS_MMX || CPU_HAS_SSE) && __GNUC__ >= 3
|
||||||
|
#undef HAVE_VECTOR_EXTENSIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CPU_HAS_SSE && __GNUC__
|
||||||
|
#define __sse_align __attribute__((aligned(16)))
|
||||||
|
#else
|
||||||
|
#define __sse_align
|
||||||
|
#endif
|
62
pwn/flipper/dist/common/include/ustl/memblock.h
vendored
Normal file
62
pwn/flipper/dist/common/include/ustl/memblock.h
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "memlink.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \class memblock memblock.h ustl.h
|
||||||
|
/// \ingroup MemoryManagement
|
||||||
|
///
|
||||||
|
/// \brief Allocated memory block.
|
||||||
|
///
|
||||||
|
/// Adds memory management capabilities to memlink. Uses malloc and realloc to
|
||||||
|
/// maintain the internal pointer, but only if allocated using members of this class,
|
||||||
|
/// or if linked to using the Manage() member function. Managed memory is automatically
|
||||||
|
/// freed in the destructor.
|
||||||
|
///
|
||||||
|
class memblock : public memlink {
|
||||||
|
public:
|
||||||
|
memblock (void) noexcept;
|
||||||
|
memblock (const void* p, size_type n);
|
||||||
|
explicit memblock (size_type n);
|
||||||
|
explicit memblock (const cmemlink& b);
|
||||||
|
explicit memblock (const memlink& b);
|
||||||
|
memblock (const memblock& b);
|
||||||
|
virtual ~memblock (void) noexcept;
|
||||||
|
virtual void unlink (void) noexcept override;
|
||||||
|
inline void assign (const cmemlink& l) { assign (l.cdata(), l.readable_size()); }
|
||||||
|
inline const memblock& operator= (const cmemlink& l) { assign (l); return *this; }
|
||||||
|
inline const memblock& operator= (const memlink& l) { assign (l); return *this; }
|
||||||
|
inline const memblock& operator= (const memblock& l) { assign (l); return *this; }
|
||||||
|
inline void swap (memblock& l) noexcept { memlink::swap (l); ::ustl::swap (_capacity, l._capacity); }
|
||||||
|
void assign (const void* p, size_type n);
|
||||||
|
void reserve (size_type newSize, bool bExact = false);
|
||||||
|
void resize (size_type newSize, bool bExact = true);
|
||||||
|
iterator insert (const_iterator start, size_type size);
|
||||||
|
iterator erase (const_iterator start, size_type size);
|
||||||
|
inline void clear (void) noexcept { resize (0); }
|
||||||
|
inline size_type capacity (void) const { return _capacity; }
|
||||||
|
inline bool is_linked (void) const { return !capacity(); }
|
||||||
|
inline size_type max_size (void) const { return is_linked() ? memlink::max_size() : SIZE_MAX; }
|
||||||
|
inline void manage (memlink& l) { manage (l.begin(), l.size()); }
|
||||||
|
void deallocate (void) noexcept;
|
||||||
|
void shrink_to_fit (void);
|
||||||
|
void manage (void* p, size_type n) noexcept;
|
||||||
|
void copy_link (void);
|
||||||
|
void read (istream& is);
|
||||||
|
void read_file (const char* filename);
|
||||||
|
#if HAVE_CPP11
|
||||||
|
inline memblock (memblock&& b) : memlink(), _capacity(0) { swap (b); }
|
||||||
|
inline memblock& operator= (memblock&& b) { swap (b); return *this; }
|
||||||
|
#endif
|
||||||
|
protected:
|
||||||
|
virtual size_type minimumFreeCapacity (void) const noexcept __attribute__((const));
|
||||||
|
private:
|
||||||
|
size_type _capacity; ///< Number of bytes allocated by Resize.
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
98
pwn/flipper/dist/common/include/ustl/memlink.h
vendored
Normal file
98
pwn/flipper/dist/common/include/ustl/memlink.h
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "cmemlink.h"
|
||||||
|
#include "ualgo.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \class memlink memlink.h ustl.h
|
||||||
|
/// \ingroup MemoryManagement
|
||||||
|
///
|
||||||
|
/// \brief Wrapper for pointer to block with size.
|
||||||
|
///
|
||||||
|
/// Use this class the way you would a pointer to an allocated unstructured block.
|
||||||
|
/// The pointer and block size are available through member functions and cast operator.
|
||||||
|
///
|
||||||
|
/// Example usage:
|
||||||
|
/// \code
|
||||||
|
/// void* p = malloc (46721);
|
||||||
|
/// memlink a, b;
|
||||||
|
/// a.link (p, 46721);
|
||||||
|
/// assert (a.size() == 46721));
|
||||||
|
/// b = a;
|
||||||
|
/// assert (b.size() == 46721));
|
||||||
|
/// assert (b.begin() + 34 == a.begin + 34);
|
||||||
|
/// assert (0 == memcmp (a, b, 12));
|
||||||
|
/// a.fill (673, b, 42, 67);
|
||||||
|
/// b.erase (87, 12);
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
class memlink : public cmemlink {
|
||||||
|
public:
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef cmemlink::pointer const_pointer;
|
||||||
|
typedef cmemlink::const_iterator const_iterator;
|
||||||
|
typedef pointer iterator;
|
||||||
|
typedef const memlink& rcself_t;
|
||||||
|
public:
|
||||||
|
inline memlink (void) : cmemlink() {}
|
||||||
|
inline memlink (void* p, size_type n) : cmemlink (p, n) {}
|
||||||
|
inline memlink (const void* p, size_type n) : cmemlink (p, n) {}
|
||||||
|
inline memlink (rcself_t l) : cmemlink (l) {}
|
||||||
|
inline explicit memlink (const cmemlink& l) : cmemlink (l) {}
|
||||||
|
inline pointer data (void) { return const_cast<pointer>(cmemlink::data()); }
|
||||||
|
inline const_pointer data (void) const { return cmemlink::data(); }
|
||||||
|
inline iterator begin (void) { return iterator (data()); }
|
||||||
|
inline iterator iat (size_type i) { assert (i <= size()); return begin() + i; }
|
||||||
|
inline iterator end (void) { return iat (size()); }
|
||||||
|
inline const_iterator begin (void) const { return cmemlink::begin(); }
|
||||||
|
inline const_iterator end (void) const { return cmemlink::end(); }
|
||||||
|
inline const_iterator iat (size_type i) const { return cmemlink::iat (i); }
|
||||||
|
size_type writable_size (void) const { return size(); }
|
||||||
|
inline rcself_t operator= (const cmemlink& l) { cmemlink::operator= (l); return *this; }
|
||||||
|
inline rcself_t operator= (rcself_t l) { cmemlink::operator= (l); return *this; }
|
||||||
|
inline void link (const void* p, size_type n) { cmemlink::link (p, n); }
|
||||||
|
inline void link (void* p, size_type n) { cmemlink::link (p, n); }
|
||||||
|
inline void link (const cmemlink& l) { cmemlink::link (l); }
|
||||||
|
inline void link (memlink& l) { cmemlink::link (l); }
|
||||||
|
inline void link (const void* first, const void* last) { link (first, distance (first, last)); }
|
||||||
|
inline void link (void* first, void* last) { link (first, distance (first, last)); }
|
||||||
|
inline void relink (const void* p, size_type n) { cmemlink::relink (p, n); }
|
||||||
|
inline void relink (void* p, size_type n) { cmemlink::relink (p, n); }
|
||||||
|
inline void swap (memlink& l) { cmemlink::swap (l); }
|
||||||
|
void fill (const_iterator start, const void* p, size_type elsize, size_type elCount = 1) noexcept;
|
||||||
|
inline void insert (const_iterator start, size_type size);
|
||||||
|
inline void erase (const_iterator start, size_type size);
|
||||||
|
void read (istream& is);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Shifts the data in the linked block from \p start to \p start + \p n.
|
||||||
|
/// The contents of the uncovered bytes is undefined.
|
||||||
|
inline void memlink::insert (const_iterator cstart, size_type n)
|
||||||
|
{
|
||||||
|
assert (data() || !n);
|
||||||
|
assert (cmemlink::begin() || !n);
|
||||||
|
assert (cstart >= begin() && cstart + n <= end());
|
||||||
|
iterator start = const_cast<iterator>(cstart);
|
||||||
|
rotate (start, end() - n, end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shifts the data in the linked block from \p start + \p n to \p start.
|
||||||
|
/// The contents of the uncovered bytes is undefined.
|
||||||
|
inline void memlink::erase (const_iterator cstart, size_type n)
|
||||||
|
{
|
||||||
|
assert (data() || !n);
|
||||||
|
assert (cmemlink::begin() || !n);
|
||||||
|
assert (cstart >= begin() && cstart + n <= end());
|
||||||
|
iterator start = const_cast<iterator>(cstart);
|
||||||
|
rotate (start, start + n, end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use with memlink-derived classes to allocate and link to stack space.
|
||||||
|
#define alloca_link(m,n) (m).link (alloca (n), (n))
|
||||||
|
|
||||||
|
} // namespace ustl
|
89
pwn/flipper/dist/common/include/ustl/metamac.h
vendored
Normal file
89
pwn/flipper/dist/common/include/ustl/metamac.h
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
//
|
||||||
|
/// \file metamac.h
|
||||||
|
/// \brief Macros for complex metaprogramming involving pseudoiteration.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Functors and general utilities.
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Evaluates to itself
|
||||||
|
#define ITSELF(x) x
|
||||||
|
|
||||||
|
/// Concatenates \p a and \p b
|
||||||
|
#define PASTE(a,b) a##b
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Lists and other iterators
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// The maximum number of elements in REPEAT, LIST, and COMMA_LIST
|
||||||
|
#define METAMAC_MAXN 9
|
||||||
|
|
||||||
|
/// Simple list with no separators. Repeats x N times.
|
||||||
|
/// @{
|
||||||
|
#define REPEAT_1(x) x(1)
|
||||||
|
#define REPEAT_2(x) REPEAT_1(x) x(2)
|
||||||
|
#define REPEAT_3(x) REPEAT_2(x) x(3)
|
||||||
|
#define REPEAT_4(x) REPEAT_3(x) x(4)
|
||||||
|
#define REPEAT_5(x) REPEAT_4(x) x(5)
|
||||||
|
#define REPEAT_6(x) REPEAT_5(x) x(6)
|
||||||
|
#define REPEAT_7(x) REPEAT_6(x) x(7)
|
||||||
|
#define REPEAT_8(x) REPEAT_7(x) x(8)
|
||||||
|
#define REPEAT_9(x) REPEAT_8(x) x(9)
|
||||||
|
#define REPEAT(N,x) PASTE(REPEAT_,N)(x)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// Simple separated list. Repeats x N times with sep in between.
|
||||||
|
/// @{
|
||||||
|
#define LIST_1(x,sep) x(1)
|
||||||
|
#define LIST_2(x,sep) LIST_1(x,sep) sep x(2)
|
||||||
|
#define LIST_3(x,sep) LIST_2(x,sep) sep x(3)
|
||||||
|
#define LIST_4(x,sep) LIST_3(x,sep) sep x(4)
|
||||||
|
#define LIST_5(x,sep) LIST_4(x,sep) sep x(5)
|
||||||
|
#define LIST_6(x,sep) LIST_5(x,sep) sep x(6)
|
||||||
|
#define LIST_7(x,sep) LIST_6(x,sep) sep x(7)
|
||||||
|
#define LIST_8(x,sep) LIST_7(x,sep) sep x(8)
|
||||||
|
#define LIST_9(x,sep) LIST_8(x,sep) sep x(9)
|
||||||
|
#define LIST(N,x,sep) PASTE(LIST_,N)(x,sep)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// Comma separated list. A special case of LIST needed because the preprocessor can't substitute commas.
|
||||||
|
/// @{
|
||||||
|
#define COMMA_LIST_1(x) x(1)
|
||||||
|
#define COMMA_LIST_2(x) COMMA_LIST_1(x), x(2)
|
||||||
|
#define COMMA_LIST_3(x) COMMA_LIST_2(x), x(3)
|
||||||
|
#define COMMA_LIST_4(x) COMMA_LIST_3(x), x(4)
|
||||||
|
#define COMMA_LIST_5(x) COMMA_LIST_4(x), x(5)
|
||||||
|
#define COMMA_LIST_6(x) COMMA_LIST_5(x), x(6)
|
||||||
|
#define COMMA_LIST_7(x) COMMA_LIST_6(x), x(7)
|
||||||
|
#define COMMA_LIST_8(x) COMMA_LIST_7(x), x(8)
|
||||||
|
#define COMMA_LIST_9(x) COMMA_LIST_8(x), x(9)
|
||||||
|
#define COMMA_LIST(N,x) PASTE(COMMA_LIST_,N)(x)
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Macros for defining LIST arguments.
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Ignores N, producing lists of identically named arguments.
|
||||||
|
#define LARG_NONE(name,N) name
|
||||||
|
|
||||||
|
/// Appends N to name.
|
||||||
|
#define LARG_NUMBER(name,N) name##N
|
||||||
|
|
||||||
|
/// name is a reference type.
|
||||||
|
#define LARG_REF(name,N) name##N&
|
||||||
|
|
||||||
|
/// Sequential parameter passed by value with sequential types.
|
||||||
|
#define LARG_MT_PARAM_BY_VALUE(type,name,N) type##N name##N
|
||||||
|
|
||||||
|
/// Sequential parameter passed by reference with sequential types.
|
||||||
|
#define LARG_MT_PARAM_BY_REF(type,name,N) type##N& name##N
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
295
pwn/flipper/dist/common/include/ustl/mistream.h
vendored
Normal file
295
pwn/flipper/dist/common/include/ustl/mistream.h
vendored
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "memlink.h"
|
||||||
|
#include "strmsize.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
#include "uios.h"
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
#include "typeinfo.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class ostream;
|
||||||
|
class memlink;
|
||||||
|
class string;
|
||||||
|
|
||||||
|
/// \class istream mistream.h ustl.h
|
||||||
|
/// \ingroup BinaryStreams
|
||||||
|
///
|
||||||
|
/// \brief Helper class to read packed binary streams.
|
||||||
|
///
|
||||||
|
/// This class contains a set of functions to read integral types from an
|
||||||
|
/// unstructured memory block. Unpacking binary file data can be done this
|
||||||
|
/// way, for instance. aligning the data is your responsibility, and can
|
||||||
|
/// be accomplished by proper ordering of reads and by calling the align()
|
||||||
|
/// function. Unaligned access is usually slower by orders of magnitude and,
|
||||||
|
/// on some architectures, such as PowerPC, can cause your program to crash.
|
||||||
|
/// Therefore, all read functions have asserts to check alignment.
|
||||||
|
/// Overreading the end of the stream will also cause a crash (an assert in
|
||||||
|
/// debug builds). Oh, and don't be intimidated by the size of the inlines
|
||||||
|
/// here. In the assembly code the compiler will usually chop everything down
|
||||||
|
/// to five instructions each.
|
||||||
|
///
|
||||||
|
/// Alignment rules for your objects:
|
||||||
|
/// - Assume your writes start off 4-byte aligned.
|
||||||
|
/// - After completion, \ref istream::align the stream to at least 4.
|
||||||
|
/// - If data portability between 32bit and 64bit platforms is important
|
||||||
|
/// (it often is not, in config files and the like), ensure you are always
|
||||||
|
/// using fixed-size types and are aligning to a fixed grain. Avoid writing
|
||||||
|
/// 8-byte types, and if you do, manually align before doing so.
|
||||||
|
/// - Non-default alignment is allowed if you plan to frequently write this
|
||||||
|
/// object in array form and alignment would be costly. For example, an
|
||||||
|
/// array of uint16_t-sized objects may leave the stream uint16_t aligned
|
||||||
|
/// as long as you know about it and will default-align the stream after
|
||||||
|
/// writing the array (note: \ref vector will already do this for you)
|
||||||
|
///
|
||||||
|
/// Example code:
|
||||||
|
/// \code
|
||||||
|
/// memblock b;
|
||||||
|
/// b.read_file ("test.file");
|
||||||
|
/// ostream is (b);
|
||||||
|
/// is >> boolVar >> ios::talign<int>();
|
||||||
|
/// is >> intVar >> floatVar;
|
||||||
|
/// is.read (binaryData, binaryDataSize);
|
||||||
|
/// is.align();
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
class istream : public cmemlink, public ios_base {
|
||||||
|
public:
|
||||||
|
inline istream (void) : cmemlink(), _pos (0) {}
|
||||||
|
inline istream (const void* p, streamsize n) : cmemlink(p, n), _pos (0) {}
|
||||||
|
inline explicit istream (const cmemlink& source) : cmemlink (source), _pos (0) {}
|
||||||
|
explicit istream (const ostream& source) noexcept;
|
||||||
|
inline iterator end (void) const { return cmemlink::end(); }
|
||||||
|
inline void link (const void* p, streamsize n) { cmemlink::link (p, n); }
|
||||||
|
inline void link (const cmemlink& l) { cmemlink::link (l.cdata(), l.readable_size()); }
|
||||||
|
inline void link (const void* f, const void* l) { cmemlink::link (f, l); }
|
||||||
|
inline void relink (const void* p, streamsize n) { cmemlink::relink (p, n); _pos = 0; }
|
||||||
|
inline void relink (const cmemlink& l) { relink (l.cdata(), l.readable_size()); }
|
||||||
|
virtual void unlink (void) noexcept override;
|
||||||
|
virtual streamsize underflow (streamsize = 1);
|
||||||
|
inline uoff_t pos (void) const { return _pos; }
|
||||||
|
inline const_iterator ipos (void) const { return begin() + pos(); }
|
||||||
|
inline streamsize remaining (void) const { return size() - pos(); }
|
||||||
|
inline void seek (uoff_t newPos);
|
||||||
|
inline void iseek (const_iterator newPos);
|
||||||
|
inline void skip (streamsize nBytes);
|
||||||
|
inline bool aligned (streamsize grain = c_DefaultAlignment) const;
|
||||||
|
inline bool verify_remaining (const char* op, const char* type, streamsize n);
|
||||||
|
inline streamsize align_size (streamsize grain = c_DefaultAlignment) const;
|
||||||
|
inline void align (streamsize grain = c_DefaultAlignment);
|
||||||
|
inline void swap (istream& is);
|
||||||
|
inline void read (void* buffer, streamsize size);
|
||||||
|
inline void read (memlink& buf) { read (buf.begin(), buf.writable_size()); }
|
||||||
|
void read_strz (string& str);
|
||||||
|
streamsize readsome (void* s, streamsize n);
|
||||||
|
inline void read (istream&) { }
|
||||||
|
void write (ostream& os) const;
|
||||||
|
void text_write (ostringstream& os) const;
|
||||||
|
inline streamsize stream_size (void) const { return remaining(); }
|
||||||
|
template <typename T>
|
||||||
|
inline void iread (T& v);
|
||||||
|
inline void ungetc (void) { seek (pos() - 1); }
|
||||||
|
inline off_t tellg (void) const { return pos(); }
|
||||||
|
inline void seekg (off_t p, seekdir d = beg);
|
||||||
|
private:
|
||||||
|
streamoff _pos; ///< The current read position.
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T, typename Stream>
|
||||||
|
inline streamsize required_stream_size (T, const Stream&) { return 1; }
|
||||||
|
template <typename T>
|
||||||
|
inline streamsize required_stream_size (T v, const istream&) { return stream_size_of(v); }
|
||||||
|
|
||||||
|
template <typename Stream>
|
||||||
|
inline bool stream_at_eof (const Stream& stm) { return stm.eof(); }
|
||||||
|
template <>
|
||||||
|
inline bool stream_at_eof (const istream&) { return false; }
|
||||||
|
|
||||||
|
/// \class istream_iterator
|
||||||
|
/// \ingroup BinaryStreamIterators
|
||||||
|
///
|
||||||
|
/// \brief An iterator over an istream to use with uSTL algorithms.
|
||||||
|
///
|
||||||
|
template <typename T, typename Stream = istream>
|
||||||
|
class istream_iterator {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef const value_type* pointer;
|
||||||
|
typedef const value_type& reference;
|
||||||
|
typedef typename Stream::size_type size_type;
|
||||||
|
typedef input_iterator_tag iterator_category;
|
||||||
|
public:
|
||||||
|
istream_iterator (void) : _pis (nullptr), _v() {}
|
||||||
|
explicit istream_iterator (Stream& is) : _pis (&is), _v() { Read(); }
|
||||||
|
istream_iterator (const istream_iterator& i) : _pis (i._pis), _v (i._v) {}
|
||||||
|
/// Reads and returns the next value.
|
||||||
|
inline const T& operator* (void) { return _v; }
|
||||||
|
inline istream_iterator& operator++ (void) { Read(); return *this; }
|
||||||
|
inline istream_iterator& operator-- (void) { _pis->seek (_pis->pos() - 2 * stream_size_of(_v)); return operator++(); }
|
||||||
|
inline istream_iterator operator++ (int) { istream_iterator old (*this); operator++(); return old; }
|
||||||
|
inline istream_iterator operator-- (int) { istream_iterator old (*this); operator--(); return old; }
|
||||||
|
inline istream_iterator& operator+= (streamsize n) { while (n--) operator++(); return *this; }
|
||||||
|
inline istream_iterator& operator-= (streamsize n) { _pis->seek (_pis->pos() - (n + 1) * stream_size_of(_v)); return operator++(); }
|
||||||
|
inline istream_iterator operator- (streamoff n) const { istream_iterator result (*this); return result -= n; }
|
||||||
|
inline difference_type operator- (const istream_iterator& i) const { return distance (i._pis->pos(), _pis->pos()) / stream_size_of(_v); }
|
||||||
|
inline bool operator== (const istream_iterator& i) const { return (!_pis && !i._pis) || (_pis && i._pis && _pis->pos() == i._pis->pos()); }
|
||||||
|
inline bool operator< (const istream_iterator& i) const { return !i._pis || (_pis && _pis->pos() < i._pis->pos()); }
|
||||||
|
private:
|
||||||
|
void Read (void)
|
||||||
|
{
|
||||||
|
if (!_pis)
|
||||||
|
return;
|
||||||
|
const streamsize rs (required_stream_size (_v, *_pis));
|
||||||
|
if (_pis->remaining() < rs && _pis->underflow (rs) < rs) {
|
||||||
|
_pis = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*_pis >> _v;
|
||||||
|
if (stream_at_eof (*_pis))
|
||||||
|
_pis = nullptr;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Stream* _pis; ///< The host stream.
|
||||||
|
T _v; ///< Last read value; cached to be returnable as a const reference.
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Checks that \p n bytes are available in the stream, or else throws.
|
||||||
|
inline bool istream::verify_remaining (const char* op, const char* type, streamsize n)
|
||||||
|
{
|
||||||
|
const streamsize rem = remaining();
|
||||||
|
bool enough = n <= rem;
|
||||||
|
if (!enough) overrun (op, type, n, pos(), rem);
|
||||||
|
return enough;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current read position to \p newPos
|
||||||
|
inline void istream::seek (uoff_t newPos)
|
||||||
|
{
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
if (newPos > size())
|
||||||
|
return overrun ("seekg", "byte", newPos, pos(), size());
|
||||||
|
#else
|
||||||
|
assert (newPos <= size());
|
||||||
|
#endif
|
||||||
|
_pos = newPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current read position to \p newPos
|
||||||
|
inline void istream::iseek (const_iterator newPos)
|
||||||
|
{
|
||||||
|
seek (distance (begin(), newPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current write position to \p p based on \p d.
|
||||||
|
inline void istream::seekg (off_t p, seekdir d)
|
||||||
|
{
|
||||||
|
switch (d) {
|
||||||
|
case beg: seek (p); break;
|
||||||
|
case cur: seek (pos() + p); break;
|
||||||
|
case ios_base::end: seek (size() - p); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Skips \p nBytes without reading them.
|
||||||
|
inline void istream::skip (streamsize nBytes)
|
||||||
|
{
|
||||||
|
seek (pos() + nBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of bytes to skip to be aligned on \p grain.
|
||||||
|
inline streamsize istream::align_size (streamsize grain) const
|
||||||
|
{
|
||||||
|
return Align (pos(), grain) - pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns \c true if the read position is aligned on \p grain
|
||||||
|
inline bool istream::aligned (streamsize grain) const
|
||||||
|
{
|
||||||
|
return pos() % grain == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// aligns the read position on \p grain
|
||||||
|
inline void istream::align (streamsize grain)
|
||||||
|
{
|
||||||
|
seek (Align (pos(), grain));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads type T from the stream via a direct pointer cast.
|
||||||
|
template <typename T>
|
||||||
|
inline void istream::iread (T& v)
|
||||||
|
{
|
||||||
|
assert (aligned (stream_align_of (v)));
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
if (!verify_remaining ("read", typeid(v).name(), sizeof(T)))
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
assert (remaining() >= sizeof(T));
|
||||||
|
#endif
|
||||||
|
v = *reinterpret_cast<const T*>(ipos());
|
||||||
|
_pos += sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Swaps contents with \p is
|
||||||
|
inline void istream::swap (istream& is)
|
||||||
|
{
|
||||||
|
cmemlink::swap (is);
|
||||||
|
::ustl::swap (_pos, is._pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads \p n bytes into \p buffer.
|
||||||
|
inline void istream::read (void* buffer, size_type n)
|
||||||
|
{
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
if (!verify_remaining ("read", "binary data", n))
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
assert (remaining() >= n && "Reading past end of buffer. Make sure you are reading the right format.");
|
||||||
|
#endif
|
||||||
|
memcpy (reinterpret_cast<value_type*>(buffer), ipos(), n);
|
||||||
|
_pos += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T> struct object_reader {
|
||||||
|
inline void operator()(istream& is, T& v) const { v.read (is); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_object_reader {
|
||||||
|
inline void operator()(istream& is, T& v) const { is.iread (v); }
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
inline istream& operator>> (istream& is, T& v) {
|
||||||
|
typedef typename tm::Select <numeric_limits<T>::is_integral,
|
||||||
|
integral_object_reader<T>, object_reader<T> >::Result object_reader_t;
|
||||||
|
object_reader_t()(is, v);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
inline istream& operator>> (istream& is, const T& v) { v.read (is); return is; }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef istream_iterator<utf8subchar_t> istream_iterator_for_utf8;
|
||||||
|
typedef utf8in_iterator<istream_iterator_for_utf8> utf8istream_iterator;
|
||||||
|
|
||||||
|
/// Returns a UTF-8 adaptor reading from \p is.
|
||||||
|
inline utf8istream_iterator utf8in (istream& is)
|
||||||
|
{
|
||||||
|
istream_iterator_for_utf8 si (is);
|
||||||
|
return utf8istream_iterator (si);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace ustl
|
266
pwn/flipper/dist/common/include/ustl/mostream.h
vendored
Normal file
266
pwn/flipper/dist/common/include/ustl/mostream.h
vendored
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "memlink.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
#include "uios.h"
|
||||||
|
#include "strmsize.h"
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
#include "typeinfo.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class istream;
|
||||||
|
class string;
|
||||||
|
|
||||||
|
/// \class ostream mostream.h ustl.h
|
||||||
|
/// \ingroup BinaryStreams
|
||||||
|
///
|
||||||
|
/// \brief Helper class to write packed binary streams.
|
||||||
|
///
|
||||||
|
/// This class contains a set of functions to write integral types into an
|
||||||
|
/// unstructured memory block. Packing binary file data can be done this
|
||||||
|
/// way, for instance. aligning the data is your responsibility, and can
|
||||||
|
/// be accomplished by proper ordering of writes and by calling align.
|
||||||
|
/// Unaligned access is usually slower by orders of magnitude and,
|
||||||
|
/// on some architectures, such as PowerPC, can cause your program to crash.
|
||||||
|
/// Therefore, all write functions have asserts to check alignment.
|
||||||
|
/// See \ref istream documentation for rules on designing your data format.
|
||||||
|
/// Overwriting the end of the stream will also cause a crash (an assert in
|
||||||
|
/// debug builds). Oh, and don't be intimidated by the size of the inlines
|
||||||
|
/// here. In the assembly code the compiler will usually chop everything down
|
||||||
|
/// to five instructions each.
|
||||||
|
///
|
||||||
|
/// Example code:
|
||||||
|
/// \code
|
||||||
|
/// memblock b;
|
||||||
|
/// ostream os (b);
|
||||||
|
/// os << boolVar << ios::talign<int>();
|
||||||
|
/// os << intVar << floatVar;
|
||||||
|
/// os.write (binaryData, binaryDataSize);
|
||||||
|
/// os.align();
|
||||||
|
/// b.resize (os.pos());
|
||||||
|
/// b.write_file ("test.file");
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
class ostream : public memlink, public ios_base {
|
||||||
|
public:
|
||||||
|
inline ostream (void) : memlink(), _pos(0) {}
|
||||||
|
inline ostream (void* p, streamsize n) : memlink (p, n), _pos (0) {}
|
||||||
|
inline explicit ostream (const memlink& source) : memlink (source), _pos (0) {}
|
||||||
|
inline iterator end (void) { return memlink::end(); }
|
||||||
|
inline const_iterator end (void) const { return memlink::end(); }
|
||||||
|
inline void seek (uoff_t newPos);
|
||||||
|
inline void iseek (const_iterator newPos);
|
||||||
|
inline void skip (streamsize nBytes);
|
||||||
|
inline uoff_t pos (void) const { return _pos; }
|
||||||
|
inline iterator ipos (void) { return begin() + pos(); }
|
||||||
|
inline const_iterator ipos (void) const { return begin() + pos(); }
|
||||||
|
inline streamsize remaining (void) const;
|
||||||
|
inline bool aligned (streamsize grain = c_DefaultAlignment) const;
|
||||||
|
bool verify_remaining (const char* op, const char* type, size_t n);
|
||||||
|
inline streamsize align_size (streamsize grain = c_DefaultAlignment) const;
|
||||||
|
void align (streamsize grain = c_DefaultAlignment);
|
||||||
|
inline void write (const void* buffer, streamsize size);
|
||||||
|
inline void write (const cmemlink& buf);
|
||||||
|
void write_strz (const char* str);
|
||||||
|
void read (istream& is);
|
||||||
|
inline void write (ostream& os) const { os.write (begin(), pos()); }
|
||||||
|
void text_write (ostringstream& os) const;
|
||||||
|
inline size_t stream_size (void) const { return pos(); }
|
||||||
|
void insert (iterator start, streamsize size);
|
||||||
|
void erase (iterator start, streamsize size);
|
||||||
|
inline void swap (ostream& os);
|
||||||
|
template <typename T>
|
||||||
|
inline void iwrite (const T& v);
|
||||||
|
inline virtual ostream& flush (void) { return *this; }
|
||||||
|
inline virtual streamsize overflow (streamsize=1) { return remaining(); }
|
||||||
|
virtual void unlink (void) noexcept override;
|
||||||
|
inline void link (void* p, streamsize n) { memlink::link (p, n); }
|
||||||
|
inline void link (memlink& l) { memlink::link (l.data(), l.writable_size()); }
|
||||||
|
inline void link (void* f, void* l) { memlink::link (f, l); }
|
||||||
|
inline void relink (void* p, streamsize n) { memlink::relink (p, n); _pos = 0; }
|
||||||
|
inline void relink (memlink& l) { relink (l.data(), l.writable_size()); }
|
||||||
|
inline void seekp (off_t p, seekdir d = beg);
|
||||||
|
inline off_t tellp (void) const { return pos(); }
|
||||||
|
protected:
|
||||||
|
inline void SetPos (uoff_t newPos) { _pos = newPos; }
|
||||||
|
private:
|
||||||
|
streamoff _pos; ///< Current write position.
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class ostream_iterator mostream.h ustl.h
|
||||||
|
/// \ingroup BinaryStreamIterators
|
||||||
|
///
|
||||||
|
/// \brief An iterator over an ostream to use with uSTL algorithms.
|
||||||
|
///
|
||||||
|
template <typename T, typename Stream = ostream>
|
||||||
|
class ostream_iterator {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef typename Stream::size_type size_type;
|
||||||
|
typedef output_iterator_tag iterator_category;
|
||||||
|
public:
|
||||||
|
inline explicit ostream_iterator (Stream& os)
|
||||||
|
: _os (os) {}
|
||||||
|
inline ostream_iterator (const ostream_iterator& iter)
|
||||||
|
: _os (iter._os) {}
|
||||||
|
/// Writes \p v into the stream.
|
||||||
|
inline ostream_iterator& operator= (const T& v)
|
||||||
|
{ _os << v; return *this; }
|
||||||
|
inline ostream_iterator& operator* (void) { return *this; }
|
||||||
|
inline ostream_iterator& operator++ (void) { return *this; }
|
||||||
|
inline ostream_iterator operator++ (int) { return *this; }
|
||||||
|
inline ostream_iterator& operator+= (streamsize n) { _os.skip (n); return *this; }
|
||||||
|
inline bool operator== (const ostream_iterator& i) const
|
||||||
|
{ return _os.pos() == i._os.pos(); }
|
||||||
|
inline bool operator< (const ostream_iterator& i) const
|
||||||
|
{ return _os.pos() < i._os.pos(); }
|
||||||
|
private:
|
||||||
|
Stream& _os;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef ostream_iterator<utf8subchar_t> ostream_iterator_for_utf8;
|
||||||
|
typedef utf8out_iterator<ostream_iterator_for_utf8> utf8ostream_iterator;
|
||||||
|
|
||||||
|
/// Returns a UTF-8 adaptor writing to \p os.
|
||||||
|
inline utf8ostream_iterator utf8out (ostream& os)
|
||||||
|
{
|
||||||
|
ostream_iterator_for_utf8 si (os);
|
||||||
|
return utf8ostream_iterator (si);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Checks that \p n bytes are available in the stream, or else throws.
|
||||||
|
inline bool ostream::verify_remaining (const char* op, const char* type, size_t n)
|
||||||
|
{
|
||||||
|
const size_t rem = remaining();
|
||||||
|
bool enough = n <= rem;
|
||||||
|
if (!enough) overrun (op, type, n, pos(), rem);
|
||||||
|
return enough;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Move the write pointer to \p newPos
|
||||||
|
inline void ostream::seek (uoff_t newPos)
|
||||||
|
{
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
if (newPos > size())
|
||||||
|
return overrun ("seekp", "byte", newPos, pos(), size());
|
||||||
|
#else
|
||||||
|
assert (newPos <= size());
|
||||||
|
#endif
|
||||||
|
SetPos (newPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current write position to \p newPos
|
||||||
|
inline void ostream::iseek (const_iterator newPos)
|
||||||
|
{
|
||||||
|
seek (distance (begin(), const_cast<iterator>(newPos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current write position to \p p based on \p d.
|
||||||
|
inline void ostream::seekp (off_t p, seekdir d)
|
||||||
|
{
|
||||||
|
switch (d) {
|
||||||
|
case beg: seek (p); break;
|
||||||
|
case cur: seek (pos() + p); break;
|
||||||
|
case ios_base::end: seek (size() - p); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Skips \p nBytes without writing anything.
|
||||||
|
inline void ostream::skip (streamsize nBytes)
|
||||||
|
{
|
||||||
|
seek (pos() + nBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns number of bytes remaining in the write buffer.
|
||||||
|
inline streamsize ostream::remaining (void) const
|
||||||
|
{
|
||||||
|
return size() - pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns \c true if the write pointer is aligned on \p grain
|
||||||
|
inline bool ostream::aligned (streamsize grain) const
|
||||||
|
{
|
||||||
|
return pos() % grain == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of bytes to skip to be aligned on \p grain.
|
||||||
|
inline streamsize ostream::align_size (streamsize grain) const
|
||||||
|
{
|
||||||
|
return Align (pos(), grain) - pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes \p n bytes from \p buffer.
|
||||||
|
inline void ostream::write (const void* buffer, size_type n)
|
||||||
|
{
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
if (!verify_remaining ("write", "binary data", n))
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
assert (remaining() >= n && "Buffer overrun. Check your stream size calculations.");
|
||||||
|
#endif
|
||||||
|
memcpy (ipos(), const_iterator(buffer), n);
|
||||||
|
_pos += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the contents of \p buf into the stream as a raw dump.
|
||||||
|
inline void ostream::write (const cmemlink& buf)
|
||||||
|
{
|
||||||
|
write (buf.begin(), buf.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes type T into the stream via a direct pointer cast.
|
||||||
|
template <typename T>
|
||||||
|
inline void ostream::iwrite (const T& v)
|
||||||
|
{
|
||||||
|
assert (aligned (stream_align_of (v)));
|
||||||
|
#if WANT_STREAM_BOUNDS_CHECKING
|
||||||
|
if (!verify_remaining ("write", typeid(v).name(), sizeof(T)))
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
assert (remaining() >= sizeof(T));
|
||||||
|
#endif
|
||||||
|
*reinterpret_cast<T*>(ipos()) = v;
|
||||||
|
SetPos (pos() + sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Swaps with \p os
|
||||||
|
inline void ostream::swap (ostream& os)
|
||||||
|
{
|
||||||
|
memlink::swap (os);
|
||||||
|
::ustl::swap (_pos, os._pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T> struct object_writer {
|
||||||
|
inline void operator()(ostream& os, const T& v) const { v.write (os); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_object_writer {
|
||||||
|
inline void operator()(ostream& os, const T& v) const { os.iwrite (v); }
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
inline ostream& operator<< (ostream& os, const T& v) {
|
||||||
|
typedef typename tm::Select <numeric_limits<T>::is_integral,
|
||||||
|
integral_object_writer<T>, object_writer<T> >::Result object_writer_t;
|
||||||
|
object_writer_t()(os, v);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace ustl
|
135
pwn/flipper/dist/common/include/ustl/outerrstream.h
vendored
Normal file
135
pwn/flipper/dist/common/include/ustl/outerrstream.h
vendored
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sostream.h"
|
||||||
|
#include "kprintf.h"
|
||||||
|
#include "uios.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
|
||||||
|
/// \class coutclass sostream.h ustl.h
|
||||||
|
/// \ingroup TextStreams
|
||||||
|
///
|
||||||
|
/// \brief This stream writes textual data into a memory block.
|
||||||
|
///
|
||||||
|
class coutclass : public ostream {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
coutclass();
|
||||||
|
coutclass(void* p, size_t n);
|
||||||
|
coutclass(void(*m_kprintf)(const char*, ...));
|
||||||
|
coutclass(void* p, size_t n, void(*m_kprintf)(const char*, ...));
|
||||||
|
void iwrite (uint8_t v);
|
||||||
|
void iwrite (wchar_t v);
|
||||||
|
inline void iwrite (int v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned int v) { iformat (v); }
|
||||||
|
inline void iwrite (long int v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned long int v) { iformat (v); }
|
||||||
|
void iwrite (bool v);
|
||||||
|
inline void iwrite (const char* s) { write (s, strlen(s)); }
|
||||||
|
inline void iwrite (const string& v) { write (v.begin(), v.size()); }
|
||||||
|
inline void iwrite (fmtflags f);
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
inline void iwrite (long long v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned long long v) { iformat (v); }
|
||||||
|
#endif
|
||||||
|
inline size_type max_size (void) const { return 0; }
|
||||||
|
inline coutclass& put (char c) { iwrite (uint8_t(c)); return (*this); }
|
||||||
|
int format (const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||||
|
inline void set_base (uint16_t b) { m_Base = b; }
|
||||||
|
inline void set_width (uint16_t w) { m_Width = w; }
|
||||||
|
inline void set_decimal_separator (char) { }
|
||||||
|
inline void set_thousand_separator (char) { }
|
||||||
|
inline void set_precision (uint16_t v) { m_Precision = v; }
|
||||||
|
void link (void* p, size_type n);
|
||||||
|
inline void link (memlink& l) { link (l.data(), l.writable_size()); }
|
||||||
|
void str (const string& s);
|
||||||
|
coutclass& write (const void* buffer, size_type size);
|
||||||
|
inline coutclass& write (const cmemlink& buf) { return (write (buf.begin(), buf.size())); }
|
||||||
|
inline coutclass& seekp (off_t p __attribute__((unused)), __attribute__((unused)) seekdir d =beg) { return (*this); }
|
||||||
|
coutclass& flush (void) { return (*this); }
|
||||||
|
virtual size_type overflow (size_type n = 1);
|
||||||
|
protected:
|
||||||
|
inline void reserve (__attribute__((unused)) size_type n) { }
|
||||||
|
inline size_type capacity (void) const { return 0; }
|
||||||
|
private:
|
||||||
|
inline void write_strz (const char*) { assert (!"Writing nul characters into a text stream is not allowed"); }
|
||||||
|
inline char* encode_dec (char* fmt, uint32_t n) const;
|
||||||
|
void fmtstring (char* fmt, const char* typestr, bool bInteger) const;
|
||||||
|
template <typename T>
|
||||||
|
void iformat (T v);
|
||||||
|
private:
|
||||||
|
uint32_t m_Flags; ///< See ios_base::fmtflags.
|
||||||
|
uint16_t m_Width; ///< Field width.
|
||||||
|
uint8_t m_Base; ///< Numeric base for writing numbers.
|
||||||
|
uint8_t m_Precision; ///< Number of digits after the decimal separator.
|
||||||
|
void (*m_kprintf)(const char*, ...);
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void coutclass::iformat (T v)
|
||||||
|
{
|
||||||
|
char fmt [16];
|
||||||
|
fmtstring (fmt, printf_typestring(v), numeric_limits<T>::is_integer);
|
||||||
|
kprintf(fmt, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the flag \p f in the stream.
|
||||||
|
inline void coutclass::iwrite (fmtflags f)
|
||||||
|
{
|
||||||
|
switch (f.f) {
|
||||||
|
case oct: set_base (8); break;
|
||||||
|
case dec: set_base (10); break;
|
||||||
|
case hex: set_base (16); break;
|
||||||
|
case left: m_Flags |= left; m_Flags &= ~right; break;
|
||||||
|
case right: m_Flags |= right; m_Flags &= ~left; break;
|
||||||
|
default: m_Flags |= f.f; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T> struct object_text_writer_cout {
|
||||||
|
inline void operator()(coutclass& os, const T& v) const { v.text_write (os); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_text_object_writer_cout {
|
||||||
|
inline void operator()(coutclass& os, const T& v) const { os.iwrite (v); }
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
inline coutclass& operator<< (coutclass& os, const T& v) {
|
||||||
|
typedef typename tm::Select <numeric_limits<T>::is_integral,
|
||||||
|
integral_text_object_writer_cout<T>, object_text_writer_cout<T> >::Result object_writer_t;
|
||||||
|
object_writer_t()(os, v);
|
||||||
|
return (os);
|
||||||
|
}
|
||||||
|
// Needed because if called with a char[], numeric_limits will not work. Should be removed if I find out how to partial specialize for arrays...
|
||||||
|
inline coutclass& operator<< (coutclass& os, const char* v)
|
||||||
|
{ os.iwrite (v); return (os); }
|
||||||
|
inline coutclass& operator<< (coutclass& os, char* v)
|
||||||
|
{ os.iwrite (v); return (os); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <> struct object_text_writer_cout<string> {
|
||||||
|
inline void operator()(coutclass& os, const string& v) const { os.iwrite (v); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_text_object_writer_cout<T*> {
|
||||||
|
inline void operator() (coutclass& os, const T* const& v) const
|
||||||
|
{ os.iwrite ((uintptr_t)(v)); }
|
||||||
|
};
|
||||||
|
#define COUTCLASS_CAST_OPERATOR(RealT, CastT) \
|
||||||
|
template <> inline coutclass& operator<< (coutclass& os, const RealT& v) \
|
||||||
|
{ os.iwrite ((CastT)(v)); return (os); }
|
||||||
|
COUTCLASS_CAST_OPERATOR (uint8_t* const, const char*)
|
||||||
|
COUTCLASS_CAST_OPERATOR (int8_t, uint8_t)
|
||||||
|
COUTCLASS_CAST_OPERATOR (short int, int)
|
||||||
|
COUTCLASS_CAST_OPERATOR (unsigned short, unsigned int)
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
COUTCLASS_CAST_OPERATOR (char, uint8_t)
|
||||||
|
#endif
|
||||||
|
#undef COUTCLASS_CAST_OPERATOR
|
||||||
|
|
||||||
|
};
|
||||||
|
|
132
pwn/flipper/dist/common/include/ustl/sistream.h
vendored
Normal file
132
pwn/flipper/dist/common/include/ustl/sistream.h
vendored
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "mistream.h"
|
||||||
|
#include "ustring.h"
|
||||||
|
#ifndef EOF
|
||||||
|
#define EOF (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \class istringstream sistream.h ustl.h
|
||||||
|
/// \ingroup TextStreams
|
||||||
|
///
|
||||||
|
/// \brief A stream that reads textual data from a memory block.
|
||||||
|
///
|
||||||
|
class istringstream : public istream {
|
||||||
|
public:
|
||||||
|
static const size_type c_MaxDelimiters = 16; ///< Maximum number of word delimiters.
|
||||||
|
public:
|
||||||
|
istringstream (void) noexcept;
|
||||||
|
istringstream (const void* p, size_type n) noexcept;
|
||||||
|
explicit istringstream (const cmemlink& source) noexcept;
|
||||||
|
inline fmtflags flags (void) const { return _flags; }
|
||||||
|
inline fmtflags flags (fmtflags f) { fmtflags of (_flags); _flags.f = f.f; return of; }
|
||||||
|
inline fmtflags setf (fmtflags f) { fmtflags of (_flags); _flags.f |= f.f; return of; }
|
||||||
|
inline fmtflags unsetf (fmtflags f) { fmtflags of (_flags); _flags.f &= ~f.f; return of; }
|
||||||
|
inline fmtflags setf (fmtflags f, fmtflags m) { unsetf(m); return setf(f); }
|
||||||
|
inline void iread (char& v) { v = skip_delimiters(); }
|
||||||
|
inline void iread (unsigned char& v) { char c; iread(c); v = c; }
|
||||||
|
void iread (int& v);
|
||||||
|
inline void iread (unsigned int& v) { int c; iread(c); v = c; }
|
||||||
|
inline void iread (short& v) { int c; iread(c); v = c; }
|
||||||
|
inline void iread (unsigned short& v) { int c; iread(c); v = c; }
|
||||||
|
void iread (long& v);
|
||||||
|
inline void iread (unsigned long& v) { long c; iread(c); v = c; }
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
void iread (signed char& v) { char c; iread(c); v = c; }
|
||||||
|
#endif
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
void iread (long long& v);
|
||||||
|
inline void iread (unsigned long long& v) { long long c; iread(c); v = c; }
|
||||||
|
#endif
|
||||||
|
/*inline void iread (float& v) { double c; iread(c); v = c; }
|
||||||
|
inline void iread (long double& v) { double c; iread(c); v = c; }*/
|
||||||
|
inline void iread (fmtflags_bits f);
|
||||||
|
/*void iread (double& v);
|
||||||
|
inline void iread (float& v) { double c; iread(c); v = c; }
|
||||||
|
inline void iread (long double& v) { double c; iread(c); v = c; }*/
|
||||||
|
void iread (bool& v);
|
||||||
|
void iread (wchar_t& v);
|
||||||
|
void iread (string& v);
|
||||||
|
inline string str (void) const { string s; s.link (*this); return s; }
|
||||||
|
inline istringstream& str (const string& s) { link (s); return *this; }
|
||||||
|
inline istringstream& get (char& c) { return read (&c, sizeof(c)); }
|
||||||
|
inline int get (void) { char c = EOF; get(c); return c; }
|
||||||
|
istringstream& get (char* p, size_type n, char delim = '\n');
|
||||||
|
istringstream& get (string& s, char delim = '\n');
|
||||||
|
istringstream& getline (char* p, size_type n, char delim = '\n');
|
||||||
|
istringstream& getline (string& s, char delim = '\n');
|
||||||
|
istringstream& ignore (size_type n, char delim = '\0');
|
||||||
|
inline char peek (void) { char v = get(); ungetc(); return v; }
|
||||||
|
inline istringstream& unget (void) { ungetc(); return *this; }
|
||||||
|
inline void set_delimiters (const char* delimiters);
|
||||||
|
istringstream& read (void* buffer, size_type size);
|
||||||
|
inline istringstream& read (memlink& buf) { return read (buf.begin(), buf.size()); }
|
||||||
|
inline size_type gcount (void) const { return _gcount; }
|
||||||
|
inline istringstream& seekg (off_t p, seekdir d =beg) { istream::seekg(p,d); return *this; }
|
||||||
|
inline int sync (void) { skip (remaining()); return 0; }
|
||||||
|
protected:
|
||||||
|
char skip_delimiters (void);
|
||||||
|
private:
|
||||||
|
inline void read_strz (string&) { assert (!"Reading nul characters is not allowed from text streams"); }
|
||||||
|
inline bool is_delimiter (char c) const noexcept;
|
||||||
|
template <typename T> void read_number (T& v);
|
||||||
|
private:
|
||||||
|
fmtflags _flags;
|
||||||
|
uint32_t _gcount;
|
||||||
|
char _delimiters [c_MaxDelimiters];
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void istringstream::iread (fmtflags_bits f)
|
||||||
|
{
|
||||||
|
if (f & basefield) setf (f, basefield);
|
||||||
|
else if (f & floatfield) setf (f, floatfield);
|
||||||
|
else if (f & adjustfield) setf (f, adjustfield);
|
||||||
|
setf (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets delimiters to the contents of \p delimiters.
|
||||||
|
void istringstream::set_delimiters (const char* delimiters)
|
||||||
|
{
|
||||||
|
#if __x86__ && __SSE__ && HAVE_VECTOR_EXTENSIONS
|
||||||
|
typedef uint32_t v16ud_t __attribute__((vector_size(16)));
|
||||||
|
asm("xorps\t%%xmm0, %%xmm0\n\tmovups\t%%xmm0, %0":"=m"(*noalias_cast<v16ud_t*>(_delimiters))::"xmm0");
|
||||||
|
#else
|
||||||
|
memset (_delimiters, 0, sizeof(_delimiters));
|
||||||
|
#endif
|
||||||
|
memcpy (_delimiters, delimiters, min (strlen(delimiters),sizeof(_delimiters)-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads a line of text from \p is into \p s
|
||||||
|
inline istringstream& getline (istringstream& is, string& s, char delim = '\n')
|
||||||
|
{ return is.getline (s, delim); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T> struct object_text_reader {
|
||||||
|
inline void operator()(istringstream& is, T& v) const { v.text_read (is); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_text_object_reader {
|
||||||
|
inline void operator()(istringstream& is, T& v) const { is.iread (v); }
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
inline istringstream& operator>> (istringstream& is, T& v) {
|
||||||
|
typedef typename tm::Select <numeric_limits<T>::is_integral,
|
||||||
|
integral_text_object_reader<T>, object_text_reader<T> >::Result object_reader_t;
|
||||||
|
object_reader_t()(is, v);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <> struct object_text_reader<string> {
|
||||||
|
inline void operator()(istringstream& is, string& v) const { is.iread (v); }
|
||||||
|
};
|
||||||
|
} // namespace ustl
|
213
pwn/flipper/dist/common/include/ustl/sostream.h
vendored
Normal file
213
pwn/flipper/dist/common/include/ustl/sostream.h
vendored
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ustring.h"
|
||||||
|
#include "mostream.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class string;
|
||||||
|
|
||||||
|
/// \class ostringstream sostream.h ustl.h
|
||||||
|
/// \ingroup TextStreams
|
||||||
|
///
|
||||||
|
/// \brief This stream writes textual data into a memory block.
|
||||||
|
///
|
||||||
|
class ostringstream : public ostream {
|
||||||
|
public:
|
||||||
|
ostringstream (const string& v = "");
|
||||||
|
ostringstream (void* p, size_t n) noexcept;
|
||||||
|
inline fmtflags flags (void) const { return _flags; }
|
||||||
|
inline fmtflags flags (fmtflags f) { fmtflags of (_flags); _flags.f = f.f; return of; }
|
||||||
|
inline fmtflags setf (fmtflags f) { fmtflags of (_flags); _flags.f |= f.f; return of; }
|
||||||
|
inline fmtflags unsetf (fmtflags f) { fmtflags of (_flags); _flags.f &= ~f.f; return of; }
|
||||||
|
inline fmtflags setf (fmtflags f, fmtflags m) { unsetf(m); return setf(f); }
|
||||||
|
void iwrite (unsigned char v);
|
||||||
|
void iwrite (wchar_t v);
|
||||||
|
inline void iwrite (char v) { iwrite (static_cast<unsigned char>(v)); }
|
||||||
|
inline void iwrite (short v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned short v) { iformat (v); }
|
||||||
|
inline void iwrite (int v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned int v) { iformat (v); }
|
||||||
|
inline void iwrite (long int v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned long int v) { iformat (v); }
|
||||||
|
/*inline void iwrite (float v) { iformat (v); }
|
||||||
|
inline void iwrite (double v) { iformat (v); }
|
||||||
|
inline void iwrite (long double v) { iformat (v); }*/
|
||||||
|
void iwrite (bool v);
|
||||||
|
inline void iwrite (const char* s) { write (s, strlen(s)); }
|
||||||
|
inline void iwrite (const unsigned char* s) { iwrite (reinterpret_cast<const char*>(s)); }
|
||||||
|
inline void iwrite (const string& v) { write (v.begin(), v.size()); }
|
||||||
|
inline void iwrite (fmtflags_bits f);
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
inline void iwrite (signed char v) { iwrite (static_cast<char>(v)); }
|
||||||
|
#endif
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
inline void iwrite (long long v) { iformat (v); }
|
||||||
|
inline void iwrite (unsigned long long v) { iformat (v); }
|
||||||
|
#endif
|
||||||
|
inline size_type max_size (void) const { return _buffer.max_size(); }
|
||||||
|
inline ostringstream& put (char c) { iwrite (uint8_t(c)); return *this; }
|
||||||
|
int vformat (const char* fmt, va_list args);
|
||||||
|
int format (const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||||
|
inline uint16_t width (void) const { return _width; }
|
||||||
|
inline void width (uint16_t w) { _width = w; }
|
||||||
|
inline void set_width (uint16_t w) { _width = w; }
|
||||||
|
inline char fill (void) const { return _fill; }
|
||||||
|
inline void fill (char c) { _fill = c; }
|
||||||
|
inline uint8_t precision (void) const { return _precision; }
|
||||||
|
inline void precision (uint8_t v) { _precision = v; }
|
||||||
|
inline void set_precision (uint8_t v) { _precision = v; }
|
||||||
|
void link (void* p, size_type n) noexcept;
|
||||||
|
inline void link (memlink& l) { link (l.data(), l.writable_size()); }
|
||||||
|
inline const string& str (void) { flush(); return _buffer; }
|
||||||
|
void str (const string& s);
|
||||||
|
ostringstream& write (const void* buffer, size_type size);
|
||||||
|
inline ostringstream& write (const cmemlink& buf) { return write (buf.begin(), buf.size()); }
|
||||||
|
inline ostringstream& seekp (off_t p, seekdir d =beg) { ostream::seekp(p,d); return *this; }
|
||||||
|
virtual ostream& flush (void) override { ostream::flush(); _buffer.resize (pos()); return *this; }
|
||||||
|
virtual size_type overflow (size_type n = 1) override;
|
||||||
|
protected:
|
||||||
|
inline void reserve (size_type n) { _buffer.reserve (n, false); }
|
||||||
|
inline size_type capacity (void) const { return _buffer.capacity(); }
|
||||||
|
private:
|
||||||
|
inline void write_strz (const char*) { assert (!"Writing nul characters into a text stream is not allowed"); }
|
||||||
|
inline char* encode_dec (char* fmt, uint32_t n) const noexcept;
|
||||||
|
void fmtstring (char* fmt, const char* typestr, bool bInteger) const;
|
||||||
|
template <typename T>
|
||||||
|
void iformat (T v);
|
||||||
|
private:
|
||||||
|
string _buffer; ///< The output buffer.
|
||||||
|
fmtflags _flags; ///< See ios_base::fmtflags.
|
||||||
|
uint16_t _width; ///< Field width.
|
||||||
|
uint8_t _precision; ///< Number of digits after the decimal separator.
|
||||||
|
char _fill; ///< Character for padding variable width fields (space or 0 only)
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline const char* printf_typestring (const T&) { return ""; }
|
||||||
|
#define PRINTF_TYPESTRING_SPEC(type,str) \
|
||||||
|
template <> inline const char* printf_typestring (const type&) { return str; }
|
||||||
|
PRINTF_TYPESTRING_SPEC (short, "hd")
|
||||||
|
PRINTF_TYPESTRING_SPEC (unsigned short, "hu")
|
||||||
|
PRINTF_TYPESTRING_SPEC (int, "d")
|
||||||
|
PRINTF_TYPESTRING_SPEC (unsigned int, "u")
|
||||||
|
PRINTF_TYPESTRING_SPEC (long, "ld")
|
||||||
|
PRINTF_TYPESTRING_SPEC (unsigned long, "lu")
|
||||||
|
/*PRINTF_TYPESTRING_SPEC (float, "f")
|
||||||
|
PRINTF_TYPESTRING_SPEC (double, "lf")
|
||||||
|
PRINTF_TYPESTRING_SPEC (long double, "Lf")*/
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
PRINTF_TYPESTRING_SPEC (long long, "lld")
|
||||||
|
PRINTF_TYPESTRING_SPEC (unsigned long long, "llu")
|
||||||
|
#endif
|
||||||
|
#undef PRINTF_TYPESTRING_SPEC
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void ostringstream::iformat (T v)
|
||||||
|
{
|
||||||
|
char fmt [16];
|
||||||
|
fmtstring (fmt, printf_typestring(v), numeric_limits<T>::is_integer);
|
||||||
|
format (fmt, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ostringstream::iwrite (fmtflags_bits f)
|
||||||
|
{
|
||||||
|
if (f & basefield) setf (f, basefield);
|
||||||
|
else if (f & floatfield) setf (f, floatfield);
|
||||||
|
else if (f & adjustfield) setf (f, adjustfield);
|
||||||
|
setf (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T> struct object_text_writer {
|
||||||
|
inline void operator()(ostringstream& os, const T& v) const { v.text_write (os); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_text_object_writer {
|
||||||
|
inline void operator()(ostringstream& os, const T& v) const { os.iwrite (v); }
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
inline ostringstream& operator<< (ostringstream& os, const T& v) {
|
||||||
|
typedef typename tm::Select <tm::TypeTraits<T>::isFundamental
|
||||||
|
|| tm::TypeTraits<T>::isPointer
|
||||||
|
|| tm::Conversion<T,long>::exists,
|
||||||
|
integral_text_object_writer<T>, object_text_writer<T> >::Result object_writer_t;
|
||||||
|
object_writer_t()(os, v);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
// Needed because if called with a char[], numeric_limits will not work. Should be removed if I find out how to partial specialize for arrays...
|
||||||
|
inline ostringstream& operator<< (ostringstream& os, const char* v)
|
||||||
|
{ os.iwrite (v); return os; }
|
||||||
|
inline ostringstream& operator<< (ostringstream& os, char* v)
|
||||||
|
{ os.iwrite (v); return os; }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Object writer operators
|
||||||
|
|
||||||
|
template <> struct object_text_writer<string> {
|
||||||
|
inline void operator()(ostringstream& os, const string& v) const { os.iwrite (v); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_text_object_writer<T*> {
|
||||||
|
inline void operator() (ostringstream& os, const T* const& v) const
|
||||||
|
{ os.iwrite (uintptr_t(v)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Manipulators
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static constexpr const struct Sendl {
|
||||||
|
inline constexpr Sendl (void) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os << '\n'; os.flush(); }
|
||||||
|
inline void write (ostream& os) const { os.iwrite ('\n'); }
|
||||||
|
} endl;
|
||||||
|
static constexpr const struct Sflush {
|
||||||
|
inline constexpr Sflush (void) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.flush(); }
|
||||||
|
inline void write (ostringstream& os) const { os.flush(); }
|
||||||
|
inline void write (ostream&) const { }
|
||||||
|
} flush;
|
||||||
|
constexpr const char ends = '\0'; ///< End of string character.
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
struct setiosflags {
|
||||||
|
inline constexpr setiosflags (ios_base::fmtflags f) : _f(f) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.setf(_f); }
|
||||||
|
private:
|
||||||
|
const ios_base::fmtflags _f;
|
||||||
|
};
|
||||||
|
struct resetiosflags {
|
||||||
|
inline constexpr resetiosflags (ios_base::fmtflags f) : _f(f) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.unsetf(_f); }
|
||||||
|
private:
|
||||||
|
const ios_base::fmtflags _f;
|
||||||
|
};
|
||||||
|
class setw {
|
||||||
|
uint16_t _w;
|
||||||
|
public:
|
||||||
|
inline constexpr setw (uint16_t w) : _w(w) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.width(_w); }
|
||||||
|
inline void write (ostringstream& os) const { os.width(_w); }
|
||||||
|
};
|
||||||
|
class setfill {
|
||||||
|
char _c;
|
||||||
|
public:
|
||||||
|
inline constexpr setfill (char c) : _c(c) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.fill(_c); }
|
||||||
|
inline void write (ostringstream& os) const { os.fill(_c); }
|
||||||
|
};
|
||||||
|
class setprecision {
|
||||||
|
uint8_t _p;
|
||||||
|
public:
|
||||||
|
inline constexpr setprecision (uint8_t p) : _p(p) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.precision(_p); }
|
||||||
|
inline void write (ostringstream& os) const { os.precision(_p); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
92
pwn/flipper/dist/common/include/ustl/strmsize.h
vendored
Normal file
92
pwn/flipper/dist/common/include/ustl/strmsize.h
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
//
|
||||||
|
/// \file strmsize.h
|
||||||
|
/// \brief This file contains stream_size_of functions for basic types and *STREAMABLE macros.
|
||||||
|
/// stream_size_of functions return the size of the object's data that is written or
|
||||||
|
/// read from a stream.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// For partial specialization of stream_size_of for objects
|
||||||
|
template <typename T> struct object_stream_size {
|
||||||
|
inline streamsize operator()(const T& v) const { return v.stream_size(); }
|
||||||
|
};
|
||||||
|
template <typename T> struct integral_object_stream_size {
|
||||||
|
inline streamsize operator()(const T& v) const { return sizeof(v); }
|
||||||
|
};
|
||||||
|
/// Returns the size of the given object. Overloads for standard types are available.
|
||||||
|
template <typename T>
|
||||||
|
inline streamsize stream_size_of (const T& v) {
|
||||||
|
typedef typename tm::Select <numeric_limits<T>::is_integral,
|
||||||
|
integral_object_stream_size<T>, object_stream_size<T> >::Result stream_sizer_t;
|
||||||
|
return stream_sizer_t()(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the recommended stream alignment for type \p T. Override with ALIGNOF.
|
||||||
|
/// Because this is occasionally called with a null value, do not access the argument!
|
||||||
|
template <typename T>
|
||||||
|
inline size_t stream_align_of (const T&)
|
||||||
|
{
|
||||||
|
if (numeric_limits<T>::is_integral)
|
||||||
|
return __alignof__(T);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ALIGNOF(type,grain) \
|
||||||
|
namespace ustl { \
|
||||||
|
template <> inline size_t stream_align_of (const type&) { return grain; } }
|
||||||
|
|
||||||
|
} // namespace ustl
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extra overloads in this macro are needed because it is the one used for
|
||||||
|
// marshalling pointers. Passing a pointer to stream_size_of creates a
|
||||||
|
// conversion ambiguity between converting to const pointer& and converting
|
||||||
|
// to bool; the compiler always chooses the bool conversion (because it
|
||||||
|
// requires 1 conversion instead of 2 for the other choice). There is little
|
||||||
|
// point in adding the overloads to other macros, since they are never used
|
||||||
|
// for pointers.
|
||||||
|
//
|
||||||
|
/// Declares that T is to be written as is into binary streams.
|
||||||
|
#define INTEGRAL_STREAMABLE(T) \
|
||||||
|
namespace ustl { \
|
||||||
|
inline istream& operator>> (istream& is, T& v) { is.iread(v); return is; } \
|
||||||
|
inline ostream& operator<< (ostream& os, const T& v) { os.iwrite(v); return os; } \
|
||||||
|
inline ostream& operator<< (ostream& os, T& v) { os.iwrite(v); return os; } \
|
||||||
|
template<> inline streamsize stream_size_of(const T& v) { return sizeof(v); } \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Declares that T contains read, write, and stream_size methods. This is no longer needed and is deprecated.
|
||||||
|
#define STD_STREAMABLE(T)
|
||||||
|
|
||||||
|
/// Declares \p T to be writable to text streams. This is no longer needed and is deprecated.
|
||||||
|
#define TEXT_STREAMABLE(T)
|
||||||
|
|
||||||
|
/// Declares that T is to be cast into TSUB for streaming.
|
||||||
|
#define CAST_STREAMABLE(T,TSUB) \
|
||||||
|
namespace ustl { \
|
||||||
|
inline istream& operator>> (istream& is, T& v) { TSUB sv; is >> sv; v = T(sv); return is; } \
|
||||||
|
inline ostream& operator<< (ostream& os, const T& v) { os << TSUB(v); return os; } \
|
||||||
|
template<> inline streamsize stream_size_of(const T& v) { return stream_size_of (TSUB(v)); } \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Placed into a class it declares the methods required by STD_STREAMABLE. Syntactic sugar.
|
||||||
|
#define DECLARE_STD_STREAMABLE \
|
||||||
|
public: \
|
||||||
|
void read (istream& is); \
|
||||||
|
void write (ostream& os) const; \
|
||||||
|
streamsize stream_size (void) const
|
||||||
|
|
||||||
|
/// Specifies that \p T is printed by using it as an index into \p Names string array.
|
||||||
|
#define LOOKUP_TEXT_STREAMABLE(T,Names,nNames) \
|
||||||
|
namespace ustl { \
|
||||||
|
inline ostringstream& operator<< (ostringstream& os, const T& v) { \
|
||||||
|
os << Names[min(uoff_t(v),uoff_t(nNames-1))]; \
|
||||||
|
return os; \
|
||||||
|
} \
|
||||||
|
}
|
266
pwn/flipper/dist/common/include/ustl/traits.h
vendored
Normal file
266
pwn/flipper/dist/common/include/ustl/traits.h
vendored
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
//
|
||||||
|
// This implementation is adapted from the Loki library, distributed under
|
||||||
|
// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "typelist.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
namespace tm {
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Type classes and type modifiers
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef tl::Seq<unsigned char, unsigned short, unsigned, unsigned long>::Type
|
||||||
|
StdUnsignedInts;
|
||||||
|
typedef tl::Seq<signed char, short, int, long>::Type StdSignedInts;
|
||||||
|
typedef tl::Seq<bool, char, wchar_t>::Type StdOtherInts;
|
||||||
|
typedef tl::Seq</*float, double*/>::Type StdFloats;
|
||||||
|
|
||||||
|
template <typename U> struct Identity { typedef U Result; };
|
||||||
|
template <typename U> struct AddPointer { typedef U* Result; };
|
||||||
|
template <typename U> struct AddPointer<U&> { typedef U* Result; };
|
||||||
|
template <typename U> struct AddReference { typedef U& Result; };
|
||||||
|
template <typename U> struct AddReference<U&> { typedef U& Result; };
|
||||||
|
template <> struct AddReference<void> { typedef NullType Result; };
|
||||||
|
template <typename U> struct AddParameterType { typedef const U& Result; };
|
||||||
|
template <typename U> struct AddParameterType<U&> { typedef U& Result; };
|
||||||
|
template <> struct AddParameterType<void> { typedef NullType Result; };
|
||||||
|
template <typename U> struct RemoveReference { typedef U Result; };
|
||||||
|
template <typename U> struct RemoveReference<U&> { typedef U Result; };
|
||||||
|
#if HAVE_CPP11
|
||||||
|
template <typename U> struct RemoveReference<U&&> { typedef U Result; };
|
||||||
|
#endif
|
||||||
|
template <bool, typename T> struct EnableIf { typedef void Result; };
|
||||||
|
template <typename T> struct EnableIf<true, T> { typedef T Result; };
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Function pointer testers
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Macros expand to numerous parameters
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsFunctionPointerRaw { enum { result = false}; };
|
||||||
|
template <typename T>
|
||||||
|
struct IsMemberFunctionPointerRaw { enum { result = false}; };
|
||||||
|
|
||||||
|
#define TM_FPR_MAXN 9
|
||||||
|
#define TM_FPR_TYPE(n) PASTE(T,n)
|
||||||
|
#define TM_FPR_TYPENAME(n) typename TM_FPR_TYPE(n)
|
||||||
|
|
||||||
|
// First specialize for regular functions
|
||||||
|
template <typename T>
|
||||||
|
struct IsFunctionPointerRaw<T(*)(void)>
|
||||||
|
{enum {result = true};};
|
||||||
|
|
||||||
|
#define TM_FPR_SPEC(n) \
|
||||||
|
template <typename T, COMMA_LIST(n, TM_FPR_TYPENAME)> \
|
||||||
|
struct IsFunctionPointerRaw<T(*)(COMMA_LIST(n, TM_FPR_TYPE))> \
|
||||||
|
{ enum { result = true }; }
|
||||||
|
|
||||||
|
LIST (TM_FPR_MAXN, TM_FPR_SPEC, ;);
|
||||||
|
|
||||||
|
// Then for those with an ellipsis argument
|
||||||
|
template <typename T>
|
||||||
|
struct IsFunctionPointerRaw<T(*)(...)>
|
||||||
|
{enum {result = true};};
|
||||||
|
|
||||||
|
#define TM_FPR_SPEC_ELLIPSIS(n) \
|
||||||
|
template <typename T, COMMA_LIST(n, TM_FPR_TYPENAME)> \
|
||||||
|
struct IsFunctionPointerRaw<T(*)(COMMA_LIST(n, TM_FPR_TYPE), ...)> \
|
||||||
|
{ enum { result = true }; }
|
||||||
|
|
||||||
|
LIST (TM_FPR_MAXN, TM_FPR_SPEC_ELLIPSIS, ;);
|
||||||
|
|
||||||
|
// Then for member function pointers
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(void)>
|
||||||
|
{ enum { result = true }; };
|
||||||
|
|
||||||
|
#define TM_MFPR_SPEC(n) \
|
||||||
|
template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE))> \
|
||||||
|
{ enum { result = true };};
|
||||||
|
|
||||||
|
LIST (TM_FPR_MAXN, TM_MFPR_SPEC, ;);
|
||||||
|
|
||||||
|
// Then for member function pointers with an ellipsis argument
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(...)>
|
||||||
|
{ enum { result = true }; };
|
||||||
|
|
||||||
|
#define TM_MFPR_SPEC_ELLIPSIS(n) \
|
||||||
|
template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE), ...)> \
|
||||||
|
{ enum { result = true }; };
|
||||||
|
|
||||||
|
LIST (TM_FPR_MAXN, TM_MFPR_SPEC_ELLIPSIS, ;);
|
||||||
|
|
||||||
|
// Then for const member function pointers (getting tired yet?)
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(void) const>
|
||||||
|
{ enum { result = true }; };
|
||||||
|
|
||||||
|
#define TM_CMFPR_SPEC(n) \
|
||||||
|
template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE)) const> \
|
||||||
|
{ enum { result = true };};
|
||||||
|
|
||||||
|
LIST (TM_FPR_MAXN, TM_CMFPR_SPEC, ;);
|
||||||
|
|
||||||
|
// Finally for const member function pointers with an ellipsis argument (whew!)
|
||||||
|
template <typename T, typename S>
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(...) const>
|
||||||
|
{ enum { result = true }; };
|
||||||
|
|
||||||
|
#define TM_CMFPR_SPEC_ELLIPSIS(n) \
|
||||||
|
template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \
|
||||||
|
struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE), ...) const> \
|
||||||
|
{ enum { result = true }; };
|
||||||
|
|
||||||
|
LIST (TM_FPR_MAXN, TM_CMFPR_SPEC_ELLIPSIS, ;);
|
||||||
|
|
||||||
|
#undef TM_FPR_SPEC
|
||||||
|
#undef TM_FPR_SPEC_ELLIPSIS
|
||||||
|
#undef TM_MFPR_SPEC
|
||||||
|
#undef TM_MFPR_SPEC_ELLIPSIS
|
||||||
|
#undef TM_CMFPR_SPEC
|
||||||
|
#undef TM_CMFPR_SPEC_ELLIPSIS
|
||||||
|
#undef TM_FPR_TYPENAME
|
||||||
|
#undef TM_FPR_TYPE
|
||||||
|
#undef TM_FPR_MAXN
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Type traits template
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Figures out at compile time various properties of any given type
|
||||||
|
/// Invocations (T is a type, TypeTraits<T>::Propertie):
|
||||||
|
///
|
||||||
|
/// - isPointer : returns true if T is a pointer type
|
||||||
|
/// - PointeeType : returns the type to which T points if T is a pointer
|
||||||
|
/// type, NullType otherwise
|
||||||
|
/// - isReference : returns true if T is a reference type
|
||||||
|
/// - isLValue : returns true if T is an lvalue
|
||||||
|
/// - isRValue : returns true if T is an rvalue
|
||||||
|
/// - ReferredType : returns the type to which T refers if T is a reference
|
||||||
|
/// type, NullType otherwise
|
||||||
|
/// - isMemberPointer : returns true if T is a pointer to member type
|
||||||
|
/// - isStdUnsignedInt: returns true if T is a standard unsigned integral type
|
||||||
|
/// - isStdSignedInt : returns true if T is a standard signed integral type
|
||||||
|
/// - isStdIntegral : returns true if T is a standard integral type
|
||||||
|
/// - isStdFloat : returns true if T is a standard floating-point type
|
||||||
|
/// - isStdArith : returns true if T is a standard arithmetic type
|
||||||
|
/// - isStdFundamental: returns true if T is a standard fundamental type
|
||||||
|
/// - isUnsignedInt : returns true if T is a unsigned integral type
|
||||||
|
/// - isSignedInt : returns true if T is a signed integral type
|
||||||
|
/// - isIntegral : returns true if T is a integral type
|
||||||
|
/// - isFloat : returns true if T is a floating-point type
|
||||||
|
/// - isArith : returns true if T is a arithmetic type
|
||||||
|
/// - isFundamental : returns true if T is a fundamental type
|
||||||
|
/// - ParameterType : returns the optimal type to be used as a parameter for
|
||||||
|
/// functions that take Ts
|
||||||
|
/// - isConst : returns true if T is a const-qualified type
|
||||||
|
/// - NonConstType : Type with removed 'const' qualifier from T, if any
|
||||||
|
/// - isVolatile : returns true if T is a volatile-qualified type
|
||||||
|
/// - NonVolatileType : Type with removed 'volatile' qualifier from T, if any
|
||||||
|
/// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from
|
||||||
|
/// T, if any
|
||||||
|
/// - ConstParameterType: returns the optimal type to be used as a parameter
|
||||||
|
/// for functions that take 'const T's
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
class TypeTraits {
|
||||||
|
private:
|
||||||
|
#define TMTT1 template <typename U> struct
|
||||||
|
#define TMTT2 template <typename U, typename V> struct
|
||||||
|
TMTT1 ReferenceTraits { enum { result = false, lvalue = true, rvalue = false }; typedef U ReferredType; };
|
||||||
|
TMTT1 ReferenceTraits<U&> { enum { result = true, lvalue = true, rvalue = false }; typedef U ReferredType; };
|
||||||
|
TMTT1 PointerTraits { enum { result = false }; typedef NullType PointeeType; };
|
||||||
|
TMTT1 PointerTraits<U*> { enum { result = true }; typedef U PointeeType; };
|
||||||
|
TMTT1 PointerTraits<U*&> { enum { result = true }; typedef U PointeeType; };
|
||||||
|
TMTT1 PToMTraits { enum { result = false }; };
|
||||||
|
TMTT2 PToMTraits<U V::*> { enum { result = true }; };
|
||||||
|
TMTT2 PToMTraits<U V::*&> { enum { result = true }; };
|
||||||
|
TMTT1 FunctionPointerTraits { enum { result = IsFunctionPointerRaw<U>::result }; };
|
||||||
|
TMTT1 PToMFunctionTraits { enum { result = IsMemberFunctionPointerRaw<U>::result }; };
|
||||||
|
TMTT1 UnConst { typedef U Result; enum { isConst = false }; };
|
||||||
|
TMTT1 UnConst<const U> { typedef U Result; enum { isConst = true }; };
|
||||||
|
TMTT1 UnConst<const U&> { typedef U& Result; enum { isConst = true }; };
|
||||||
|
TMTT1 UnVolatile { typedef U Result; enum { isVolatile = false }; };
|
||||||
|
TMTT1 UnVolatile<volatile U>{ typedef U Result; enum { isVolatile = true }; };
|
||||||
|
TMTT1 UnVolatile<volatile U&> {typedef U& Result;enum { isVolatile = true }; };
|
||||||
|
#if HAVE_CPP11
|
||||||
|
TMTT1 ReferenceTraits<U&&> { enum { result = true, lvalue = false, rvalue = true }; typedef U ReferredType; };
|
||||||
|
TMTT1 PointerTraits<U*&&> { enum { result = true }; typedef U PointeeType; };
|
||||||
|
TMTT2 PToMTraits<U V::*&&> { enum { result = true }; };
|
||||||
|
TMTT1 UnConst<const U&&> { typedef U&& Result; enum { isConst = true }; };
|
||||||
|
TMTT1 UnVolatile<volatile U&&> {typedef U&& Result;enum { isVolatile = true }; };
|
||||||
|
#endif
|
||||||
|
#undef TMTT2
|
||||||
|
#undef TMTT1
|
||||||
|
public:
|
||||||
|
typedef typename UnConst<T>::Result
|
||||||
|
NonConstType;
|
||||||
|
typedef typename UnVolatile<T>::Result
|
||||||
|
NonVolatileType;
|
||||||
|
typedef typename UnVolatile<typename UnConst<T>::Result>::Result
|
||||||
|
UnqualifiedType;
|
||||||
|
typedef typename PointerTraits<UnqualifiedType>::PointeeType
|
||||||
|
PointeeType;
|
||||||
|
typedef typename ReferenceTraits<T>::ReferredType
|
||||||
|
ReferredType;
|
||||||
|
|
||||||
|
enum { isConst = UnConst<T>::isConst };
|
||||||
|
enum { isVolatile = UnVolatile<T>::isVolatile };
|
||||||
|
enum { isReference = ReferenceTraits<UnqualifiedType>::result };
|
||||||
|
enum { isLValue = ReferenceTraits<UnqualifiedType>::lvalue };
|
||||||
|
enum { isRValue = ReferenceTraits<UnqualifiedType>::rvalue };
|
||||||
|
enum { isFunction = FunctionPointerTraits<typename AddPointer<T>::Result >::result };
|
||||||
|
enum { isFunctionPointer = FunctionPointerTraits<
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType >::result };
|
||||||
|
enum { isMemberFunctionPointer= PToMFunctionTraits<
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType >::result };
|
||||||
|
enum { isMemberPointer = PToMTraits<
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
|
||||||
|
isMemberFunctionPointer };
|
||||||
|
enum { isPointer = PointerTraits<
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
|
||||||
|
isFunctionPointer };
|
||||||
|
enum { isStdUnsignedInt = tl::IndexOf<StdUnsignedInts, UnqualifiedType>::value >= 0 ||
|
||||||
|
tl::IndexOf<StdUnsignedInts,
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
|
||||||
|
enum { isStdSignedInt = tl::IndexOf<StdSignedInts, UnqualifiedType>::value >= 0 ||
|
||||||
|
tl::IndexOf<StdSignedInts,
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
|
||||||
|
enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
|
||||||
|
tl::IndexOf<StdOtherInts, UnqualifiedType>::value >= 0 ||
|
||||||
|
tl::IndexOf<StdOtherInts,
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
|
||||||
|
enum { isStdFloat = tl::IndexOf<StdFloats, UnqualifiedType>::value >= 0 ||
|
||||||
|
tl::IndexOf<StdFloats,
|
||||||
|
typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
|
||||||
|
enum { isStdArith = isStdIntegral || isStdFloat };
|
||||||
|
enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType };
|
||||||
|
|
||||||
|
enum { isUnsignedInt = isStdUnsignedInt };
|
||||||
|
enum { isUnsigned = isUnsignedInt || isPointer };
|
||||||
|
enum { isSignedInt = isStdSignedInt };
|
||||||
|
enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
|
||||||
|
enum { isFloat = isStdFloat };
|
||||||
|
enum { isSigned = isSignedInt || isFloat };
|
||||||
|
enum { isArith = isIntegral || isFloat };
|
||||||
|
enum { isFundamental = isStdFundamental || isArith };
|
||||||
|
|
||||||
|
typedef typename Select<isStdArith || isPointer || isMemberPointer, T,
|
||||||
|
typename AddParameterType<T>::Result>::Result
|
||||||
|
ParameterType;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace tm
|
||||||
|
} // namespace ustl
|
219
pwn/flipper/dist/common/include/ustl/typelist.h
vendored
Normal file
219
pwn/flipper/dist/common/include/ustl/typelist.h
vendored
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
//
|
||||||
|
// This implementation is adapted from the Loki library, distributed under
|
||||||
|
// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "metamac.h"
|
||||||
|
#include "typet.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
namespace tm {
|
||||||
|
|
||||||
|
/// The building block of typelists. Use it throught the Seq templates.
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct Typelist {
|
||||||
|
typedef T Head;
|
||||||
|
typedef U Tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Namespace containing typelist-related functionality.
|
||||||
|
namespace tl {
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Seq template definitions. The macros expand to a spec per arg count
|
||||||
|
//
|
||||||
|
#define TL_MAX_SEQ_TYPES 9
|
||||||
|
#define TL_MAX_SEQ_SPECS 8
|
||||||
|
#define TL_SEQ_TYPE(n) T##n
|
||||||
|
#define TL_SEQ_TYPENAME(n) typename TL_SEQ_TYPE(n)
|
||||||
|
#define TL_SEQ_NULLTYPE_DEFAULT(n) TL_SEQ_TYPENAME(n)=NullType
|
||||||
|
#define TL_SEQ_TL_END(n) >
|
||||||
|
#define TL_SEQ_ONE_TYPELIST(n) Typelist<TL_SEQ_TYPE(n)
|
||||||
|
|
||||||
|
/// Creates a typelist from a sequence of types
|
||||||
|
template <COMMA_LIST(TL_MAX_SEQ_TYPES,TL_SEQ_NULLTYPE_DEFAULT)>
|
||||||
|
struct Seq {
|
||||||
|
typedef COMMA_LIST(TL_MAX_SEQ_TYPES,TL_SEQ_ONE_TYPELIST),
|
||||||
|
NullType REPEAT(TL_MAX_SEQ_TYPES,TL_SEQ_TL_END) Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TL_SEQ_SPEC(n) \
|
||||||
|
template <COMMA_LIST (n, TL_SEQ_TYPENAME)> \
|
||||||
|
struct Seq<COMMA_LIST (n, TL_SEQ_TYPE)> { \
|
||||||
|
typedef COMMA_LIST(n,TL_SEQ_ONE_TYPELIST), \
|
||||||
|
NullType REPEAT(n,TL_SEQ_TL_END) Type; \
|
||||||
|
}
|
||||||
|
LIST(TL_MAX_SEQ_SPECS,TL_SEQ_SPEC, ;);
|
||||||
|
|
||||||
|
#undef TL_SEQ_SPEC
|
||||||
|
#undef TL_SEQ_TL_END
|
||||||
|
#undef TL_SEQ_ONE_TYPELIST
|
||||||
|
#undef TL_SEQ_NULLTYPE_DEFAULT
|
||||||
|
#undef TL_SEQ_TYPE
|
||||||
|
#undef TL_MAX_SEQ_SPECS
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Various utility functions follow.
|
||||||
|
|
||||||
|
/// Length<List>::value is the number of types in the typelist.
|
||||||
|
template <typename List> struct Length { };
|
||||||
|
template <> struct Length<NullType> { enum { value = 0 }; };
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct Length<Typelist<T, U> > { enum { value = 1 + Length<U>::value }; };
|
||||||
|
|
||||||
|
/// TypeAt<List, i>::Result is the ith type in List
|
||||||
|
template <typename List, unsigned index> struct TypeAt { };
|
||||||
|
template <class Head, class Tail>
|
||||||
|
struct TypeAt<Typelist<Head, Tail>, 0> {
|
||||||
|
typedef Head Result;
|
||||||
|
};
|
||||||
|
template <class Head, class Tail, unsigned index>
|
||||||
|
struct TypeAt<Typelist<Head, Tail>, index> {
|
||||||
|
typedef typename TypeAt<Tail, index-1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// TypeAtNonStrict<List,i,DefaultType>::Result is List[i] or DefaultType if out of range.
|
||||||
|
template <typename List, unsigned index, typename DefaultType = NullType>
|
||||||
|
struct TypeAtNonStrict {
|
||||||
|
typedef DefaultType Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail, typename DefaultType>
|
||||||
|
struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType> {
|
||||||
|
typedef Head Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail, unsigned index, typename DefaultType>
|
||||||
|
struct TypeAtNonStrict<Typelist<Head, Tail>, index, DefaultType> {
|
||||||
|
typedef typename TypeAtNonStrict<Tail, index-1, DefaultType>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// IndexOf<List,T>::value is the position of T in List, or -1 if not found.
|
||||||
|
template <typename List, typename T> struct IndexOf;
|
||||||
|
template <typename T>
|
||||||
|
struct IndexOf<NullType, T> { enum { value = -1 }; };
|
||||||
|
template <typename T, typename Tail>
|
||||||
|
struct IndexOf<Typelist<T, Tail>, T> { enum { value = 0 }; };
|
||||||
|
template <typename Head, typename Tail, typename T>
|
||||||
|
struct IndexOf<Typelist<Head, Tail>, T> {
|
||||||
|
private:
|
||||||
|
enum { iintail = IndexOf<Tail, T>::value };
|
||||||
|
public:
|
||||||
|
enum { value = (iintail == -1 ? -1 : 1+iintail) };
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Appends a type or a typelist to another in Append<TList, T>::Result
|
||||||
|
template <typename List, typename T> struct Append;
|
||||||
|
template <> struct Append<NullType, NullType> { typedef NullType Result; };
|
||||||
|
template <typename T> struct Append<NullType, T> {
|
||||||
|
typedef Typelist<T,NullType> Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail>
|
||||||
|
struct Append<NullType, Typelist<Head, Tail> > {
|
||||||
|
typedef Typelist<Head, Tail> Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail, typename T>
|
||||||
|
struct Append<Typelist<Head, Tail>, T> {
|
||||||
|
typedef Typelist<Head, typename Append<Tail, T>::Result> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Erase<List, T>::Result contains List without the first T.
|
||||||
|
template <typename TList, typename T> struct Erase;
|
||||||
|
template <typename T>
|
||||||
|
struct Erase<NullType, T> { typedef NullType Result; };
|
||||||
|
template <typename T, typename Tail>
|
||||||
|
struct Erase<Typelist<T, Tail>, T> { typedef Tail Result; };
|
||||||
|
template <typename Head, typename Tail, typename T>
|
||||||
|
struct Erase<Typelist<Head, Tail>, T> {
|
||||||
|
typedef Typelist<Head, typename Erase<Tail, T>::Result> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// EraseAll<List, T>::Result contains List without any T.
|
||||||
|
template <typename List, typename T> struct EraseAll;
|
||||||
|
template <typename T>
|
||||||
|
struct EraseAll<NullType, T> { typedef NullType Result; };
|
||||||
|
template <typename T, typename Tail>
|
||||||
|
struct EraseAll<Typelist<T, Tail>, T> {
|
||||||
|
typedef typename EraseAll<Tail, T>::Result Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail, typename T>
|
||||||
|
struct EraseAll<Typelist<Head, Tail>, T> {
|
||||||
|
typedef Typelist<Head, typename EraseAll<Tail, T>::Result> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Removes all duplicate types in a typelist
|
||||||
|
template <typename List> struct NoDuplicates;
|
||||||
|
template <> struct NoDuplicates<NullType> { typedef NullType Result; };
|
||||||
|
template <typename Head, typename Tail>
|
||||||
|
struct NoDuplicates< Typelist<Head, Tail> > {
|
||||||
|
private:
|
||||||
|
typedef typename NoDuplicates<Tail>::Result L1;
|
||||||
|
typedef typename Erase<L1, Head>::Result L2;
|
||||||
|
public:
|
||||||
|
typedef Typelist<Head, L2> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Replaces the first occurence of a type in a typelist, with another type
|
||||||
|
template <typename List, typename T, typename U> struct Replace;
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct Replace<NullType, T, U> { typedef NullType Result; };
|
||||||
|
template <typename T, typename Tail, typename U>
|
||||||
|
struct Replace<Typelist<T, Tail>, T, U> {
|
||||||
|
typedef Typelist<U, Tail> Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail, typename T, typename U>
|
||||||
|
struct Replace<Typelist<Head, Tail>, T, U> {
|
||||||
|
typedef Typelist<Head, typename Replace<Tail, T, U>::Result> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Replaces all occurences of a type in a typelist, with another type
|
||||||
|
template <typename List, typename T, typename U> struct ReplaceAll;
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct ReplaceAll<NullType, T, U> { typedef NullType Result; };
|
||||||
|
template <typename T, typename Tail, typename U>
|
||||||
|
struct ReplaceAll<Typelist<T, Tail>, T, U> {
|
||||||
|
typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
|
||||||
|
};
|
||||||
|
template <typename Head, typename Tail, typename T, typename U>
|
||||||
|
struct ReplaceAll<Typelist<Head, Tail>, T, U> {
|
||||||
|
typedef Typelist<Head, typename ReplaceAll<Tail, T, U>::Result> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reverses a typelist
|
||||||
|
template <typename List> struct Reverse;
|
||||||
|
template <> struct Reverse<NullType> { typedef NullType Result; };
|
||||||
|
template <typename Head, typename Tail>
|
||||||
|
struct Reverse< Typelist<Head, Tail> > {
|
||||||
|
typedef typename Append<typename Reverse<Tail>::Result, Head>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Finds the type in a typelist that is the most derived from a given type
|
||||||
|
template <typename List, typename T> struct MostDerived;
|
||||||
|
template <typename T> struct MostDerived<NullType, T> { typedef T Result; };
|
||||||
|
template <typename Head, typename Tail, typename T>
|
||||||
|
struct MostDerived<Typelist<Head, Tail>, T> {
|
||||||
|
private:
|
||||||
|
typedef typename MostDerived<Tail, T>::Result Candidate;
|
||||||
|
public:
|
||||||
|
typedef typename Select<SuperSubclass<Candidate,Head>::value, Head, Candidate>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Arranges the types in a typelist so that the most derived types appear first
|
||||||
|
template <typename List> struct DerivedToFront;
|
||||||
|
template <> struct DerivedToFront<NullType> { typedef NullType Result; };
|
||||||
|
template <typename Head, typename Tail>
|
||||||
|
struct DerivedToFront< Typelist<Head, Tail> > {
|
||||||
|
private:
|
||||||
|
typedef typename MostDerived<Tail, Head>::Result TheMostDerived;
|
||||||
|
typedef typename Replace<Tail, TheMostDerived, Head>::Result Temp;
|
||||||
|
typedef typename DerivedToFront<Temp>::Result L;
|
||||||
|
public:
|
||||||
|
typedef Typelist<TheMostDerived, L> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace tl
|
||||||
|
} // namespace tm
|
||||||
|
} // namespace ustl
|
96
pwn/flipper/dist/common/include/ustl/typet.h
vendored
Normal file
96
pwn/flipper/dist/common/include/ustl/typet.h
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
//
|
||||||
|
// This implementation is adapted from the Loki library, distributed under
|
||||||
|
// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
/// Template metaprogramming tools
|
||||||
|
namespace tm {
|
||||||
|
|
||||||
|
/// An empty type useful as a placeholder.
|
||||||
|
class NullType { };
|
||||||
|
|
||||||
|
/// Converts an integer to a type.
|
||||||
|
template <int v> struct Int2Type { enum { value = v }; };
|
||||||
|
|
||||||
|
/// Converts an type to a unique empty type.
|
||||||
|
template <typename T> struct Type2Type { typedef T OriginalType; };
|
||||||
|
|
||||||
|
/// Selects type Result = flag ? T : U
|
||||||
|
template <bool flag, typename T, typename U>
|
||||||
|
struct Select { typedef T Result; };
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct Select<false, T, U> { typedef U Result; };
|
||||||
|
|
||||||
|
/// IsSameType<T,U>::value is true when T=U
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct IsSameType { enum { value = false }; };
|
||||||
|
template <typename T>
|
||||||
|
struct IsSameType<T,T> { enum { value = true }; };
|
||||||
|
|
||||||
|
/// \brief Checks for conversion possibilities between T and U
|
||||||
|
/// Conversion<T,U>::exists is true if T is convertible to U
|
||||||
|
/// Conversion<T,U>::sameType is true if U is T
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct Conversion {
|
||||||
|
private:
|
||||||
|
typedef char UT;
|
||||||
|
typedef short TT;
|
||||||
|
static UT Test (U);
|
||||||
|
static TT Test (...);
|
||||||
|
static T MakeT (void);
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
exists = sizeof(UT) == sizeof(Test(MakeT())),
|
||||||
|
sameType = false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct Conversion<T, T> { enum { exists = true, sameType = true }; };
|
||||||
|
template <typename T>
|
||||||
|
struct Conversion<void, T> { enum { exists = false, sameType = false }; };
|
||||||
|
template <typename T>
|
||||||
|
struct Conversion<T, void> { enum { exists = false, sameType = false }; };
|
||||||
|
template <>
|
||||||
|
struct Conversion<void, void> { enum { exists = true, sameType = true }; };
|
||||||
|
|
||||||
|
/// SuperSubclass<T,U>::value is true when U is derived from T, or when U is T
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct SuperSubclass {
|
||||||
|
enum { value = (::ustl::tm::Conversion<const volatile U*, const volatile T*>::exists &&
|
||||||
|
!::ustl::tm::Conversion<const volatile T*, const volatile void*>::sameType) };
|
||||||
|
enum { dontUseWithIncompleteTypes = sizeof(T)==sizeof(U) }; // Dummy enum to make sure that both classes are fully defined.
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct SuperSubclass<void, void> { enum { value = false }; };
|
||||||
|
template <typename U>
|
||||||
|
struct SuperSubclass<void, U> {
|
||||||
|
enum { value = false };
|
||||||
|
enum { dontUseWithIncompleteTypes = 0==sizeof(U) };
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct SuperSubclass<T, void> {
|
||||||
|
enum { value = false };
|
||||||
|
enum { dontUseWithIncompleteTypes = 0==sizeof(T) };
|
||||||
|
};
|
||||||
|
|
||||||
|
/// SuperSubclassStrict<T,U>::value is true when U is derived from T
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct SuperSubclassStrict {
|
||||||
|
enum { value = SuperSubclass<T,U>::value &&
|
||||||
|
!::ustl::tm::Conversion<const volatile T*, const volatile U*>::sameType };
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !HAVE_CPP11
|
||||||
|
// static assert support
|
||||||
|
template <bool> struct CompileTimeError;
|
||||||
|
template <> struct CompileTimeError<true> {};
|
||||||
|
#define static_assert(cond,msg) { ::ustl::tm::CompileTimeError<!!(cond)> ERROR_##msg; (void) ERROR_##msg; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace tm
|
||||||
|
} // namespace ustl
|
733
pwn/flipper/dist/common/include/ustl/ualgo.h
vendored
Normal file
733
pwn/flipper/dist/common/include/ustl/ualgo.h
vendored
Normal file
@ -0,0 +1,733 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "upair.h"
|
||||||
|
#include "ufunction.h"
|
||||||
|
#include "umemory.h"
|
||||||
|
#include "util/qsort.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// Swaps corresponding elements of [first, last) and [result,)
|
||||||
|
/// \ingroup SwapAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator1, typename ForwardIterator2>
|
||||||
|
inline ForwardIterator2 swap_ranges (ForwardIterator1 first, ForwardIterator2 last, ForwardIterator2 result)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first, ++result)
|
||||||
|
iter_swap (first, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the first iterator i in the range [first, last) such that
|
||||||
|
/// *i == value. Returns last if no such iterator exists.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename EqualityComparable>
|
||||||
|
inline InputIterator find (InputIterator first, InputIterator last, const EqualityComparable& value)
|
||||||
|
{
|
||||||
|
while (first != last && !(*first == value))
|
||||||
|
++ first;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the first iterator such that *i == *(i + 1)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
if (first != last)
|
||||||
|
for (ForwardIterator prev = first; ++first != last; ++ prev)
|
||||||
|
if (*prev == *first)
|
||||||
|
return prev;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the pointer to the first pair of unequal elements.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator>
|
||||||
|
pair<InputIterator,InputIterator>
|
||||||
|
mismatch (InputIterator first1, InputIterator last1, InputIterator first2)
|
||||||
|
{
|
||||||
|
while (first1 != last1 && *first1 == *first2)
|
||||||
|
++ first1, ++ first2;
|
||||||
|
return make_pair (first1, first2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns true if two ranges are equal.
|
||||||
|
/// This is an extension, present in uSTL and SGI STL.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator>
|
||||||
|
inline bool equal (InputIterator first1, InputIterator last1, InputIterator first2)
|
||||||
|
{
|
||||||
|
return mismatch (first1, last1, first2).first == last1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count finds the number of elements in [first, last) that are equal
|
||||||
|
/// to value. More precisely, the first version of count returns the
|
||||||
|
/// number of iterators i in [first, last) such that *i == value.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename EqualityComparable>
|
||||||
|
inline size_t count (InputIterator first, InputIterator last, const EqualityComparable& value)
|
||||||
|
{
|
||||||
|
size_t total = 0;
|
||||||
|
for (; first != last; ++first)
|
||||||
|
if (*first == value)
|
||||||
|
++ total;
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The first version of transform performs the operation op(*i) for each
|
||||||
|
/// iterator i in the range [first, last), and assigns the result of that
|
||||||
|
/// operation to *o, where o is the corresponding output iterator. That is,
|
||||||
|
/// for each n such that 0 <= n < last - first, it performs the assignment
|
||||||
|
/// *(result + n) = op(*(first + n)).
|
||||||
|
/// The return value is result + (last - first).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
/// \ingroup PredicateAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator, typename UnaryFunction>
|
||||||
|
inline OutputIterator transform (InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op)
|
||||||
|
{
|
||||||
|
for (; first != last; ++result, ++first)
|
||||||
|
*result = op (*first);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The second version of transform is very similar, except that it uses a
|
||||||
|
/// Binary Function instead of a Unary Function: it performs the operation
|
||||||
|
/// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns
|
||||||
|
/// the result to *o, where i2 is the corresponding iterator in the second
|
||||||
|
/// input range and where o is the corresponding output iterator. That is,
|
||||||
|
/// for each n such that 0 <= n < last1 - first1, it performs the assignment
|
||||||
|
/// *(result + n) = op(*(first1 + n), *(first2 + n).
|
||||||
|
/// The return value is result + (last1 - first1).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
/// \ingroup PredicateAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryFunction>
|
||||||
|
inline OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op)
|
||||||
|
{
|
||||||
|
for (; first1 != last1; ++result, ++first1, ++first2)
|
||||||
|
*result = op (*first1, *first2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace replaces every element in the range [first, last) equal to
|
||||||
|
/// old_value with new_value. That is: for every iterator i,
|
||||||
|
/// if *i == old_value then it performs the assignment *i = new_value.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename T>
|
||||||
|
inline void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first)
|
||||||
|
if (*first == old_value)
|
||||||
|
*first = new_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace_copy copies elements from the range [first, last) to the range
|
||||||
|
/// [result, result + (last-first)), except that any element equal to old_value
|
||||||
|
/// is not copied; new_value is copied instead. More precisely, for every
|
||||||
|
/// integer n such that 0 <= n < last-first, replace_copy performs the
|
||||||
|
/// assignment *(result+n) = new_value if *(first+n) == old_value, and
|
||||||
|
/// *(result+n) = *(first+n) otherwise.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator, typename T>
|
||||||
|
inline OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value)
|
||||||
|
{
|
||||||
|
for (; first != last; ++result, ++first)
|
||||||
|
*result = (*first == old_value) ? new_value : *first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate assigns the result of invoking gen, a function object that
|
||||||
|
/// takes no arguments, to each element in the range [first, last).
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
/// \ingroup PredicateAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename Generator>
|
||||||
|
inline void generate (ForwardIterator first, ForwardIterator last, Generator gen)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first)
|
||||||
|
*first = gen();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate_n assigns the result of invoking gen, a function object that
|
||||||
|
/// takes no arguments, to each element in the range [first, first+n).
|
||||||
|
/// The return value is first + n.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
/// \ingroup PredicateAlgorithms
|
||||||
|
///
|
||||||
|
template <typename OutputIterator, typename Generator>
|
||||||
|
inline OutputIterator generate_n (OutputIterator first, size_t n, Generator gen)
|
||||||
|
{
|
||||||
|
for (uoff_t i = 0; i != n; ++i, ++first)
|
||||||
|
*first = gen();
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Reverse reverses a range.
|
||||||
|
/// That is: for every i such that 0 <= i <= (last - first) / 2),
|
||||||
|
/// it exchanges *(first + i) and *(last - (i + 1)).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename BidirectionalIterator>
|
||||||
|
inline void reverse (BidirectionalIterator first, BidirectionalIterator last)
|
||||||
|
{
|
||||||
|
for (; distance (first, --last) > 0; ++first)
|
||||||
|
iter_swap (first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Reverses [first,last) and writes it to \p output.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename BidirectionalIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator reverse_copy (BidirectionalIterator first, BidirectionalIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
for (; first != last; ++result)
|
||||||
|
*result = *--last;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Exchanges ranges [first, middle) and [middle, last)
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
ForwardIterator rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last)
|
||||||
|
{
|
||||||
|
if (first == middle || middle == last)
|
||||||
|
return first;
|
||||||
|
reverse (first, middle);
|
||||||
|
reverse (middle, last);
|
||||||
|
for (;first != middle && middle != last; ++first)
|
||||||
|
iter_swap (first, --last);
|
||||||
|
reverse (first, (first == middle ? last : middle));
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specialization for pointers, which can be treated identically.
|
||||||
|
template <typename T>
|
||||||
|
inline T* rotate (T* first, T* middle, T* last)
|
||||||
|
{
|
||||||
|
rotate_fast (first, middle, last);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Exchanges ranges [first, middle) and [middle, last) into \p result.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
return copy (first, middle, copy (middle, last, result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Combines two sorted ranges.
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||||
|
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
|
||||||
|
InputIterator2 first2, InputIterator2 last2, OutputIterator result)
|
||||||
|
{
|
||||||
|
for (; first1 != last1 && first2 != last2; ++result) {
|
||||||
|
if (*first1 < *first2)
|
||||||
|
*result = *first1++;
|
||||||
|
else
|
||||||
|
*result = *first2++;
|
||||||
|
}
|
||||||
|
if (first1 < last1)
|
||||||
|
return copy (first1, last1, result);
|
||||||
|
else
|
||||||
|
return copy (first2, last2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Combines two sorted ranges from the same container.
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator>
|
||||||
|
void inplace_merge (InputIterator first, InputIterator middle, InputIterator last)
|
||||||
|
{
|
||||||
|
for (; middle != last; ++first) {
|
||||||
|
while (*first < *middle)
|
||||||
|
++ first;
|
||||||
|
reverse (first, middle);
|
||||||
|
reverse (first, ++middle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove_copy copies elements that are not equal to value from the range
|
||||||
|
/// [first, last) to a range beginning at result. The return value is the
|
||||||
|
/// end of the resulting range. This operation is stable, meaning that the
|
||||||
|
/// relative order of the elements that are copied is the same as in the
|
||||||
|
/// range [first, last).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator, typename T>
|
||||||
|
OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& value)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
if (!(*first == value)) {
|
||||||
|
*result = *first;
|
||||||
|
++ result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove_copy copies elements pointed to by iterators in [rfirst, rlast)
|
||||||
|
/// from the range [first, last) to a range beginning at result. The return
|
||||||
|
/// value is the end of the resulting range. This operation is stable, meaning
|
||||||
|
/// that the relative order of the elements that are copied is the same as in the
|
||||||
|
/// range [first, last). Range [rfirst, rlast) is assumed to be sorted.
|
||||||
|
/// This algorithm is a uSTL extension.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator, typename RInputIterator>
|
||||||
|
OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, RInputIterator rfirst, RInputIterator rlast)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
while (rfirst != rlast && *rfirst < first)
|
||||||
|
++ rfirst;
|
||||||
|
if (rfirst == rlast || first != *rfirst) {
|
||||||
|
*result = *first;
|
||||||
|
++ result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove removes from the range [first, last) all elements that are equal to
|
||||||
|
/// value. That is, remove returns an iterator new_last such that the range
|
||||||
|
/// [first, new_last) contains no elements equal to value. [1] The iterators
|
||||||
|
/// in the range [new_last, last) are all still dereferenceable, but the
|
||||||
|
/// elements that they point to are unspecified. Remove is stable, meaning
|
||||||
|
/// that the relative order of elements that are not equal to value is
|
||||||
|
/// unchanged.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename T>
|
||||||
|
inline ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& value)
|
||||||
|
{
|
||||||
|
return remove_copy (first, last, first, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unique_copy copies elements from the range [first, last) to a range
|
||||||
|
/// beginning with result, except that in a consecutive group of duplicate
|
||||||
|
/// elements only the first one is copied. The return value is the end of
|
||||||
|
/// the range to which the elements are copied. This behavior is similar
|
||||||
|
/// to the Unix filter uniq.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator>
|
||||||
|
OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
if (first != last) {
|
||||||
|
*result = *first;
|
||||||
|
while (++first != last)
|
||||||
|
if (!(*first == *result))
|
||||||
|
*++result = *first;
|
||||||
|
++ result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every time a consecutive group of duplicate elements appears in the range
|
||||||
|
/// [first, last), the algorithm unique removes all but the first element.
|
||||||
|
/// That is, unique returns an iterator new_last such that the range [first,
|
||||||
|
/// new_last) contains no two consecutive elements that are duplicates.
|
||||||
|
/// The iterators in the range [new_last, last) are all still dereferenceable,
|
||||||
|
/// but the elements that they point to are unspecified. Unique is stable,
|
||||||
|
/// meaning that the relative order of elements that are not removed is
|
||||||
|
/// unchanged.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline ForwardIterator unique (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
return unique_copy (first, last, first);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the furthermost iterator i in [first, last) such that,
|
||||||
|
/// for every iterator j in [first, i), *j < value
|
||||||
|
/// Assumes the range is sorted.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename LessThanComparable>
|
||||||
|
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
ForwardIterator mid;
|
||||||
|
while (first != last) {
|
||||||
|
mid = advance (first, size_t(distance (first,last)) / 2);
|
||||||
|
if (*mid < value)
|
||||||
|
first = mid + 1;
|
||||||
|
else
|
||||||
|
last = mid;
|
||||||
|
}
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs a binary search inside the sorted range.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename LessThanComparable>
|
||||||
|
inline bool binary_search (ForwardIterator first, ForwardIterator last, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
ForwardIterator found = lower_bound (first, last, value);
|
||||||
|
return found != last && !(value < *found);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the furthermost iterator i in [first,last) such that for
|
||||||
|
/// every iterator j in [first,i), value < *j is false.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename LessThanComparable>
|
||||||
|
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
ForwardIterator mid;
|
||||||
|
while (first != last) {
|
||||||
|
mid = advance (first, size_t(distance (first,last)) / 2);
|
||||||
|
if (value < *mid)
|
||||||
|
last = mid;
|
||||||
|
else
|
||||||
|
first = mid + 1;
|
||||||
|
}
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns pair<lower_bound,upper_bound>
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename LessThanComparable>
|
||||||
|
inline pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
pair<ForwardIterator,ForwardIterator> rv;
|
||||||
|
rv.second = rv.first = lower_bound (first, last, value);
|
||||||
|
while (rv.second != last && !(value < *(rv.second)))
|
||||||
|
++ rv.second;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Randomly permute the elements of the container.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
///
|
||||||
|
/*template <typename RandomAccessIterator>
|
||||||
|
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last)
|
||||||
|
{
|
||||||
|
for (; first != last; ++ first)
|
||||||
|
iter_swap (first, first + (rand() % distance (first, last)));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// \brief Generic compare function adaptor to pass to qsort
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <typename ConstPointer, typename Compare>
|
||||||
|
int qsort_adapter (const void* p1, const void* p2)
|
||||||
|
{
|
||||||
|
ConstPointer i1 = reinterpret_cast<ConstPointer>(p1);
|
||||||
|
ConstPointer i2 = reinterpret_cast<ConstPointer>(p2);
|
||||||
|
Compare comp;
|
||||||
|
return comp (*i1, *i2) ? -1 : (comp (*i2, *i1) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
/// \ingroup PredicateAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::const_pointer const_pointer;
|
||||||
|
qsort (first, distance (first, last), sizeof(value_type),
|
||||||
|
&qsort_adapter<const_pointer, Compare>);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator>
|
||||||
|
inline void sort (RandomAccessIterator first, RandomAccessIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
sort (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container preserving order of equal elements.
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
/// \ingroup PredicateAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void stable_sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
for (RandomAccessIterator j, i = first; ++i < last;) { // Insertion sort
|
||||||
|
for (j = i; j-- > first && comp(*i, *j);) ;
|
||||||
|
if (++j != i) rotate (j, i, i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator>
|
||||||
|
inline void stable_sort (RandomAccessIterator first, RandomAccessIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
stable_sort (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Searches for the first subsequence [first2,last2) in [first1,last1)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
template <typename ForwardIterator1, typename ForwardIterator2>
|
||||||
|
inline ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator1>::value_type value_type;
|
||||||
|
return search (first1, last1, first2, last2, equal_to<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Searches for the last subsequence [first2,last2) in [first1,last1)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
template <typename ForwardIterator1, typename ForwardIterator2>
|
||||||
|
inline ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator1>::value_type value_type;
|
||||||
|
return find_end (first1, last1, first2, last2, equal_to<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Searches for the first occurence of \p count \p values in [first, last)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
template <typename Iterator, typename T>
|
||||||
|
inline Iterator search_n (Iterator first, Iterator last, size_t count, const T& value)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<Iterator>::value_type value_type;
|
||||||
|
return search_n (first, last, count, value, equal_to<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Searches [first1,last1) for the first occurrence of an element from [first2,last2)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
template <typename InputIterator, typename ForwardIterator>
|
||||||
|
inline InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator>::value_type value_type;
|
||||||
|
return find_first_of (first1, last1, first2, last2, equal_to<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns true if [first2,last2) is a subset of [first1,last1)
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
/// \ingroup SetAlgorithms
|
||||||
|
template <typename InputIterator1, typename InputIterator2>
|
||||||
|
inline bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator1>::value_type value_type;
|
||||||
|
return includes (first1, last1, first2, last2, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Merges [first1,last1) with [first2,last2)
|
||||||
|
///
|
||||||
|
/// Result will contain every element that is in either set. If duplicate
|
||||||
|
/// elements are present, max(n,m) is placed in the result.
|
||||||
|
///
|
||||||
|
/// \ingroup SetAlgorithms
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||||
|
inline OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator1>::value_type value_type;
|
||||||
|
return set_union (first1, last1, first2, last2, result, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Creates a set containing elements shared by the given ranges.
|
||||||
|
/// \ingroup SetAlgorithms
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||||
|
inline OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator1>::value_type value_type;
|
||||||
|
return set_intersection (first1, last1, first2, last2, result, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Removes from [first1,last1) elements present in [first2,last2)
|
||||||
|
/// \ingroup SetAlgorithms
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||||
|
inline OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator1>::value_type value_type;
|
||||||
|
return set_difference (first1, last1, first2, last2, result, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Performs union of sets A-B and B-A.
|
||||||
|
/// \ingroup SetAlgorithms
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||||
|
inline OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator1>::value_type value_type;
|
||||||
|
return set_symmetric_difference (first1, last1, first2, last2, result, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns true if the given range is sorted.
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline bool is_sorted (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator>::value_type value_type;
|
||||||
|
return is_sorted (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Compares two given containers like strcmp compares strings.
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
template <typename InputIterator1, typename InputIterator2>
|
||||||
|
inline bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator1>::value_type value_type;
|
||||||
|
return lexicographical_compare (first1, last1, first2, last2, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Creates the next lexicographical permutation of [first,last).
|
||||||
|
/// Returns false if no further permutations can be created.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
template <typename BidirectionalIterator>
|
||||||
|
inline bool next_permutation (BidirectionalIterator first, BidirectionalIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;
|
||||||
|
return next_permutation (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Creates the previous lexicographical permutation of [first,last).
|
||||||
|
/// Returns false if no further permutations can be created.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
template <typename BidirectionalIterator>
|
||||||
|
inline bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;
|
||||||
|
return prev_permutation (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns \p v clamped to the given range
|
||||||
|
template <typename T, typename Compare>
|
||||||
|
inline T clamp (const T& v, const T& l, const T& h, Compare comp)
|
||||||
|
{ return comp(v, l) ? l : comp(h, v) ? h : v; }
|
||||||
|
template <typename T>
|
||||||
|
inline T clamp (const T& v, const T& l, const T& h)
|
||||||
|
{ return v < l ? l : (h < v ? h : v); }
|
||||||
|
|
||||||
|
/// Returns iterator to the max element in [first,last)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline ForwardIterator max_element (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator>::value_type value_type;
|
||||||
|
return max_element (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns iterator to the min element in [first,last)
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline ForwardIterator min_element (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator>::value_type value_type;
|
||||||
|
return min_element (first, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_CPP14
|
||||||
|
|
||||||
|
/// Returns min,max pair of the argument
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr auto minmax (const T& a, const T& b)
|
||||||
|
{ return a < b ? make_pair<const T&,const T&>(a,b) : make_pair<const T&,const T&>(b,a); }
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr auto minmax (T& a, T& b)
|
||||||
|
{ return a < b ? make_pair<T&,T&>(a,b) : make_pair<T&,T&>(b,a); }
|
||||||
|
template <typename T, typename Compare>
|
||||||
|
inline constexpr auto minmax (const T& a, const T& b, Compare comp)
|
||||||
|
{ return comp(a,b) ? make_pair<const T&,const T&>(a,b) : make_pair<const T&,const T&>(b,a); }
|
||||||
|
template <typename T> constexpr void minmax (T&& a, T&& b) = delete;
|
||||||
|
template <typename T, typename Compare> constexpr void minmax (const T& a, const T& b, Compare comp) = delete;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto minmax (std::initializer_list<T> l)
|
||||||
|
{
|
||||||
|
auto r = make_pair (*l.begin(),*l.begin());
|
||||||
|
for (auto& i : l) {
|
||||||
|
r.first = min (r.first, i);
|
||||||
|
r.second = max (r.second, i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template <typename T, typename Compare>
|
||||||
|
auto minmax (std::initializer_list<T> l, Compare comp)
|
||||||
|
{
|
||||||
|
auto r = make_pair (*l.begin(),*l.begin());
|
||||||
|
for (auto& i : l) {
|
||||||
|
if (comp(i, r.first))
|
||||||
|
r.first = i;
|
||||||
|
if (comp(r.second, i))
|
||||||
|
r.second = i;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
pair<ForwardIterator,ForwardIterator> minmax_element (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
pair<ForwardIterator,ForwardIterator> r = make_pair (first, first);
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
if (*first < *r.first)
|
||||||
|
r.first = first;
|
||||||
|
if (*r.second < *first)
|
||||||
|
r.second = first;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template <typename ForwardIterator, typename Compare>
|
||||||
|
pair<ForwardIterator,ForwardIterator> minmax_element (ForwardIterator first, ForwardIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
pair<ForwardIterator,ForwardIterator> r = make_pair (first, first);
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
if (comp (*first, *r.first))
|
||||||
|
r.first = first;
|
||||||
|
if (comp (*r.second, *first))
|
||||||
|
r.second = first;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Makes [first,middle) a part of the sorted array.
|
||||||
|
/// Contents of [middle,last) is undefined. This implementation just calls stable_sort.
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
template <typename RandomAccessIterator>
|
||||||
|
inline void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
partial_sort (first, middle, last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Puts \p nth element into its sorted position.
|
||||||
|
/// In this implementation, the entire array is sorted. I can't think of any
|
||||||
|
/// use for it where the time gained would be useful.
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator>
|
||||||
|
inline void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last)
|
||||||
|
{
|
||||||
|
partial_sort (first, nth, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Like partial_sort, but outputs to [result_first,result_last)
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
template <typename InputIterator, typename RandomAccessIterator>
|
||||||
|
inline RandomAccessIterator partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<InputIterator>::value_type value_type;
|
||||||
|
return partial_sort_copy (first, last, result_first, result_last, less<value_type>());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ustl
|
353
pwn/flipper/dist/common/include/ustl/ualgobase.h
vendored
Normal file
353
pwn/flipper/dist/common/include/ustl/ualgobase.h
vendored
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "uutility.h"
|
||||||
|
#include <kstring.h>
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr typename tm::RemoveReference<T>::Result&& move (T&& v) noexcept
|
||||||
|
{ return static_cast<typename tm::RemoveReference<T>::Result&&>(v); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T&& forward (typename tm::RemoveReference<T>::Result& v) noexcept
|
||||||
|
{ return static_cast<T&&>(v); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T&& forward (typename tm::RemoveReference<T>::Result&& v) noexcept
|
||||||
|
{ return static_cast<T&&>(v); }
|
||||||
|
|
||||||
|
#if HAVE_CPP14
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
T exchange (T& a, U&& b)
|
||||||
|
{
|
||||||
|
T t = move(a);
|
||||||
|
a = forward<U>(b);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr typename tm::RemoveReference<T>::Result& move (T& v) noexcept
|
||||||
|
{ return v; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr T& forward (typename tm::RemoveReference<T>::Result& v) noexcept
|
||||||
|
{ return v; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Assigns the contents of a to b and the contents of b to a.
|
||||||
|
/// This is used as a primitive operation by many other algorithms.
|
||||||
|
/// \ingroup SwapAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline void swap (T& a, T& b)
|
||||||
|
{
|
||||||
|
typename tm::RemoveReference<T>::Result t = move(a);
|
||||||
|
a = move(b);
|
||||||
|
b = move(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Equivalent to swap (*a, *b)
|
||||||
|
/// \ingroup SwapAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Iterator>
|
||||||
|
inline void iter_swap (Iterator a, Iterator b)
|
||||||
|
{
|
||||||
|
swap (*a, *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy copies elements from the range [first, last) to the range
|
||||||
|
/// [result, result + (last - first)). That is, it performs the assignments
|
||||||
|
/// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally,
|
||||||
|
/// for every integer n from 0 to last - first, copy performs the assignment
|
||||||
|
/// *(result + n) = *(first + n). Assignments are performed in forward order,
|
||||||
|
/// i.e. in order of increasing n.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
for (; first != last; ++result, ++first)
|
||||||
|
*result = *first;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy_n copies elements from the range [first, first + n) to the range
|
||||||
|
/// [result, result + n). That is, it performs the assignments
|
||||||
|
/// *result = *first, *(result + 1) = *(first + 1), and so on. Generally,
|
||||||
|
/// for every integer i from 0 up to (but not including) n, copy_n performs
|
||||||
|
/// the assignment *(result + i) = *(first + i). Assignments are performed
|
||||||
|
/// in forward order, i.e. in order of increasing n.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator copy_n (InputIterator first, size_t count, OutputIterator result)
|
||||||
|
{
|
||||||
|
for (; count; --count, ++result, ++first)
|
||||||
|
*result = *first;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Copy copies elements from the range (last, first] to result.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
/// Copies elements starting at last, decrementing both last and result.
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator copy_backward (InputIterator first, InputIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
while (first != last)
|
||||||
|
*--result = *--last;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For_each applies the function object f to each element in the range
|
||||||
|
/// [first, last); f's return value, if any, is ignored. Applications are
|
||||||
|
/// performed in forward order, i.e. from first to last. For_each returns
|
||||||
|
/// the function object after it has been applied to each element.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename UnaryFunction>
|
||||||
|
inline UnaryFunction for_each (InputIterator first, InputIterator last, UnaryFunction f)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first)
|
||||||
|
f (*first);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill assigns the value value to every element in the range [first, last).
|
||||||
|
/// That is, for every iterator i in [first, last),
|
||||||
|
/// it performs the assignment *i = value.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename T>
|
||||||
|
inline void fill (ForwardIterator first, ForwardIterator last, const T& value)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first)
|
||||||
|
*first = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill_n assigns the value value to every element in the range
|
||||||
|
/// [first, first+count). That is, for every iterator i in [first, first+count),
|
||||||
|
/// it performs the assignment *i = value. The return value is first + count.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
///
|
||||||
|
template <typename OutputIterator, typename T>
|
||||||
|
inline OutputIterator fill_n (OutputIterator first, size_t count, const T& value)
|
||||||
|
{
|
||||||
|
for (; count; --count, ++first)
|
||||||
|
*first = value;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __MMX__
|
||||||
|
extern "C" void copy_n_fast (const void* src, size_t count, void* dest) noexcept;
|
||||||
|
#else
|
||||||
|
inline void copy_n_fast (const void* src, size_t count, void* dest) noexcept
|
||||||
|
{ memmove (dest, src, count); }
|
||||||
|
#endif
|
||||||
|
#if __x86__
|
||||||
|
extern "C" void copy_backward_fast (const void* first, const void* last, void* result) noexcept;
|
||||||
|
#else
|
||||||
|
inline void copy_backward_fast (const void* first, const void* last, void* result) noexcept
|
||||||
|
{
|
||||||
|
const size_t nBytes (distance (first, last));
|
||||||
|
memmove (advance (result, -nBytes), first, nBytes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
extern "C" void fill_n8_fast (uint8_t* dest, size_t count, uint8_t v) noexcept;
|
||||||
|
extern "C" void fill_n16_fast (uint16_t* dest, size_t count, uint16_t v) noexcept;
|
||||||
|
extern "C" void fill_n32_fast (uint32_t* dest, size_t count, uint32_t v) noexcept;
|
||||||
|
extern "C" void rotate_fast (void* first, void* middle, void* last) noexcept;
|
||||||
|
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
/// \brief Computes the number of 1 bits in a number.
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
inline size_t popcount (uint32_t v) { return __builtin_popcount (v); }
|
||||||
|
#if HAVE_INT64_T
|
||||||
|
inline size_t popcount (uint64_t v) { return __builtin_popcountll (v); }
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
size_t popcount (uint32_t v) noexcept;
|
||||||
|
#if HAVE_INT64_T
|
||||||
|
size_t popcount (uint64_t v) noexcept;
|
||||||
|
#endif // HAVE_INT64_T
|
||||||
|
#endif // __GNUC__
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Optimized versions for standard types
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if WANT_UNROLLED_COPY
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* unrolled_copy (const T* first, size_t count, T* result)
|
||||||
|
{
|
||||||
|
copy_n_fast (first, count * sizeof(T), result);
|
||||||
|
return advance (result, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline uint8_t* copy_backward (const uint8_t* first, const uint8_t* last, uint8_t* result)
|
||||||
|
{
|
||||||
|
copy_backward_fast (first, last, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* unrolled_fill (T* result, size_t count, T value)
|
||||||
|
{
|
||||||
|
for (; count; --count, ++result)
|
||||||
|
*result = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
template <> inline uint8_t* unrolled_fill (uint8_t* result, size_t count, uint8_t value)
|
||||||
|
{ fill_n8_fast (result, count, value); return advance (result, count); }
|
||||||
|
template <> inline uint16_t* unrolled_fill (uint16_t* result, size_t count, uint16_t value)
|
||||||
|
{ fill_n16_fast (result, count, value); return advance (result, count); }
|
||||||
|
template <> inline uint32_t* unrolled_fill (uint32_t* result, size_t count, uint32_t value)
|
||||||
|
{ fill_n32_fast (result, count, value); return advance (result, count); }
|
||||||
|
/*template <> inline float* unrolled_fill (float* result, size_t count, float value)
|
||||||
|
{ fill_n32_fast (reinterpret_cast<uint32_t*>(result), count, *noalias_cast<uint32_t*>(&value)); return advance (result, count); }*/
|
||||||
|
|
||||||
|
#if __MMX__
|
||||||
|
#define UNROLLED_COPY_SPECIALIZATION(type) \
|
||||||
|
template <> inline type* copy (const type* first, const type* last, type* result) \
|
||||||
|
{ return unrolled_copy (first, distance (first, last), result); } \
|
||||||
|
template <> inline type* copy_n (const type* first, size_t count, type* result) \
|
||||||
|
{ return unrolled_copy (first, count, result); }
|
||||||
|
#define UNROLLED_FILL_SPECIALIZATION(type) \
|
||||||
|
template <> inline void fill (type* first, type* last, const type& value) \
|
||||||
|
{ unrolled_fill (first, distance (first, last), value); } \
|
||||||
|
template <> inline type* fill_n (type* first, size_t count, const type& value) \
|
||||||
|
{ return unrolled_fill (first, count, value); }
|
||||||
|
UNROLLED_COPY_SPECIALIZATION(uint8_t)
|
||||||
|
UNROLLED_FILL_SPECIALIZATION(uint8_t)
|
||||||
|
UNROLLED_COPY_SPECIALIZATION(uint16_t)
|
||||||
|
UNROLLED_FILL_SPECIALIZATION(uint16_t)
|
||||||
|
UNROLLED_COPY_SPECIALIZATION(uint32_t)
|
||||||
|
UNROLLED_FILL_SPECIALIZATION(uint32_t)
|
||||||
|
UNROLLED_COPY_SPECIALIZATION(float)
|
||||||
|
UNROLLED_FILL_SPECIALIZATION(float)
|
||||||
|
#undef UNROLLED_FILL_SPECIALIZATION
|
||||||
|
#undef UNROLLED_COPY_SPECIALIZATION
|
||||||
|
#endif // WANT_UNROLLED_COPY
|
||||||
|
#endif // __MMX__
|
||||||
|
|
||||||
|
// Specializations for void* and char*, aliasing the above optimized versions.
|
||||||
|
//
|
||||||
|
// All these need duplication with const and non-const arguments, since
|
||||||
|
// otherwise the compiler will default to the unoptimized version for
|
||||||
|
// pointers not const in the caller's context, such as local variables.
|
||||||
|
// These are all inline, but they sure slow down compilation... :(
|
||||||
|
//
|
||||||
|
#define COPY_ALIAS_FUNC(ctype, type, alias_type) \
|
||||||
|
template <> inline type* copy (ctype* first, ctype* last, type* result) \
|
||||||
|
{ return reinterpret_cast<type*> (copy (reinterpret_cast<const alias_type*>(first), reinterpret_cast<const alias_type*>(last), reinterpret_cast<alias_type*>(result))); }
|
||||||
|
#if WANT_UNROLLED_COPY
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
COPY_ALIAS_FUNC(const char, char, uint8_t)
|
||||||
|
COPY_ALIAS_FUNC(char, char, uint8_t)
|
||||||
|
#endif
|
||||||
|
COPY_ALIAS_FUNC(const int8_t, int8_t, uint8_t)
|
||||||
|
COPY_ALIAS_FUNC(int8_t, int8_t, uint8_t)
|
||||||
|
COPY_ALIAS_FUNC(uint8_t, uint8_t, uint8_t)
|
||||||
|
COPY_ALIAS_FUNC(const int16_t, int16_t, uint16_t)
|
||||||
|
COPY_ALIAS_FUNC(int16_t, int16_t, uint16_t)
|
||||||
|
COPY_ALIAS_FUNC(uint16_t, uint16_t, uint16_t)
|
||||||
|
#if __MMX__ || (SIZE_OF_LONG > 4)
|
||||||
|
COPY_ALIAS_FUNC(const int32_t, int32_t, uint32_t)
|
||||||
|
COPY_ALIAS_FUNC(int32_t, int32_t, uint32_t)
|
||||||
|
COPY_ALIAS_FUNC(uint32_t, uint32_t, uint32_t)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
COPY_ALIAS_FUNC(const void, void, uint8_t)
|
||||||
|
COPY_ALIAS_FUNC(void, void, uint8_t)
|
||||||
|
#undef COPY_ALIAS_FUNC
|
||||||
|
#define COPY_BACKWARD_ALIAS_FUNC(ctype, type, alias_type) \
|
||||||
|
template <> inline type* copy_backward (ctype* first, ctype* last, type* result) \
|
||||||
|
{ return reinterpret_cast<type*> (copy_backward (reinterpret_cast<const alias_type*>(first), reinterpret_cast<const alias_type*>(last), reinterpret_cast<alias_type*>(result))); }
|
||||||
|
#if WANT_UNROLLED_COPY
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(char, char, uint8_t)
|
||||||
|
#endif
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(uint8_t, uint8_t, uint8_t)
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(int8_t, int8_t, uint8_t)
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(uint16_t, uint16_t, uint8_t)
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(const uint16_t, uint16_t, uint8_t)
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(int16_t, int16_t, uint8_t)
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(const int16_t, int16_t, uint8_t)
|
||||||
|
#endif
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(void, void, uint8_t)
|
||||||
|
COPY_BACKWARD_ALIAS_FUNC(const void, void, uint8_t)
|
||||||
|
#undef COPY_BACKWARD_ALIAS_FUNC
|
||||||
|
#define FILL_ALIAS_FUNC(type, alias_type, v_type) \
|
||||||
|
template <> inline void fill (type* first, type* last, const v_type& value) \
|
||||||
|
{ fill (reinterpret_cast<alias_type*>(first), reinterpret_cast<alias_type*>(last), alias_type(value)); }
|
||||||
|
FILL_ALIAS_FUNC(void, uint8_t, char)
|
||||||
|
FILL_ALIAS_FUNC(void, uint8_t, uint8_t)
|
||||||
|
#if WANT_UNROLLED_COPY
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
FILL_ALIAS_FUNC(char, uint8_t, char)
|
||||||
|
FILL_ALIAS_FUNC(char, uint8_t, uint8_t)
|
||||||
|
#endif
|
||||||
|
FILL_ALIAS_FUNC(int8_t, uint8_t, int8_t)
|
||||||
|
FILL_ALIAS_FUNC(int16_t, uint16_t, int16_t)
|
||||||
|
#if __MMX__ || (SIZE_OF_LONG > 4)
|
||||||
|
FILL_ALIAS_FUNC(int32_t, uint32_t, int32_t)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#undef FILL_ALIAS_FUNC
|
||||||
|
#define COPY_N_ALIAS_FUNC(ctype, type, alias_type) \
|
||||||
|
template <> inline type* copy_n (ctype* first, size_t count, type* result) \
|
||||||
|
{ return reinterpret_cast<type*> (copy_n (reinterpret_cast<const alias_type*>(first), count, reinterpret_cast<alias_type*>(result))); }
|
||||||
|
COPY_N_ALIAS_FUNC(const void, void, uint8_t)
|
||||||
|
COPY_N_ALIAS_FUNC(void, void, uint8_t)
|
||||||
|
#if WANT_UNROLLED_COPY
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
COPY_N_ALIAS_FUNC(const char, char, uint8_t)
|
||||||
|
COPY_N_ALIAS_FUNC(char, char, uint8_t)
|
||||||
|
#endif
|
||||||
|
COPY_N_ALIAS_FUNC(int8_t, int8_t, uint8_t)
|
||||||
|
COPY_N_ALIAS_FUNC(uint8_t, uint8_t, uint8_t)
|
||||||
|
COPY_N_ALIAS_FUNC(const int8_t, int8_t, uint8_t)
|
||||||
|
COPY_N_ALIAS_FUNC(int16_t, int16_t, uint16_t)
|
||||||
|
COPY_N_ALIAS_FUNC(uint16_t, uint16_t, uint16_t)
|
||||||
|
COPY_N_ALIAS_FUNC(const int16_t, int16_t, uint16_t)
|
||||||
|
#if __MMX__ || (SIZE_OF_LONG > 4)
|
||||||
|
COPY_N_ALIAS_FUNC(int32_t, int32_t, uint32_t)
|
||||||
|
COPY_N_ALIAS_FUNC(uint32_t, uint32_t, uint32_t)
|
||||||
|
COPY_N_ALIAS_FUNC(const int32_t, int32_t, uint32_t)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#undef COPY_N_ALIAS_FUNC
|
||||||
|
#define FILL_N_ALIAS_FUNC(type, alias_type, v_type) \
|
||||||
|
template <> inline type* fill_n (type* first, size_t n, const v_type& value) \
|
||||||
|
{ return reinterpret_cast<type*> (fill_n (reinterpret_cast<alias_type*>(first), n, alias_type(value))); }
|
||||||
|
FILL_N_ALIAS_FUNC(void, uint8_t, char)
|
||||||
|
FILL_N_ALIAS_FUNC(void, uint8_t, uint8_t)
|
||||||
|
#if WANT_UNROLLED_COPY
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
FILL_N_ALIAS_FUNC(char, uint8_t, char)
|
||||||
|
FILL_N_ALIAS_FUNC(char, uint8_t, uint8_t)
|
||||||
|
#endif
|
||||||
|
FILL_N_ALIAS_FUNC(int8_t, uint8_t, int8_t)
|
||||||
|
FILL_N_ALIAS_FUNC(int16_t, uint16_t, int16_t)
|
||||||
|
#if __MMX__ || (SIZE_OF_LONG > 4)
|
||||||
|
FILL_N_ALIAS_FUNC(int32_t, uint32_t, int32_t)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#undef FILL_N_ALIAS_FUNC
|
||||||
|
|
||||||
|
extern const char _FmtPrtChr[2][8];
|
||||||
|
|
||||||
|
} // namespace ustl
|
115
pwn/flipper/dist/common/include/ustl/uatomic.h
vendored
Normal file
115
pwn/flipper/dist/common/include/ustl/uatomic.h
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2016 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "utypes.h"
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
//{{{ memory_order -----------------------------------------------------
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
enum memory_order {
|
||||||
|
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||||
|
memory_order_consume = __ATOMIC_CONSUME,
|
||||||
|
memory_order_acquire = __ATOMIC_ACQUIRE,
|
||||||
|
memory_order_release = __ATOMIC_RELEASE,
|
||||||
|
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||||
|
memory_order_seq_cst = __ATOMIC_SEQ_CST
|
||||||
|
};
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ atomic
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class atomic {
|
||||||
|
T _v;
|
||||||
|
public:
|
||||||
|
atomic (void) = default;
|
||||||
|
inline constexpr atomic (T v) : _v(v) {}
|
||||||
|
atomic (const atomic&) = delete;
|
||||||
|
atomic& operator= (const atomic&) = delete;
|
||||||
|
inline bool is_lock_free (void) const
|
||||||
|
{ return __atomic_is_lock_free (sizeof(T), &_v); }
|
||||||
|
inline void store (T v, memory_order order = memory_order_seq_cst)
|
||||||
|
{ __atomic_store_n (&_v, v, order); }
|
||||||
|
inline T load (memory_order order = memory_order_seq_cst) const
|
||||||
|
{ return __atomic_load_n (&_v, order); }
|
||||||
|
inline T exchange (T v, memory_order order = memory_order_seq_cst)
|
||||||
|
{ return __atomic_exchange_n (&_v, v, order); }
|
||||||
|
inline bool compare_exchange_weak (T& expected, T desired, memory_order order = memory_order_seq_cst)
|
||||||
|
{ return __atomic_compare_exchange_n (&_v, &expected, desired, true, order, order); }
|
||||||
|
inline bool compare_exchange_weak (T& expected, T desired, memory_order success, memory_order failure)
|
||||||
|
{ return __atomic_compare_exchange_n (&_v, &expected, desired, true, success, failure); }
|
||||||
|
inline bool compare_exchange_strong (T& expected, T desired, memory_order success, memory_order failure)
|
||||||
|
{ return __atomic_compare_exchange_n (&_v, &expected, desired, false, success, failure); }
|
||||||
|
inline T fetch_add (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_fetch_add (&_v, v, order); }
|
||||||
|
inline T fetch_sub (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_fetch_sub (&_v, v, order); }
|
||||||
|
inline T fetch_and (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_fetch_and (&_v, v, order); }
|
||||||
|
inline T fetch_or (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_fetch_or (&_v, v, order); }
|
||||||
|
inline T fetch_xor (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_fetch_xor (&_v, v, order); }
|
||||||
|
inline T add_fetch (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_add_fetch (&_v, v, order); }
|
||||||
|
inline T sub_fetch (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_sub_fetch (&_v, v, order); }
|
||||||
|
inline T and_fetch (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_and_fetch (&_v, v, order); }
|
||||||
|
inline T or_fetch (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_or_fetch (&_v, v, order); }
|
||||||
|
inline T xor_fetch (T v, memory_order order = memory_order_seq_cst )
|
||||||
|
{ return __atomic_xor_fetch (&_v, v, order); }
|
||||||
|
inline operator T (void) const { return load(); }
|
||||||
|
inline T operator= (T v) { store(v); return v; }
|
||||||
|
inline T operator++ (int) { return fetch_add (1); }
|
||||||
|
inline T operator-- (int) { return fetch_sub (1); }
|
||||||
|
inline T operator++ (void) { return add_fetch (1); }
|
||||||
|
inline T operator-- (void) { return sub_fetch (1); }
|
||||||
|
inline T operator+= (T v) { return add_fetch (v); }
|
||||||
|
inline T operator-= (T v) { return sub_fetch (v); }
|
||||||
|
inline T operator&= (T v) { return and_fetch (v); }
|
||||||
|
inline T operator|= (T v) { return or_fetch (v); }
|
||||||
|
inline T operator^= (T v) { return xor_fetch (v); }
|
||||||
|
};
|
||||||
|
#define ATOMIC_VAR_INIT {0}
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ atomic_flag
|
||||||
|
|
||||||
|
class atomic_flag {
|
||||||
|
bool _v;
|
||||||
|
public:
|
||||||
|
atomic_flag (void) = default;
|
||||||
|
inline constexpr atomic_flag (bool v) : _v(v) {}
|
||||||
|
atomic_flag (const atomic_flag&) = delete;
|
||||||
|
atomic_flag& operator= (const atomic_flag&) = delete;
|
||||||
|
void clear (memory_order order = memory_order_seq_cst)
|
||||||
|
{ __atomic_clear (&_v, order); }
|
||||||
|
bool test_and_set (memory_order order = memory_order_seq_cst)
|
||||||
|
{ return __atomic_test_and_set (&_v, order); }
|
||||||
|
};
|
||||||
|
#define ATOMIC_FLAG_INIT {false}
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ fence functions
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline T kill_dependency (T v) noexcept
|
||||||
|
{ T r (v); return r; }
|
||||||
|
static inline void atomic_thread_fence (memory_order order) noexcept
|
||||||
|
{ __atomic_thread_fence (order); }
|
||||||
|
static inline void atomic_signal_fence (memory_order order) noexcept
|
||||||
|
{ __atomic_signal_fence (order); }
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace ustl
|
||||||
|
#endif // HAVE_CPP11
|
||||||
|
//}}}-------------------------------------------------------------------
|
129
pwn/flipper/dist/common/include/ustl/ubitset.h
vendored
Normal file
129
pwn/flipper/dist/common/include/ustl/ubitset.h
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ustring.h"
|
||||||
|
#include "ufunction.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class istringstream;
|
||||||
|
|
||||||
|
typedef uint32_t bitset_value_type;
|
||||||
|
|
||||||
|
void convert_to_bitstring (const bitset_value_type* v, size_t n, string& buf) noexcept;
|
||||||
|
void convert_from_bitstring (const string& buf, bitset_value_type* v, size_t n) noexcept;
|
||||||
|
|
||||||
|
/// \class bitset ubitset.h ustl.h
|
||||||
|
/// \ingroup Sequences
|
||||||
|
///
|
||||||
|
/// \brief bitset is a fixed-size block of memory with addressable bits.
|
||||||
|
///
|
||||||
|
/// Normally used for state flags; allows setting and unsetting of individual
|
||||||
|
/// bits as well as bitwise operations on the entire set. The interface is
|
||||||
|
/// most like that of unsigned integers, and is intended to be used as such.
|
||||||
|
/// If you were using begin() and end() functions in STL's bitset, you would
|
||||||
|
/// not be able to do the same thing here, because those functions return
|
||||||
|
/// host type iterators, not bits.
|
||||||
|
///
|
||||||
|
template <size_t Size>
|
||||||
|
class bitset {
|
||||||
|
public:
|
||||||
|
typedef bitset_value_type value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef const value_type* const_pointer;
|
||||||
|
typedef pointer iterator;
|
||||||
|
typedef const_pointer const_iterator;
|
||||||
|
typedef size_t difference_type;
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef const bitset<Size>& rcself_t;
|
||||||
|
private:
|
||||||
|
static const size_t s_WordBits = BitsInType (value_type);
|
||||||
|
static const size_t s_nWords = Size / s_WordBits + ((Size % s_WordBits) != 0);
|
||||||
|
static const size_t s_nBits = s_nWords * s_WordBits;
|
||||||
|
private:
|
||||||
|
inline value_type& BitRef (uoff_t n) { assert (n < Size); return _bits [n / s_WordBits]; }
|
||||||
|
inline value_type BitRef (uoff_t n) const { assert (n < Size); return _bits [n / s_WordBits]; }
|
||||||
|
inline value_type Mask (uoff_t n) const { assert (n < Size); return 1 << (n % s_WordBits); }
|
||||||
|
public:
|
||||||
|
inline bitset (value_type v = 0) { fill_n (_bits, s_nWords, 0); _bits[0] = v; }
|
||||||
|
inline bitset (const string& buf) { convert_from_bitstring (buf, _bits, s_nWords); }
|
||||||
|
inline void flip (uoff_t n) { BitRef(n) ^= Mask(n); }
|
||||||
|
inline void reset (void) { fill_n (_bits, s_nWords, 0); }
|
||||||
|
inline void clear (void) { fill_n (_bits, s_nWords, 0); }
|
||||||
|
inline void set (void) { fill_n (_bits, s_nWords, -1); }
|
||||||
|
inline bitset operator~ (void) const { bitset rv (*this); rv.flip(); return rv; }
|
||||||
|
inline size_type size (void) const { return Size; }
|
||||||
|
inline size_type capacity (void) const { return s_nBits; }
|
||||||
|
inline bool test (uoff_t n) const { return BitRef(n) & Mask(n); }
|
||||||
|
inline bool operator[] (uoff_t n) const { return test(n); }
|
||||||
|
inline const_iterator begin (void) const { return _bits; }
|
||||||
|
inline iterator begin (void) { return _bits; }
|
||||||
|
inline const_iterator end (void) const { return _bits + s_nWords; }
|
||||||
|
inline iterator end (void) { return _bits + s_nWords; }
|
||||||
|
/// Returns the value_type with the equivalent bits. If size() > 1, you'll get only the first BitsInType(value_type) bits.
|
||||||
|
inline value_type to_value (void) const { return _bits[0]; }
|
||||||
|
/// Flips all the bits in the set.
|
||||||
|
inline void flip (void) { transform (begin(), end(), begin(), bitwise_not<value_type>()); }
|
||||||
|
/// Sets or clears bit \p n.
|
||||||
|
inline void set (uoff_t n, bool val = true)
|
||||||
|
{
|
||||||
|
value_type& br (BitRef (n));
|
||||||
|
const value_type mask (Mask (n));
|
||||||
|
const value_type bOn (br | mask), bOff (br & ~mask);
|
||||||
|
br = val ? bOn : bOff;
|
||||||
|
}
|
||||||
|
// Sets the value of the bitrange \p first through \p last to the equivalent number of bits from \p v.
|
||||||
|
inline void set (uoff_t first, uoff_t DebugArg(last), value_type v)
|
||||||
|
{
|
||||||
|
assert (size_t (distance (first, last)) <= s_WordBits && "Bit ranges must be 32 bits or smaller");
|
||||||
|
assert (first / s_WordBits == last / s_WordBits && "Bit ranges can not cross dword (4 byte) boundary");
|
||||||
|
assert ((v & BitMask(value_type,distance(first,last))) == v && "The value is too large to fit in the given bit range");
|
||||||
|
BitRef(first) |= v << (first % s_WordBits);
|
||||||
|
}
|
||||||
|
/// Clears the bit \p n.
|
||||||
|
inline void reset (uoff_t n) { set (n, false); }
|
||||||
|
/// Returns a string with bits MSB "001101001..." LSB.
|
||||||
|
inline string to_string (void) const
|
||||||
|
{
|
||||||
|
string rv (Size, '0');
|
||||||
|
convert_to_bitstring (_bits, s_nWords, rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
inline value_type at (uoff_t n) const { return test(n); }
|
||||||
|
/// Returns the value in bits \p first through \p last.
|
||||||
|
inline value_type at (uoff_t first, uoff_t last) const
|
||||||
|
{
|
||||||
|
assert (size_t (distance (first, last)) <= s_WordBits && "Bit ranges must be 32 bits or smaller");
|
||||||
|
assert (first / s_WordBits == last / s_WordBits && "Bit ranges can not cross dword (4 byte) boundary");
|
||||||
|
return (BitRef(first) >> (first % s_WordBits)) & BitMask(value_type,distance(first, last));
|
||||||
|
}
|
||||||
|
inline bool any (void) const { value_type sum = 0; foreach (const_iterator, i, *this) sum |= *i; return sum; }
|
||||||
|
inline bool none (void) const { return !any(); }
|
||||||
|
inline size_t count (void) const { size_t sum = 0; foreach (const_iterator, i, *this) sum += popcount(*i); return sum; }
|
||||||
|
inline bool operator== (rcself_t v) const
|
||||||
|
{ return s_nWords == 1 ? (_bits[0] == v._bits[0]) : equal (begin(), end(), v.begin()); }
|
||||||
|
inline bitset operator& (rcself_t v) const
|
||||||
|
{ bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_and<value_type>()); return result; }
|
||||||
|
inline bitset operator| (rcself_t v) const
|
||||||
|
{ bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_or<value_type>()); return result; }
|
||||||
|
inline bitset operator^ (rcself_t v) const
|
||||||
|
{ bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_xor<value_type>()); return result; }
|
||||||
|
inline rcself_t operator&= (rcself_t v)
|
||||||
|
{ transform (begin(), end(), v.begin(), begin(), bitwise_and<value_type>()); return *this; }
|
||||||
|
inline rcself_t operator|= (rcself_t v)
|
||||||
|
{ transform (begin(), end(), v.begin(), begin(), bitwise_or<value_type>()); return *this; }
|
||||||
|
inline rcself_t operator^= (rcself_t v)
|
||||||
|
{ transform (begin(), end(), v.begin(), begin(), bitwise_xor<value_type>()); return *this; }
|
||||||
|
inline void read (istream& is) { nr_container_read (is, *this); }
|
||||||
|
inline void write (ostream& os) const { nr_container_write (os, *this); }
|
||||||
|
inline void text_write (ostringstream& os) const { os << to_string(); }
|
||||||
|
void text_read (istringstream& is);
|
||||||
|
inline size_t stream_size (void) const { return sizeof(_bits); }
|
||||||
|
private:
|
||||||
|
value_type _bits [s_nWords];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
467
pwn/flipper/dist/common/include/ustl/uctralgo.h
vendored
Normal file
467
pwn/flipper/dist/common/include/ustl/uctralgo.h
vendored
Normal file
@ -0,0 +1,467 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// Copy copies elements from the range [first, last) to the range
|
||||||
|
/// [result, result + (last - first)). That is, it performs the assignments
|
||||||
|
/// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally,
|
||||||
|
/// for every integer n from 0 to last - first, copy performs the assignment
|
||||||
|
/// *(result + n) = *(first + n). Assignments are performed in forward order,
|
||||||
|
/// i.e. in order of increasing n.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator>
|
||||||
|
inline OutputIterator copy (const Container& ctr, OutputIterator result)
|
||||||
|
{
|
||||||
|
return copy (ctr.begin(), ctr.end(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy_if copies elements from the range [first, last) to the range
|
||||||
|
/// [result, result + (last - first)) if pred(*i) returns true.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator, typename Predicate>
|
||||||
|
inline OutputIterator copy_if (Container& ctr, OutputIterator result, Predicate pred)
|
||||||
|
{
|
||||||
|
return copy_if (ctr.begin(), ctr.end(), result, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For_each applies the function object f to each element in the range
|
||||||
|
/// [first, last); f's return value, if any, is ignored. Applications are
|
||||||
|
/// performed in forward order, i.e. from first to last. For_each returns
|
||||||
|
/// the function object after it has been applied to each element.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename UnaryFunction>
|
||||||
|
inline UnaryFunction for_each (Container& ctr, UnaryFunction f)
|
||||||
|
{
|
||||||
|
return for_each (ctr.begin(), ctr.end(), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For_each applies the function object f to each element in the range
|
||||||
|
/// [first, last); f's return value, if any, is ignored. Applications are
|
||||||
|
/// performed in forward order, i.e. from first to last. For_each returns
|
||||||
|
/// the function object after it has been applied to each element.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename UnaryFunction>
|
||||||
|
inline UnaryFunction for_each (const Container& ctr, UnaryFunction f)
|
||||||
|
{
|
||||||
|
return for_each (ctr.begin(), ctr.end(), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the first iterator i in the range [first, last) such that
|
||||||
|
/// *i == value. Returns last if no such iterator exists.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename EqualityComparable>
|
||||||
|
inline typename Container::const_iterator find (const Container& ctr, const EqualityComparable& value)
|
||||||
|
{
|
||||||
|
return find (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
template <typename Container, typename EqualityComparable>
|
||||||
|
inline typename Container::iterator find (Container& ctr, const EqualityComparable& value)
|
||||||
|
{
|
||||||
|
return find (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the first iterator i in the range [first, last) such that
|
||||||
|
/// pred(*i) is true. Returns last if no such iterator exists.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Predicate>
|
||||||
|
inline typename Container::const_iterator find_if (const Container& ctr, Predicate pred)
|
||||||
|
{
|
||||||
|
return find_if (ctr.begin(), ctr.end(), pred);
|
||||||
|
}
|
||||||
|
template <typename Container, typename Predicate>
|
||||||
|
inline typename Container::iterator find_if (Container& ctr, Predicate pred)
|
||||||
|
{
|
||||||
|
return find_if (ctr.begin(), ctr.end(), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count finds the number of elements in [first, last) that are equal
|
||||||
|
/// to value. More precisely, the first version of count returns the
|
||||||
|
/// number of iterators i in [first, last) such that *i == value.
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename EqualityComparable>
|
||||||
|
inline size_t count (const Container& ctr, const EqualityComparable& value)
|
||||||
|
{
|
||||||
|
return count (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count_if finds the number of elements in [first, last) that satisfy the
|
||||||
|
/// predicate pred. More precisely, the first version of count_if returns the
|
||||||
|
/// number of iterators i in [first, last) such that pred(*i) is true.
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Predicate>
|
||||||
|
inline size_t count_if (const Container& ctr, Predicate pred)
|
||||||
|
{
|
||||||
|
return count_if (ctr.begin(), ctr.end(), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The first version of transform performs the operation op(*i) for each
|
||||||
|
/// iterator i in the range [first, last), and assigns the result of that
|
||||||
|
/// operation to *o, where o is the corresponding output iterator. That is,
|
||||||
|
/// for each n such that 0 <= n < last - first, it performs the assignment
|
||||||
|
/// *(result + n) = op(*(first + n)).
|
||||||
|
/// The return value is result + (last - first).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename UnaryFunction>
|
||||||
|
inline void transform (Container& ctr, UnaryFunction op)
|
||||||
|
{
|
||||||
|
transform (ctr.begin(), ctr.end(), ctr.begin(), op);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The first version of transform performs the operation op(*i) for each
|
||||||
|
/// iterator i in the range [first, last), and assigns the result of that
|
||||||
|
/// operation to *o, where o is the corresponding output iterator. That is,
|
||||||
|
/// for each n such that 0 <= n < last - first, it performs the assignment
|
||||||
|
/// *(result + n) = op(*(first + n)).
|
||||||
|
/// The return value is result + (last - first).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator, typename UnaryFunction>
|
||||||
|
inline OutputIterator transform (Container& ctr, OutputIterator result, UnaryFunction op)
|
||||||
|
{
|
||||||
|
return transform (ctr.begin(), ctr.end(), result, op);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The second version of transform is very similar, except that it uses a
|
||||||
|
/// Binary Function instead of a Unary Function: it performs the operation
|
||||||
|
/// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns
|
||||||
|
/// the result to *o, where i2 is the corresponding iterator in the second
|
||||||
|
/// input range and where o is the corresponding output iterator. That is,
|
||||||
|
/// for each n such that 0 <= n < last1 - first1, it performs the assignment
|
||||||
|
/// *(result + n) = op(*(first1 + n), *(first2 + n).
|
||||||
|
/// The return value is result + (last1 - first1).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename InputIterator, typename OutputIterator, typename BinaryFunction>
|
||||||
|
inline OutputIterator transform (Container& ctr, InputIterator first, OutputIterator result, BinaryFunction op)
|
||||||
|
{
|
||||||
|
return transform (ctr.begin(), ctr.end(), first, result, op);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace replaces every element in the range [first, last) equal to
|
||||||
|
/// old_value with new_value. That is: for every iterator i,
|
||||||
|
/// if *i == old_value then it performs the assignment *i = new_value.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename T>
|
||||||
|
inline void replace (Container& ctr, const T& old_value, const T& new_value)
|
||||||
|
{
|
||||||
|
replace (ctr.begin(), ctr.end(), old_value, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace_if replaces every element in the range [first, last) for which
|
||||||
|
/// pred returns true with new_value. That is: for every iterator i, if
|
||||||
|
/// pred(*i) is true then it performs the assignment *i = new_value.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Predicate, typename T>
|
||||||
|
inline void replace_if (Container& ctr, Predicate pred, const T& new_value)
|
||||||
|
{
|
||||||
|
replace_if (ctr.begin(), ctr.end(), pred, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace_copy copies elements from the range [first, last) to the range
|
||||||
|
/// [result, result + (last-first)), except that any element equal to old_value
|
||||||
|
/// is not copied; new_value is copied instead. More precisely, for every
|
||||||
|
/// integer n such that 0 <= n < last-first, replace_copy performs the
|
||||||
|
/// assignment *(result+n) = new_value if *(first+n) == old_value, and
|
||||||
|
/// *(result+n) = *(first+n) otherwise.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator, typename T>
|
||||||
|
inline OutputIterator replace_copy (const Container& ctr, OutputIterator result, const T& old_value, const T& new_value)
|
||||||
|
{
|
||||||
|
return replace_copy (ctr.begin(), ctr.end(), result, old_value, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace_copy_if copies elements from the range [first, last) to the range
|
||||||
|
/// [result, result + (last-first)), except that any element for which pred is
|
||||||
|
/// true is not copied; new_value is copied instead. More precisely, for every
|
||||||
|
/// integer n such that 0 <= n < last-first, replace_copy_if performs the
|
||||||
|
/// assignment *(result+n) = new_value if pred(*(first+n)),
|
||||||
|
/// and *(result+n) = *(first+n) otherwise.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator, typename Predicate, typename T>
|
||||||
|
inline OutputIterator replace_copy_if (const Container& ctr, OutputIterator result, Predicate pred, const T& new_value)
|
||||||
|
{
|
||||||
|
return replace_copy_if (ctr.begin(), ctr.end(), result, pred, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill assigns the value value to every element in the range [first, last).
|
||||||
|
/// That is, for every iterator i in [first, last),
|
||||||
|
/// it performs the assignment *i = value.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename T>
|
||||||
|
inline void fill (Container& ctr, const T& value)
|
||||||
|
{
|
||||||
|
fill (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate assigns the result of invoking gen, a function object that
|
||||||
|
/// takes no arguments, to each element in the range [first, last).
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Generator>
|
||||||
|
inline void generate (Container& ctr, Generator gen)
|
||||||
|
{
|
||||||
|
generate (ctr.begin(), ctr.end(), gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Randomly permute the elements of the container.
|
||||||
|
/// \ingroup GeneratorAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline void random_shuffle (Container& ctr)
|
||||||
|
{
|
||||||
|
random_shuffle (ctr.begin(), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove_copy copies elements that are not equal to value from the range
|
||||||
|
/// [first, last) to a range beginning at result. The return value is the
|
||||||
|
/// end of the resulting range. This operation is stable, meaning that the
|
||||||
|
/// relative order of the elements that are copied is the same as in the
|
||||||
|
/// range [first, last).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator, typename T>
|
||||||
|
inline OutputIterator remove_copy (const Container& ctr, OutputIterator result, const T& value)
|
||||||
|
{
|
||||||
|
return remove_copy (ctr.begin(), ctr.end(), result, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove_copy_if copies elements from the range [first, last) to a range
|
||||||
|
/// beginning at result, except that elements for which pred is true are not
|
||||||
|
/// copied. The return value is the end of the resulting range. This operation
|
||||||
|
/// is stable, meaning that the relative order of the elements that are copied
|
||||||
|
/// is the same as in the range [first, last).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator, typename Predicate>
|
||||||
|
inline OutputIterator remove_copy_if (const Container& ctr, OutputIterator result, Predicate pred)
|
||||||
|
{
|
||||||
|
return remove_copy_if (ctr.begin(), ctr.end(), result, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove removes from the range [first, last) all elements that are equal to
|
||||||
|
/// value. That is, remove returns an iterator new_last such that the range
|
||||||
|
/// [first, new_last) contains no elements equal to value. Remove is stable,
|
||||||
|
/// meaning that the relative order of elements that are not equal to value is
|
||||||
|
/// unchanged.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename T>
|
||||||
|
inline void remove (Container& ctr, const T& value)
|
||||||
|
{
|
||||||
|
ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), value), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove removes from the range [first, last) all elements that have an iterator
|
||||||
|
/// in range [rfirst, rlast). The range is assumed to be sorted. That is, remove
|
||||||
|
/// returns an iterator new_last such that the range [first, new_last) contains
|
||||||
|
/// no elements whose iterators are in [rfirst, rlast). Remove is stable,
|
||||||
|
/// meaning that the relative order of elements that are not equal to value is
|
||||||
|
/// unchanged. This version of the algorithm is a uSTL extension.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename ForwardIterator>
|
||||||
|
inline void remove (Container& ctr, ForwardIterator rfirst, ForwardIterator rlast)
|
||||||
|
{
|
||||||
|
ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), rfirst, rlast), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove_if removes from the range [first, last) every element x such that
|
||||||
|
/// pred(x) is true. That is, remove_if returns an iterator new_last such that
|
||||||
|
/// the range [first, new_last) contains no elements for which pred is true.
|
||||||
|
/// The iterators in the range [new_last, last) are all still dereferenceable,
|
||||||
|
/// but the elements that they point to are unspecified. Remove_if is stable,
|
||||||
|
/// meaning that the relative order of elements that are not removed is
|
||||||
|
/// unchanged.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Predicate>
|
||||||
|
inline void remove_if (Container& ctr, Predicate pred)
|
||||||
|
{
|
||||||
|
ctr.erase (remove_copy_if (ctr.begin(), ctr.end(), ctr.begin(), pred), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unique_copy copies elements from the range [first, last) to a range
|
||||||
|
/// beginning with result, except that in a consecutive group of duplicate
|
||||||
|
/// elements only the first one is copied. The return value is the end of
|
||||||
|
/// the range to which the elements are copied. This behavior is similar
|
||||||
|
/// to the Unix filter uniq.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename OutputIterator>
|
||||||
|
inline OutputIterator unique_copy (const Container& ctr, OutputIterator result)
|
||||||
|
{
|
||||||
|
return unique_copy (ctr.begin(), ctr.end(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every time a consecutive group of duplicate elements appears in the range
|
||||||
|
/// [first, last), the algorithm unique removes all but the first element.
|
||||||
|
/// That is, unique returns an iterator new_last such that the range [first,
|
||||||
|
/// new_last) contains no two consecutive elements that are duplicates.
|
||||||
|
/// The iterators in the range [new_last, last) are all still dereferenceable,
|
||||||
|
/// but the elements that they point to are unspecified. Unique is stable,
|
||||||
|
/// meaning that the relative order of elements that are not removed is
|
||||||
|
/// unchanged.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline void unique (Container& ctr)
|
||||||
|
{
|
||||||
|
ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin()), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every time a consecutive group of duplicate elements appears in the range
|
||||||
|
/// [first, last), the algorithm unique removes all but the first element.
|
||||||
|
/// That is, unique returns an iterator new_last such that the range [first,
|
||||||
|
/// new_last) contains no two consecutive elements that are duplicates.
|
||||||
|
/// The iterators in the range [new_last, last) are all still dereferenceable,
|
||||||
|
/// but the elements that they point to are unspecified. Unique is stable,
|
||||||
|
/// meaning that the relative order of elements that are not removed is
|
||||||
|
/// unchanged.
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename BinaryPredicate>
|
||||||
|
inline void unique (Container& ctr, BinaryPredicate binary_pred)
|
||||||
|
{
|
||||||
|
ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin(), binary_pred), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reverse reverses a range.
|
||||||
|
/// That is: for every i such that 0 <= i <= (last - first) / 2),
|
||||||
|
/// it exchanges *(first + i) and *(last - (i + 1)).
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline void reverse (Container& ctr)
|
||||||
|
{
|
||||||
|
reverse (ctr.begin(), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Exchanges ranges [first, middle) and [middle, last)
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline void rotate (Container& ctr, off_t offset)
|
||||||
|
{
|
||||||
|
assert (size_t(offset > 0 ? offset : -offset) < ctr.size());
|
||||||
|
if (offset > 0)
|
||||||
|
rotate (ctr.begin(), ctr.end() - offset, ctr.end());
|
||||||
|
else
|
||||||
|
rotate (ctr.begin(), ctr.begin() - offset, ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the furthermost iterator i in [first, last) such that,
|
||||||
|
/// for every iterator j in [first, i), *j < value
|
||||||
|
/// Assumes the range is sorted.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename LessThanComparable>
|
||||||
|
inline typename Container::const_iterator lower_bound (const Container& ctr, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
return lower_bound (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
template <typename Container, typename LessThanComparable>
|
||||||
|
inline typename Container::iterator lower_bound (Container& ctr, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
return lower_bound (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the furthermost iterator i in [first,last) such that for
|
||||||
|
/// every iterator j in [first,i), value < *j is false.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename LessThanComparable>
|
||||||
|
inline typename Container::const_iterator upper_bound (const Container& ctr, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
return upper_bound (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
template <typename Container, typename LessThanComparable>
|
||||||
|
inline typename Container::iterator upper_bound (Container& ctr, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
return upper_bound (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs a binary search for \p value.
|
||||||
|
/// Assumes the range is sorted.
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline bool binary_search (const Container& ctr, const typename Container::value_type& value)
|
||||||
|
{
|
||||||
|
return binary_search (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
template <typename Container>
|
||||||
|
inline bool binary_search (Container& ctr, const typename Container::value_type& value)
|
||||||
|
{
|
||||||
|
return binary_search (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns pair<lower_bound,upper_bound>
|
||||||
|
/// \ingroup SearchingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename LessThanComparable>
|
||||||
|
inline pair<typename Container::const_iterator,typename Container::const_iterator> equal_range (const Container& ctr, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
return equal_range (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
template <typename Container, typename LessThanComparable>
|
||||||
|
inline pair<typename Container::iterator,typename Container::iterator> equal_range (Container& ctr, const LessThanComparable& value)
|
||||||
|
{
|
||||||
|
return equal_range (ctr.begin(), ctr.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline void sort (Container& ctr)
|
||||||
|
{
|
||||||
|
sort (ctr.begin(), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Compare>
|
||||||
|
inline void sort (Container& ctr, Compare comp)
|
||||||
|
{
|
||||||
|
sort (ctr.begin(), ctr.end(), comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline void stable_sort (Container& ctr)
|
||||||
|
{
|
||||||
|
stable_sort (ctr.begin(), ctr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts the container
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename Container, typename Compare>
|
||||||
|
inline void stable_sort (Container& ctr, Compare comp)
|
||||||
|
{
|
||||||
|
stable_sort (ctr.begin(), ctr.end(), comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ustl
|
462
pwn/flipper/dist/common/include/ustl/ufunction.h
vendored
Normal file
462
pwn/flipper/dist/common/include/ustl/ufunction.h
vendored
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Standard functors
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief void-returning function abstract interface.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <typename Result>
|
||||||
|
struct void_function {
|
||||||
|
typedef Result result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief \p Result f (\p Arg) function abstract interface.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <typename Arg, typename Result>
|
||||||
|
struct unary_function {
|
||||||
|
typedef Arg argument_type;
|
||||||
|
typedef Result result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief \p Result f (\p Arg1, \p Arg2) function abstract interface.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <typename Arg1, typename Arg2, typename Result>
|
||||||
|
struct binary_function {
|
||||||
|
typedef Arg1 first_argument_type;
|
||||||
|
typedef Arg2 second_argument_type;
|
||||||
|
typedef Result result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
#define STD_BINARY_FUNCTOR(name, rv, func) \
|
||||||
|
template <class T> struct name : public binary_function<T,T,rv> \
|
||||||
|
{ inline rv operator()(const T& a, const T& b) const { return func; } };
|
||||||
|
#define STD_UNARY_FUNCTOR(name, rv, func) \
|
||||||
|
template <class T> struct name : public unary_function<T,rv> \
|
||||||
|
{ inline rv operator()(const T& a) const { return func; } };
|
||||||
|
#define STD_CONVERSION_FUNCTOR(name, func) \
|
||||||
|
template <class S, class D> struct name : public unary_function<S,D> \
|
||||||
|
{ inline D operator()(const S& a) const { return func; } };
|
||||||
|
|
||||||
|
STD_BINARY_FUNCTOR (plus, T, (a + b))
|
||||||
|
STD_BINARY_FUNCTOR (minus, T, (a - b))
|
||||||
|
STD_BINARY_FUNCTOR (divides, T, (a / b))
|
||||||
|
STD_BINARY_FUNCTOR (modulus, T, (a % b))
|
||||||
|
STD_BINARY_FUNCTOR (multiplies, T, (a * b))
|
||||||
|
STD_BINARY_FUNCTOR (logical_and, T, (a && b))
|
||||||
|
STD_BINARY_FUNCTOR (logical_or, T, (a || b))
|
||||||
|
STD_UNARY_FUNCTOR (logical_not, T, (!a))
|
||||||
|
STD_BINARY_FUNCTOR (bitwise_or, T, (a | b))
|
||||||
|
STD_BINARY_FUNCTOR (bitwise_and, T, (a & b))
|
||||||
|
STD_BINARY_FUNCTOR (bitwise_xor, T, (a ^ b))
|
||||||
|
STD_UNARY_FUNCTOR (bitwise_not, T, (~a))
|
||||||
|
STD_UNARY_FUNCTOR (negate, T, (-a))
|
||||||
|
STD_BINARY_FUNCTOR (equal_to, bool, (a == b))
|
||||||
|
STD_BINARY_FUNCTOR (not_equal_to, bool, (!(a == b)))
|
||||||
|
STD_BINARY_FUNCTOR (greater, bool, (b < a))
|
||||||
|
STD_BINARY_FUNCTOR (less, bool, (a < b))
|
||||||
|
STD_BINARY_FUNCTOR (greater_equal, bool, (!(a < b)))
|
||||||
|
STD_BINARY_FUNCTOR (less_equal, bool, (!(b < a)))
|
||||||
|
STD_BINARY_FUNCTOR (compare, int, (a < b ? -1 : (b < a)))
|
||||||
|
STD_UNARY_FUNCTOR (identity, T, (a))
|
||||||
|
|
||||||
|
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
/// \brief Selects and returns the first argument.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <class T1, class T2> struct project1st : public binary_function<T1,T2,T1> { inline const T1& operator()(const T1& a, const T2&) const { return a; } };
|
||||||
|
/// \brief Selects and returns the second argument.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <class T1, class T2> struct project2nd : public binary_function<T1,T2,T2> { inline const T2& operator()(const T1&, const T2& a) const { return a; } };
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Generic function to functor converters.
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Wrapper object for unary function pointers.
|
||||||
|
/// Use the ptr_fun accessor to create this object.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <typename Arg, typename Result>
|
||||||
|
class pointer_to_unary_function : public unary_function<Arg,Result> {
|
||||||
|
public:
|
||||||
|
typedef Arg argument_type;
|
||||||
|
typedef Result result_type;
|
||||||
|
typedef Result (*pfunc_t)(Arg);
|
||||||
|
public:
|
||||||
|
explicit inline pointer_to_unary_function (pfunc_t pfn) : _pfn (pfn) {}
|
||||||
|
inline result_type operator() (argument_type v) const { return _pfn(v); }
|
||||||
|
private:
|
||||||
|
pfunc_t _pfn; ///< Pointer to the wrapped function.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Wrapper object for binary function pointers.
|
||||||
|
/// Use the ptr_fun accessor to create this object.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <typename Arg1, typename Arg2, typename Result>
|
||||||
|
class pointer_to_binary_function : public binary_function<Arg1,Arg2,Result> {
|
||||||
|
public:
|
||||||
|
typedef Arg1 first_argument_type;
|
||||||
|
typedef Arg2 second_argument_type;
|
||||||
|
typedef Result result_type;
|
||||||
|
typedef Result (*pfunc_t)(Arg1, Arg2);
|
||||||
|
public:
|
||||||
|
explicit inline pointer_to_binary_function (pfunc_t pfn) : _pfn (pfn) {}
|
||||||
|
inline result_type operator() (first_argument_type v1, second_argument_type v2) const { return _pfn(v1, v2); }
|
||||||
|
private:
|
||||||
|
pfunc_t _pfn; ///< Pointer to the wrapped function.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <typename Arg, typename Result>
|
||||||
|
inline pointer_to_unary_function<Arg,Result> ptr_fun (Result (*pfn)(Arg))
|
||||||
|
{
|
||||||
|
return pointer_to_unary_function<Arg,Result> (pfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <typename Arg1, typename Arg2, typename Result>
|
||||||
|
inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun (Result (*pfn)(Arg1,Arg2))
|
||||||
|
{
|
||||||
|
return pointer_to_binary_function<Arg1,Arg2,Result> (pfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Negators.
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Wraps a unary function to return its logical negative.
|
||||||
|
/// Use the unary_negator accessor to create this object.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <class UnaryFunction>
|
||||||
|
class unary_negate : public unary_function<typename UnaryFunction::argument_type,
|
||||||
|
typename UnaryFunction::result_type> {
|
||||||
|
public:
|
||||||
|
typedef typename UnaryFunction::argument_type argument_type;
|
||||||
|
typedef typename UnaryFunction::result_type result_type;
|
||||||
|
public:
|
||||||
|
explicit inline unary_negate (UnaryFunction pfn) : _pfn (pfn) {}
|
||||||
|
inline result_type operator() (argument_type v) const { return !_pfn(v); }
|
||||||
|
private:
|
||||||
|
UnaryFunction _pfn;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the functor that negates the result of *pfn().
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <class UnaryFunction>
|
||||||
|
inline unary_negate<UnaryFunction> unary_negator (UnaryFunction pfn)
|
||||||
|
{
|
||||||
|
return unary_negate<UnaryFunction>(pfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Argument binders
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Converts a binary function to a unary function
|
||||||
|
/// by binding a constant value to the first argument.
|
||||||
|
/// Use the bind1st accessor to create this object.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <class BinaryFunction>
|
||||||
|
class binder1st : public unary_function<typename BinaryFunction::second_argument_type,
|
||||||
|
typename BinaryFunction::result_type> {
|
||||||
|
public:
|
||||||
|
typedef typename BinaryFunction::first_argument_type arg1_t;
|
||||||
|
typedef typename BinaryFunction::second_argument_type arg2_t;
|
||||||
|
typedef typename BinaryFunction::result_type result_t;
|
||||||
|
public:
|
||||||
|
inline binder1st (const BinaryFunction& pfn, const arg1_t& v) : _pfn (pfn), _v(v) {}
|
||||||
|
inline result_t operator()(arg2_t v2) const { return _pfn (_v, v2); }
|
||||||
|
protected:
|
||||||
|
BinaryFunction _pfn;
|
||||||
|
arg1_t _v;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Converts a binary function to a unary function
|
||||||
|
/// by binding a constant value to the second argument.
|
||||||
|
/// Use the bind2nd accessor to create this object.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
template <class BinaryFunction>
|
||||||
|
class binder2nd : public unary_function<typename BinaryFunction::first_argument_type,
|
||||||
|
typename BinaryFunction::result_type> {
|
||||||
|
public:
|
||||||
|
typedef typename BinaryFunction::first_argument_type arg1_t;
|
||||||
|
typedef typename BinaryFunction::second_argument_type arg2_t;
|
||||||
|
typedef typename BinaryFunction::result_type result_t;
|
||||||
|
public:
|
||||||
|
inline binder2nd (const BinaryFunction& pfn, const arg2_t& v) : _pfn (pfn), _v(v) {}
|
||||||
|
inline result_t operator()(arg1_t v1) const { return _pfn (v1, _v); }
|
||||||
|
protected:
|
||||||
|
BinaryFunction _pfn;
|
||||||
|
arg2_t _v;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Converts \p pfn into a unary function by binding the first argument to \p v.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <typename BinaryFunction>
|
||||||
|
inline binder1st<BinaryFunction>
|
||||||
|
bind1st (BinaryFunction pfn, typename BinaryFunction::first_argument_type v)
|
||||||
|
{
|
||||||
|
return binder1st<BinaryFunction> (pfn, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts \p pfn into a unary function by binding the second argument to \p v.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <typename BinaryFunction>
|
||||||
|
inline binder2nd<BinaryFunction>
|
||||||
|
bind2nd (BinaryFunction pfn, typename BinaryFunction::second_argument_type v)
|
||||||
|
{
|
||||||
|
return binder2nd<BinaryFunction> (pfn, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Composition adapters
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \brief Chains two unary functions together.
|
||||||
|
///
|
||||||
|
/// When f(x) and g(x) are composed, the result is function c(x)=f(g(x)).
|
||||||
|
/// Use the \ref compose1 accessor to create this object.
|
||||||
|
/// This template is an extension, implemented by SGI STL and uSTL.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
///
|
||||||
|
template <typename Operation1, typename Operation2>
|
||||||
|
class unary_compose : public unary_function<typename Operation2::argument_type,
|
||||||
|
typename Operation1::result_type> {
|
||||||
|
public:
|
||||||
|
typedef typename Operation2::argument_type arg_t;
|
||||||
|
typedef const arg_t& rcarg_t;
|
||||||
|
typedef typename Operation1::result_type result_t;
|
||||||
|
public:
|
||||||
|
inline unary_compose (const Operation1& f, const Operation2& g) : _f(f), _g(g) {}
|
||||||
|
inline result_t operator() (rcarg_t x) const { return _f(_g(x)); }
|
||||||
|
protected:
|
||||||
|
Operation1 _f; ///< f(x), if c(x) = f(g(x))
|
||||||
|
Operation2 _g; ///< g(x), if c(x) = f(g(x))
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Creates a \ref unary_compose object whose function c(x)=f(g(x))
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <typename Operation1, typename Operation2>
|
||||||
|
inline unary_compose<Operation1, Operation2>
|
||||||
|
compose1 (const Operation1& f, const Operation2& g)
|
||||||
|
{ return unary_compose<Operation1,Operation2>(f, g); }
|
||||||
|
|
||||||
|
/// \brief Chains two unary functions through a binary function.
|
||||||
|
///
|
||||||
|
/// When f(x,y), g(x), and h(x) are composed, the result is function
|
||||||
|
/// c(x)=f(g(x),h(x)). Use the \ref compose2 accessor to create this
|
||||||
|
/// object. This template is an extension, implemented by SGI STL and uSTL.
|
||||||
|
/// \ingroup FunctorObjects
|
||||||
|
///
|
||||||
|
template <typename Operation1, typename Operation2, typename Operation3>
|
||||||
|
class binary_compose : public unary_function<typename Operation2::argument_type,
|
||||||
|
typename Operation1::result_type> {
|
||||||
|
public:
|
||||||
|
typedef typename Operation2::argument_type arg_t;
|
||||||
|
typedef const arg_t& rcarg_t;
|
||||||
|
typedef typename Operation1::result_type result_t;
|
||||||
|
public:
|
||||||
|
inline binary_compose (const Operation1& f, const Operation2& g, const Operation3& h) : _f(f), _g(g), _h(h) {}
|
||||||
|
inline result_t operator() (rcarg_t x) const { return _f(_g(x), _h(x)); }
|
||||||
|
protected:
|
||||||
|
Operation1 _f; ///< f(x,y), if c(x) = f(g(x),h(x))
|
||||||
|
Operation2 _g; ///< g(x), if c(x) = f(g(x),h(x))
|
||||||
|
Operation3 _h; ///< h(x), if c(x) = f(g(x),h(x))
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Creates a \ref binary_compose object whose function c(x)=f(g(x),h(x))
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <typename Operation1, typename Operation2, typename Operation3>
|
||||||
|
inline binary_compose<Operation1, Operation2, Operation3>
|
||||||
|
compose2 (const Operation1& f, const Operation2& g, const Operation3& h)
|
||||||
|
{ return binary_compose<Operation1, Operation2, Operation3> (f, g, h); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Member function adaptors
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
#define MEM_FUN_T(WrapperName, ClassName, ArgType, FuncType, CallType) \
|
||||||
|
template <typename Ret, class T> \
|
||||||
|
class ClassName : public unary_function<ArgType,Ret> { \
|
||||||
|
public: \
|
||||||
|
typedef Ret (T::*func_t) FuncType; \
|
||||||
|
public: \
|
||||||
|
explicit inline ClassName (func_t pf) : _pf (pf) {} \
|
||||||
|
inline Ret operator() (ArgType p) const { return (p CallType _pf)(); } \
|
||||||
|
private: \
|
||||||
|
func_t _pf; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class Ret, typename T> \
|
||||||
|
inline ClassName<Ret,T> WrapperName (Ret (T::*pf) FuncType) \
|
||||||
|
{ \
|
||||||
|
return ClassName<Ret,T> (pf); \
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_FUN_T(mem_fun, mem_fun_t, T*, (void), ->*)
|
||||||
|
MEM_FUN_T(mem_fun, const_mem_fun_t, const T*, (void) const, ->*)
|
||||||
|
MEM_FUN_T(mem_fun_ref, mem_fun_ref_t, T&, (void), .*)
|
||||||
|
MEM_FUN_T(mem_fun_ref, const_mem_fun_ref_t, const T&, (void) const, .*)
|
||||||
|
|
||||||
|
#define EXT_MEM_FUN_T(ClassName, HostType, FuncType) \
|
||||||
|
template <class T, typename Ret, typename V> \
|
||||||
|
class ClassName : public unary_function<V,void> { \
|
||||||
|
public: \
|
||||||
|
typedef Ret (T::*func_t)(V) FuncType; \
|
||||||
|
public: \
|
||||||
|
inline ClassName (HostType t, func_t pf) : _t (t), _pf (pf) {} \
|
||||||
|
inline Ret operator() (V v) const { return (_t->*_pf)(v); } \
|
||||||
|
private: \
|
||||||
|
HostType _t; \
|
||||||
|
func_t _pf; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, typename Ret, typename V> \
|
||||||
|
inline ClassName<T,Ret,V> mem_fun (HostType p, Ret (T::*pf)(V) FuncType) \
|
||||||
|
{ \
|
||||||
|
return ClassName<T,Ret,V> (p, pf); \
|
||||||
|
}
|
||||||
|
|
||||||
|
EXT_MEM_FUN_T(ext_mem_fun_t, T*, )
|
||||||
|
EXT_MEM_FUN_T(const_ext_mem_fun_t, const T*, const)
|
||||||
|
|
||||||
|
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Member variable adaptors (uSTL extension)
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
#define MEM_VAR_T(FunctorName, ArgType, VarType, BaseClass, CallImpl) \
|
||||||
|
template <typename Function, class T, typename VT> \
|
||||||
|
class FunctorName##_t : public BaseClass { \
|
||||||
|
public: \
|
||||||
|
typedef ArgType argument_type; \
|
||||||
|
typedef typename Function::result_type result_type; \
|
||||||
|
typedef VarType mem_var_ptr_t; \
|
||||||
|
public: \
|
||||||
|
inline FunctorName##_t (mem_var_ptr_t pv, Function pfn) : _pv(pv), _pfn(pfn) {} \
|
||||||
|
inline result_type operator() CallImpl \
|
||||||
|
private: \
|
||||||
|
mem_var_ptr_t _pv; \
|
||||||
|
Function _pfn; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <typename Function, class T, typename VT> \
|
||||||
|
inline FunctorName##_t<Function, T, VT> \
|
||||||
|
FunctorName (VT T::*mvp, Function pfn) \
|
||||||
|
{ \
|
||||||
|
return FunctorName##_t<Function,T,VT> (mvp, pfn); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FUNCTOR_UNARY_BASE(ArgType) unary_function<ArgType, typename Function::result_type>
|
||||||
|
#define FUNCTOR_BINARY_BASE(ArgType) binary_function<ArgType, ArgType, typename Function::result_type>
|
||||||
|
|
||||||
|
#define MEM_VAR_UNARY_ARGS (argument_type p) const \
|
||||||
|
{ return _pfn(p.*_pv); }
|
||||||
|
#define MEM_VAR_BINARY_ARGS (argument_type p1, argument_type p2) const \
|
||||||
|
{ return _pfn(p1.*_pv, p2.*_pv); }
|
||||||
|
|
||||||
|
MEM_VAR_T(mem_var1, T&, VT T::*, FUNCTOR_UNARY_BASE(T&), MEM_VAR_UNARY_ARGS)
|
||||||
|
MEM_VAR_T(const_mem_var1, const T&, const VT T::*, FUNCTOR_UNARY_BASE(T&), MEM_VAR_UNARY_ARGS)
|
||||||
|
MEM_VAR_T(mem_var2, T&, VT T::*, FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS)
|
||||||
|
MEM_VAR_T(const_mem_var2, const T&, const VT T::*, FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS)
|
||||||
|
|
||||||
|
#undef MEM_VAR_UNARY_ARGS
|
||||||
|
#undef MEM_VAR_BINARY_ARGS
|
||||||
|
|
||||||
|
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <class T, typename VT>
|
||||||
|
inline const_mem_var1_t<binder2nd<equal_to<VT> >, T, VT>
|
||||||
|
mem_var_equal_to (const VT T::*mvp, const VT& v)
|
||||||
|
{
|
||||||
|
return const_mem_var1_t<binder2nd<equal_to<VT> >,T,VT> (mvp, bind2nd(equal_to<VT>(), v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <class T, typename VT>
|
||||||
|
inline const_mem_var1_t<binder2nd<less<VT> >, T, VT>
|
||||||
|
mem_var_less (const VT T::*mvp, const VT& v)
|
||||||
|
{
|
||||||
|
return const_mem_var1_t<binder2nd<less<VT> >,T,VT> (mvp, bind2nd(less<VT>(), v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <class T, typename VT>
|
||||||
|
inline const_mem_var2_t<equal_to<VT>, T, VT>
|
||||||
|
mem_var_equal_to (const VT T::*mvp)
|
||||||
|
{
|
||||||
|
return const_mem_var2_t<equal_to<VT>,T,VT> (mvp, equal_to<VT>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>.
|
||||||
|
/// \ingroup FunctorAccessors
|
||||||
|
template <class T, typename VT>
|
||||||
|
inline const_mem_var2_t<less<VT>, T, VT>
|
||||||
|
mem_var_less (const VT T::*mvp)
|
||||||
|
{
|
||||||
|
return const_mem_var2_t<less<VT>,T,VT> (mvp, less<VT>());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Dereference adaptors (uSTL extension)
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
#define DEREFERENCER_T(ClassName, ArgType, BaseClass, CallImpl, FunctorKey) \
|
||||||
|
template <typename T, typename Function> \
|
||||||
|
class ClassName : public BaseClass { \
|
||||||
|
public: \
|
||||||
|
typedef ArgType* argument_type; \
|
||||||
|
typedef typename Function::result_type result_type; \
|
||||||
|
public: \
|
||||||
|
inline ClassName (Function pfn) : _pfn (pfn) {} \
|
||||||
|
inline result_type operator() CallImpl \
|
||||||
|
private: \
|
||||||
|
Function _pfn; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <typename T, typename Function> \
|
||||||
|
inline ClassName<T,Function> _dereference (Function pfn, FunctorKey) \
|
||||||
|
{ \
|
||||||
|
return ClassName<T,Function> (pfn); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEREF_UNARY_ARGS (argument_type p) const \
|
||||||
|
{ return _pfn(*p); }
|
||||||
|
#define DEREF_BINARY_ARGS (argument_type p1, argument_type p2) const \
|
||||||
|
{ return _pfn(*p1, *p2); }
|
||||||
|
|
||||||
|
DEREFERENCER_T(deref1_t, T, FUNCTOR_UNARY_BASE(T*), DEREF_UNARY_ARGS, FUNCTOR_UNARY_BASE(T))
|
||||||
|
DEREFERENCER_T(const_deref1_t, const T, FUNCTOR_UNARY_BASE(const T*), DEREF_UNARY_ARGS, FUNCTOR_UNARY_BASE(const T))
|
||||||
|
DEREFERENCER_T(deref2_t, T, FUNCTOR_BINARY_BASE(T*), DEREF_BINARY_ARGS, FUNCTOR_BINARY_BASE(T))
|
||||||
|
DEREFERENCER_T(const_deref2_t, const T, FUNCTOR_BINARY_BASE(const T*), DEREF_BINARY_ARGS, FUNCTOR_BINARY_BASE(const T))
|
||||||
|
|
||||||
|
#define dereference(f) _dereference(f,f)
|
||||||
|
|
||||||
|
#undef DEREF_UNARY_ARGS
|
||||||
|
#undef DEREF_BINARY_ARGS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace ustl
|
161
pwn/flipper/dist/common/include/ustl/uheap.h
vendored
Normal file
161
pwn/flipper/dist/common/include/ustl/uheap.h
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ualgobase.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \brief Returns true if the given range is a heap under \p comp.
|
||||||
|
/// A heap is a sequentially encoded binary tree where for every node
|
||||||
|
/// comp(node,child1) is false and comp(node,child2) is false.
|
||||||
|
/// \ingroup HeapAlgorithms
|
||||||
|
/// \ingroup ConditionAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
bool is_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
RandomAccessIterator iChild (first);
|
||||||
|
for (; ++iChild < last; ++first)
|
||||||
|
if (comp (*first, *iChild) || (++iChild < last && comp (*first, *iChild)))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Utility function to "trickle down" the root item - swaps the root item with its
|
||||||
|
/// largest child and recursively fixes the proper subtree.
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void trickle_down_heap (RandomAccessIterator first, size_t iHole, size_t heapSize, Compare comp)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
const value_type v (first[iHole]);
|
||||||
|
for (size_t iChild; (iChild = 2 * iHole + 1) < heapSize;) {
|
||||||
|
if (iChild + 1 < heapSize)
|
||||||
|
iChild += comp (first[iChild], first[iChild + 1]);
|
||||||
|
if (comp (v, first[iChild])) {
|
||||||
|
first[iHole] = first[iChild];
|
||||||
|
iHole = iChild;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
first[iHole] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief make_heap turns the range [first, last) into a heap
|
||||||
|
/// At completion, is_heap (first, last, comp) is true.
|
||||||
|
/// The algorithm is adapted from "Classic Data Structures in C++" by Timothy Budd.
|
||||||
|
/// \ingroup HeapAlgorithms
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void make_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
if (last <= first)
|
||||||
|
return;
|
||||||
|
const size_t heapSize = distance (first, last);
|
||||||
|
for (RandomAccessIterator i = first + (heapSize - 1)/2; i >= first; --i)
|
||||||
|
trickle_down_heap (first, distance(first,i), heapSize, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Inserts the *--last into the preceeding range assumed to be a heap.
|
||||||
|
/// \ingroup HeapAlgorithms
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void push_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
if (last <= first)
|
||||||
|
return;
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
const value_type v (*--last);
|
||||||
|
while (first < last) {
|
||||||
|
RandomAccessIterator iParent = first + (distance(first, last) - 1) / 2;
|
||||||
|
if (comp (v, *iParent))
|
||||||
|
break;
|
||||||
|
*last = *iParent;
|
||||||
|
last = iParent;
|
||||||
|
}
|
||||||
|
*last = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes the largest element from the heap (*first) and places it at *(last-1)
|
||||||
|
/// [first, last-1) is a heap after this operation.
|
||||||
|
/// \ingroup HeapAlgorithms
|
||||||
|
/// \ingroup MutatingAlgorithms
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void pop_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
if (--last <= first)
|
||||||
|
return;
|
||||||
|
iter_swap (first, last);
|
||||||
|
trickle_down_heap (first, 0, distance(first,last), comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sorts heap [first, last) in descending order according to comp.
|
||||||
|
/// \ingroup HeapAlgorithms
|
||||||
|
/// \ingroup SortingAlgorithms
|
||||||
|
template <typename RandomAccessIterator, typename Compare>
|
||||||
|
void sort_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
|
||||||
|
{
|
||||||
|
for (; first < last; --last)
|
||||||
|
pop_heap (first, last, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HEAP_FN_WITH_LESS(rtype, name) \
|
||||||
|
template <typename RandomAccessIterator>\
|
||||||
|
inline rtype name (RandomAccessIterator first, RandomAccessIterator last) \
|
||||||
|
{ \
|
||||||
|
typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; \
|
||||||
|
return name (first, last, less<value_type>()); \
|
||||||
|
}
|
||||||
|
HEAP_FN_WITH_LESS (bool, is_heap)
|
||||||
|
HEAP_FN_WITH_LESS (void, make_heap)
|
||||||
|
HEAP_FN_WITH_LESS (void, push_heap)
|
||||||
|
HEAP_FN_WITH_LESS (void, pop_heap)
|
||||||
|
HEAP_FN_WITH_LESS (void, sort_heap)
|
||||||
|
#undef HEAP_FN_WITH_LESS
|
||||||
|
|
||||||
|
/// \class priority_queue uheap.h ustl.h
|
||||||
|
/// \ingroup Sequences
|
||||||
|
///
|
||||||
|
/// \brief Sorted queue adapter to uSTL containers.
|
||||||
|
///
|
||||||
|
/// Acts just like the queue adapter, but keeps the elements sorted by priority
|
||||||
|
/// specified by the given comparison operator.
|
||||||
|
///
|
||||||
|
template <typename T, typename Container = vector<T>, typename Comp = less<typename Container::value_type> >
|
||||||
|
class priority_queue {
|
||||||
|
public:
|
||||||
|
typedef Container container_type;
|
||||||
|
typedef typename container_type::size_type size_type;
|
||||||
|
typedef typename container_type::value_type value_type;
|
||||||
|
typedef typename container_type::reference reference;
|
||||||
|
typedef typename container_type::const_reference const_reference;
|
||||||
|
typedef typename container_type::const_iterator const_iterator;
|
||||||
|
public:
|
||||||
|
inline explicit priority_queue (const Comp& c = Comp()) : _v(), _c(c) {}
|
||||||
|
inline priority_queue (const Comp& c, const container_type& v) : _v(v), _c(c) {}
|
||||||
|
priority_queue (const_iterator f, const_iterator l, const Comp& c = Comp())
|
||||||
|
: _v(f, l), _c(c) { make_heap (_v.begin(), _v.end(), _c); }
|
||||||
|
inline size_type size (void) const { return _v.size(); }
|
||||||
|
inline bool empty (void) const { return _v.empty(); }
|
||||||
|
inline const_reference top (void) const { return _v.front(); }
|
||||||
|
inline void push (const_reference v){ _v.push_back (v); push_heap (_v.begin(), _v.end(), _c); }
|
||||||
|
inline void pop (void) { pop_heap (_v.begin(), _v.end()); _v.pop_back(); }
|
||||||
|
inline void swap (priority_queue& v){ _v.swap (v._v); swap (_c, v._c); }
|
||||||
|
#if HAVE_CPP11
|
||||||
|
inline explicit priority_queue (priority_queue&& v) : _v(move(v._v)),_c(v._c) {}
|
||||||
|
inline priority_queue (const Comp& c, container_type&& v) : _v(move(v)),_c(c) {}
|
||||||
|
priority_queue (const_iterator f, const_iterator l, const Comp& c, container_type&& v)
|
||||||
|
: _v(move(v)), _c(c) { _v.insert (_v.end(), f, l); make_heap (_v.begin(), _v.end(), _c); }
|
||||||
|
inline priority_queue& operator= (priority_queue&& v) { swap (v); return *this; }
|
||||||
|
template <typename... Args>
|
||||||
|
inline void emplace (Args&&... args) { _v.emplace_back (forward<Args>(args)...); push_heap (_v.begin(), _v.end(), _c); }
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
container_type _v; ///< Element container.
|
||||||
|
Comp _c; ///< Comparison functor by value.
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
99
pwn/flipper/dist/common/include/ustl/uios.h
vendored
Normal file
99
pwn/flipper/dist/common/include/ustl/uios.h
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "utypes.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class file_exception;
|
||||||
|
|
||||||
|
/// Defines types and constants used by all stream classes.
|
||||||
|
class ios_base {
|
||||||
|
public:
|
||||||
|
/// Used to set parameters for stringstreams
|
||||||
|
enum fmtflags_bits {
|
||||||
|
boolalpha = (1 << 0), ///< Boolean values printed as text.
|
||||||
|
showbase = (1 << 1), ///< Add 0x or 0 prefixes on hex and octal numbers.
|
||||||
|
showpoint = (1 << 2), ///< Print decimal point.
|
||||||
|
showpos = (1 << 3),
|
||||||
|
skipws = (1 << 4), ///< Skip whitespace when reading.
|
||||||
|
unitbuf = (1 << 5),
|
||||||
|
uppercase = (1 << 6),
|
||||||
|
dec = (1 << 7), ///< Decimal number output.
|
||||||
|
oct = (1 << 8), ///< Octal number output.
|
||||||
|
hex = (1 << 9), ///< Hexadecimal number output.
|
||||||
|
fixed = (1 << 10), ///< Fixed-point float output.
|
||||||
|
scientific = (1 << 11), ///< Scientific float format.
|
||||||
|
left = (1 << 12), ///< Left alignment.
|
||||||
|
right = (1 << 13), ///< Right alignment.
|
||||||
|
internal = (1 << 14),
|
||||||
|
basefield = dec| oct| hex,
|
||||||
|
floatfield = fixed| scientific,
|
||||||
|
adjustfield = left| right| internal
|
||||||
|
};
|
||||||
|
/// For file-based streams, specifies fd mode.
|
||||||
|
enum openmode_bits {
|
||||||
|
in = (1 << 0),
|
||||||
|
out = (1 << 1),
|
||||||
|
app = (1 << 2),
|
||||||
|
ate = (1 << 3),
|
||||||
|
binary = (1 << 4),
|
||||||
|
trunc = (1 << 5),
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
nonblock= (1 << 6),
|
||||||
|
nocreate= (1 << 7),
|
||||||
|
noctty = (1 << 8),
|
||||||
|
nombits = 9
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
/// Seek directions, equivalent to SEEK_SET, SEEK_CUR, and SEEK_END.
|
||||||
|
enum seekdir {
|
||||||
|
beg,
|
||||||
|
cur,
|
||||||
|
end
|
||||||
|
};
|
||||||
|
/// I/O state bitmasks.
|
||||||
|
enum iostate_bits {
|
||||||
|
goodbit = 0,
|
||||||
|
badbit = (1 << 0),
|
||||||
|
eofbit = (1 << 1),
|
||||||
|
failbit = (1 << 2),
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
nbadbits = 3,
|
||||||
|
allbadbits = 0x7
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { default_stream_buffer_size = 4095 };
|
||||||
|
|
||||||
|
typedef uint32_t openmode; ///< Holds openmode_bits.
|
||||||
|
struct fmtflags{ fmtflags(const uint32_t& flags) : f(flags){}; fmtflags() = default; uint32_t f; }; ///< Holds fmtflags_bits for a string stream.
|
||||||
|
typedef uint32_t iostate; ///< Holds iostate_bits for a file stream.
|
||||||
|
typedef file_exception failure; ///< Thrown by fstream on errors.
|
||||||
|
|
||||||
|
static const char c_DefaultDelimiters [16]; ///< Default word delimiters for stringstreams.
|
||||||
|
public:
|
||||||
|
inline ios_base (void) : _state (goodbit), _exceptions (allbadbits) {}
|
||||||
|
inline iostate rdstate (void) const { return _state; }
|
||||||
|
inline bool bad (void) const { return rdstate() & badbit; }
|
||||||
|
inline bool good (void) const { return rdstate() == goodbit; }
|
||||||
|
inline bool fail (void) const { return rdstate() & (badbit | failbit); }
|
||||||
|
inline bool eof (void) const { return rdstate() & eofbit; }
|
||||||
|
inline bool operator! (void) const { return fail(); }
|
||||||
|
inline operator bool (void) const { return !fail(); }
|
||||||
|
inline void clear (iostate v = goodbit) { _state = v; }
|
||||||
|
inline void setstate (iostate v) { _state |= v; }
|
||||||
|
inline iostate exceptions (void) const { return _exceptions; }
|
||||||
|
inline iostate exceptions (iostate v) { return _exceptions = v; }
|
||||||
|
protected:
|
||||||
|
inline bool set_and_throw (iostate v) { setstate(v); return exceptions() & v; }
|
||||||
|
void overrun (const char* op, const char* type, uint32_t n, uint32_t p, uint32_t rem);
|
||||||
|
private:
|
||||||
|
uint16_t _state; ///< Open state, using ios::iostate_bits.
|
||||||
|
uint16_t _exceptions; ///< Exception flags, using ios::iostate_bits.
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
82
pwn/flipper/dist/common/include/ustl/uiosfunc.h
vendored
Normal file
82
pwn/flipper/dist/common/include/ustl/uiosfunc.h
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "sostream.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class ios : public ios_base {
|
||||||
|
public:
|
||||||
|
/// \class align uiosfunc.h ustl.h
|
||||||
|
/// \ingroup StreamFunctors
|
||||||
|
/// \brief Stream functor to allow inline align() calls.
|
||||||
|
///
|
||||||
|
/// Example: os << ios::align(sizeof(uint16_t));
|
||||||
|
///
|
||||||
|
class align {
|
||||||
|
public:
|
||||||
|
inline explicit align (size_t grain = c_DefaultAlignment) : _grain(grain) {}
|
||||||
|
inline istream& apply (istream& is) const { is.align (_grain); return is; }
|
||||||
|
inline ostream& apply (ostream& os) const { os.align (_grain); return os; }
|
||||||
|
inline void read (istream& is) const { apply (is); }
|
||||||
|
inline void write (ostream& os) const { apply (os); }
|
||||||
|
inline size_t stream_size (void) const { return _grain - 1; }
|
||||||
|
private:
|
||||||
|
const size_t _grain;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \class talign uiosfunc.h ustl.h
|
||||||
|
/// \ingroup StreamFunctors
|
||||||
|
/// \brief Stream functor to allow type-based alignment.
|
||||||
|
template <typename T>
|
||||||
|
class talign : public align {
|
||||||
|
public:
|
||||||
|
inline explicit talign (void) : align (stream_align_of (NullValue<T>())) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \class skip uiosfunc.h ustl.h
|
||||||
|
/// \ingroup StreamFunctors
|
||||||
|
/// \brief Stream functor to allow inline skip() calls.
|
||||||
|
///
|
||||||
|
/// Example: os << ios::skip(sizeof(uint16_t));
|
||||||
|
///
|
||||||
|
class skip {
|
||||||
|
public:
|
||||||
|
inline explicit skip (size_t nBytes) : _nBytes(nBytes) {}
|
||||||
|
inline istream& apply (istream& is) const { is.skip (_nBytes); return is; }
|
||||||
|
inline ostream& apply (ostream& os) const { os.skip (_nBytes); return os; }
|
||||||
|
inline void read (istream& is) const { apply (is); }
|
||||||
|
inline void write (ostream& os) const { apply (os); }
|
||||||
|
inline size_t stream_size (void) const { return _nBytes; }
|
||||||
|
private:
|
||||||
|
const size_t _nBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \class width uiosfunc.h ustl.h
|
||||||
|
/// \ingroup StreamFunctors
|
||||||
|
/// \brief Stream functor to allow inline set_width() calls.
|
||||||
|
///
|
||||||
|
/// Example: os << ios::width(15);
|
||||||
|
///
|
||||||
|
class width {
|
||||||
|
public:
|
||||||
|
inline explicit width (size_t nBytes) : _nBytes(nBytes) {}
|
||||||
|
inline ostringstream& apply (ostringstream& os) const { os.width (_nBytes); return os; }
|
||||||
|
inline void text_write (ostringstream& os) const { apply (os); }
|
||||||
|
private:
|
||||||
|
const size_t _nBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deprecated way to set output format base. Use setiosflags manipulator instead.
|
||||||
|
struct base {
|
||||||
|
inline explicit base (size_t n) : _f (n == 16 ? hex : (n == 8 ? oct : dec)) {}
|
||||||
|
inline void text_write (ostringstream& os) const { os.setf (_f, basefield); }
|
||||||
|
private:
|
||||||
|
fmtflags _f;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
13
pwn/flipper/dist/common/include/ustl/uiostream.h
vendored
Normal file
13
pwn/flipper/dist/common/include/ustl/uiostream.h
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sostream.h"
|
||||||
|
#include "mistream.h"
|
||||||
|
#include "outerrstream.h"
|
||||||
|
|
||||||
|
namespace ustl
|
||||||
|
{
|
||||||
|
|
||||||
|
extern coutclass& cout;
|
||||||
|
extern coutclass& cerr;
|
||||||
|
|
||||||
|
}
|
360
pwn/flipper/dist/common/include/ustl/uiterator.h
vendored
Normal file
360
pwn/flipper/dist/common/include/ustl/uiterator.h
vendored
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
//
|
||||||
|
/// \file uiterator.h
|
||||||
|
/// \brief Contains various iterator adapters.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "utypes.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename Category, typename T, typename Distance = ptrdiff_t, typename Pointer = T*, typename Reference = T&>
|
||||||
|
struct iterator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef Distance difference_type;
|
||||||
|
typedef Pointer pointer;
|
||||||
|
typedef Reference reference;
|
||||||
|
typedef Category iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct input_iterator_tag {};
|
||||||
|
struct output_iterator_tag {};
|
||||||
|
struct forward_iterator_tag {};
|
||||||
|
struct bidirectional_iterator_tag {};
|
||||||
|
struct random_access_iterator_tag {};
|
||||||
|
|
||||||
|
/// \struct iterator_traits uiterator.h ustl.h
|
||||||
|
/// \brief Contains the type traits of \p Iterator
|
||||||
|
///
|
||||||
|
template <typename Iterator>
|
||||||
|
struct iterator_traits {
|
||||||
|
typedef typename Iterator::value_type value_type;
|
||||||
|
typedef typename Iterator::difference_type difference_type;
|
||||||
|
typedef typename Iterator::pointer pointer;
|
||||||
|
typedef typename Iterator::reference reference;
|
||||||
|
typedef typename Iterator::iterator_category iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct iterator_traits<T*> {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef const T* const_pointer;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef random_access_iterator_tag iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct iterator_traits<const T*> {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef const T* const_pointer;
|
||||||
|
typedef const T* pointer;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const T& reference;
|
||||||
|
typedef random_access_iterator_tag iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_traits<void*> {
|
||||||
|
typedef uint8_t value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef const void* const_pointer;
|
||||||
|
typedef void* pointer;
|
||||||
|
typedef const value_type& const_reference;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef random_access_iterator_tag iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct iterator_traits<const void*> {
|
||||||
|
typedef uint8_t value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef const void* const_pointer;
|
||||||
|
typedef const void* pointer;
|
||||||
|
typedef const value_type& const_reference;
|
||||||
|
typedef const value_type& reference;
|
||||||
|
typedef random_access_iterator_tag iterator_category;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class reverse_iterator uiterator.h ustl.h
|
||||||
|
/// \ingroup IteratorAdaptors
|
||||||
|
/// \brief Wraps \p Iterator to behave in an exactly opposite manner.
|
||||||
|
///
|
||||||
|
template <typename Iterator>
|
||||||
|
class reverse_iterator {
|
||||||
|
public:
|
||||||
|
typedef typename iterator_traits<Iterator>::value_type value_type;
|
||||||
|
typedef typename iterator_traits<Iterator>::difference_type difference_type;
|
||||||
|
typedef typename iterator_traits<Iterator>::pointer pointer;
|
||||||
|
typedef typename iterator_traits<Iterator>::reference reference;
|
||||||
|
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
|
||||||
|
public:
|
||||||
|
reverse_iterator (void) : _i() {}
|
||||||
|
explicit reverse_iterator (Iterator iter) : _i (iter) {}
|
||||||
|
inline bool operator== (const reverse_iterator& iter) const { return _i == iter._i; }
|
||||||
|
inline bool operator< (const reverse_iterator& iter) const { return iter._i < _i; }
|
||||||
|
inline Iterator base (void) const { return _i; }
|
||||||
|
inline reference operator* (void) const { Iterator prev (_i); --prev; return *prev; }
|
||||||
|
inline pointer operator-> (void) const { return &(operator*()); }
|
||||||
|
inline reverse_iterator& operator++ (void) { -- _i; return *this; }
|
||||||
|
inline reverse_iterator& operator-- (void) { ++ _i; return *this; }
|
||||||
|
inline reverse_iterator operator++ (int) { reverse_iterator prev (*this); -- _i; return prev; }
|
||||||
|
inline reverse_iterator operator-- (int) { reverse_iterator prev (*this); ++ _i; return prev; }
|
||||||
|
inline reverse_iterator& operator+= (size_t n) { _i -= n; return *this; }
|
||||||
|
inline reverse_iterator& operator-= (size_t n) { _i += n; return *this; }
|
||||||
|
inline reverse_iterator operator+ (size_t n) const { return reverse_iterator (_i - n); }
|
||||||
|
inline reverse_iterator operator- (size_t n) const { return reverse_iterator (_i + n); }
|
||||||
|
inline reference operator[] (uoff_t n) const { return *(*this + n); }
|
||||||
|
inline difference_type operator- (const reverse_iterator& i) const { return distance (i._i, _i); }
|
||||||
|
protected:
|
||||||
|
Iterator _i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
inline reverse_iterator<Iterator> make_reverse_iterator (Iterator i)
|
||||||
|
{ return reverse_iterator<Iterator>(i); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
/// \class move_iterator uiterator.h ustl.h
|
||||||
|
/// \ingroup IteratorAdaptors
|
||||||
|
/// \brief Wraps \p Iterator to behave in an exactly opposite manner.
|
||||||
|
///
|
||||||
|
template <typename Iterator>
|
||||||
|
class move_iterator {
|
||||||
|
public:
|
||||||
|
using value_type = typename iterator_traits<Iterator>::value_type;
|
||||||
|
using difference_type = typename iterator_traits<Iterator>::difference_type;
|
||||||
|
using pointer = typename iterator_traits<Iterator>::pointer;
|
||||||
|
using reference = value_type&&;
|
||||||
|
using iterator_category = typename iterator_traits<Iterator>::iterator_category;
|
||||||
|
public:
|
||||||
|
move_iterator (void) : _i() {}
|
||||||
|
explicit move_iterator (Iterator iter) : _i (iter) {}
|
||||||
|
inline bool operator== (const move_iterator& iter) const { return _i == iter._i; }
|
||||||
|
inline bool operator< (const move_iterator& iter) const { return _i < iter._i; }
|
||||||
|
inline Iterator base (void) const { return _i; }
|
||||||
|
inline reference operator* (void) const { return move(*_i); }
|
||||||
|
inline pointer operator-> (void) const { return &*_i; }
|
||||||
|
inline move_iterator& operator++ (void) { ++_i; return *this; }
|
||||||
|
inline move_iterator& operator-- (void) { --_i; return *this; }
|
||||||
|
inline move_iterator operator++ (int) { move_iterator r (*this); ++ _i; return r; }
|
||||||
|
inline move_iterator operator-- (int) { move_iterator r (*this); -- _i; return r; }
|
||||||
|
inline move_iterator& operator+= (size_t n) { _i += n; return *this; }
|
||||||
|
inline move_iterator& operator-= (size_t n) { _i -= n; return *this; }
|
||||||
|
inline move_iterator operator+ (size_t n) const { return move_iterator (_i - n); }
|
||||||
|
inline move_iterator operator- (size_t n) const { return move_iterator (_i + n); }
|
||||||
|
inline reference operator[] (uoff_t n) const { return move(*(*this + n)); }
|
||||||
|
inline difference_type operator- (const move_iterator& i) const { return distance (_i, i._i); }
|
||||||
|
protected:
|
||||||
|
Iterator _i;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
inline move_iterator<Iterator> make_move_iterator (Iterator i)
|
||||||
|
{ return move_iterator<Iterator>(i); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class insert_iterator uiterator.h ustl.h
|
||||||
|
/// \ingroup IteratorAdaptors
|
||||||
|
/// \brief Calls insert on bound container for each assignment.
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
class insert_iterator {
|
||||||
|
public:
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::difference_type difference_type;
|
||||||
|
typedef typename Container::pointer pointer;
|
||||||
|
typedef typename Container::reference reference;
|
||||||
|
typedef typename Container::iterator iterator;
|
||||||
|
typedef output_iterator_tag iterator_category;
|
||||||
|
public:
|
||||||
|
explicit insert_iterator (Container& ctr, iterator ip) : _rctr (ctr), _ip (ip) {}
|
||||||
|
inline insert_iterator& operator= (typename Container::const_reference v)
|
||||||
|
{ _ip = _rctr.insert (_ip, v); return *this; }
|
||||||
|
inline insert_iterator& operator* (void) { return *this; }
|
||||||
|
inline insert_iterator& operator++ (void) { ++ _ip; return *this; }
|
||||||
|
inline insert_iterator operator++ (int) { insert_iterator prev (*this); ++_ip; return prev; }
|
||||||
|
protected:
|
||||||
|
Container& _rctr;
|
||||||
|
iterator _ip;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the insert_iterator for \p ctr.
|
||||||
|
template <typename Container>
|
||||||
|
inline insert_iterator<Container> inserter (Container& ctr, typename Container::iterator ip)
|
||||||
|
{ return insert_iterator<Container> (ctr, ip); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class back_insert_iterator uiterator.h ustl.h
|
||||||
|
/// \ingroup IteratorAdaptors
|
||||||
|
/// \brief Calls push_back on bound container for each assignment.
|
||||||
|
///
|
||||||
|
template <class Container>
|
||||||
|
class back_insert_iterator {
|
||||||
|
public:
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::difference_type difference_type;
|
||||||
|
typedef typename Container::pointer pointer;
|
||||||
|
typedef typename Container::reference reference;
|
||||||
|
typedef output_iterator_tag iterator_category;
|
||||||
|
public:
|
||||||
|
explicit back_insert_iterator (Container& ctr) : _rctr (ctr) {}
|
||||||
|
inline back_insert_iterator& operator= (typename Container::const_reference v)
|
||||||
|
{ _rctr.push_back (v); return *this; }
|
||||||
|
inline back_insert_iterator& operator* (void) { return *this; }
|
||||||
|
inline back_insert_iterator& operator++ (void) { return *this; }
|
||||||
|
inline back_insert_iterator operator++ (int) { return *this; }
|
||||||
|
protected:
|
||||||
|
Container& _rctr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the back_insert_iterator for \p ctr.
|
||||||
|
template <class Container>
|
||||||
|
inline back_insert_iterator<Container> back_inserter (Container& ctr)
|
||||||
|
{ return back_insert_iterator<Container> (ctr); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class front_insert_iterator uiterator.h ustl.h
|
||||||
|
/// \ingroup IteratorAdaptors
|
||||||
|
/// \brief Calls push_front on bound container for each assignment.
|
||||||
|
///
|
||||||
|
template <class Container>
|
||||||
|
class front_insert_iterator {
|
||||||
|
public:
|
||||||
|
typedef typename Container::value_type value_type;
|
||||||
|
typedef typename Container::difference_type difference_type;
|
||||||
|
typedef typename Container::pointer pointer;
|
||||||
|
typedef typename Container::reference reference;
|
||||||
|
typedef output_iterator_tag iterator_category;
|
||||||
|
public:
|
||||||
|
explicit front_insert_iterator (Container& ctr) : _rctr (ctr) {}
|
||||||
|
inline front_insert_iterator& operator= (typename Container::const_reference v)
|
||||||
|
{ _rctr.push_front (v); return *this; }
|
||||||
|
inline front_insert_iterator& operator* (void) { return *this; }
|
||||||
|
inline front_insert_iterator& operator++ (void) { return *this; }
|
||||||
|
inline front_insert_iterator operator++ (int) { return *this; }
|
||||||
|
protected:
|
||||||
|
Container& _rctr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the front_insert_iterator for \p ctr.
|
||||||
|
template <class Container>
|
||||||
|
inline front_insert_iterator<Container> front_inserter (Container& ctr)
|
||||||
|
{ return front_insert_iterator<Container> (ctr); }
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class index_iterate uiterator.h ustl.h
|
||||||
|
/// \ingroup IteratorAdaptors
|
||||||
|
///
|
||||||
|
/// \brief Allows iteration through an index container.
|
||||||
|
///
|
||||||
|
/// Converts an iterator into a container of uoff_t indexes to an
|
||||||
|
/// iterator of iterators into another container.
|
||||||
|
///
|
||||||
|
template <typename RandomAccessIterator, typename IndexIterator>
|
||||||
|
class index_iterate {
|
||||||
|
public:
|
||||||
|
typedef RandomAccessIterator value_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef RandomAccessIterator* pointer;
|
||||||
|
typedef RandomAccessIterator reference;
|
||||||
|
typedef random_access_iterator_tag iterator_category;
|
||||||
|
public:
|
||||||
|
index_iterate (void) : _base(), _i() {}
|
||||||
|
index_iterate (RandomAccessIterator ibase, IndexIterator iindex) : _base (ibase), _i (iindex) {}
|
||||||
|
inline bool operator== (const index_iterate& i) const { return _i == i._i; }
|
||||||
|
inline bool operator< (const index_iterate& i) const { return _i < i._i; }
|
||||||
|
inline bool operator== (const RandomAccessIterator& i) const { return _base == i; }
|
||||||
|
inline bool operator< (const RandomAccessIterator& i) const { return _base < i; }
|
||||||
|
inline IndexIterator base (void) const { return _i; }
|
||||||
|
inline reference operator* (void) const { return advance(_base, *_i); }
|
||||||
|
inline pointer operator-> (void) const { return &(operator*()); }
|
||||||
|
inline index_iterate& operator++ (void) { ++_i; return *this; }
|
||||||
|
inline index_iterate& operator-- (void) { --_i; return *this; }
|
||||||
|
inline index_iterate operator++ (int) { index_iterate prev (*this); ++_i; return prev; }
|
||||||
|
inline index_iterate operator-- (int) { index_iterate prev (*this); --_i; return prev; }
|
||||||
|
inline index_iterate& operator+= (size_t n) { _i += n; return *this; }
|
||||||
|
inline index_iterate& operator-= (size_t n) { _i -= n; return *this; }
|
||||||
|
inline index_iterate operator+ (size_t n) const { return index_iterate (_base, _i + n); }
|
||||||
|
inline index_iterate operator- (size_t n) const { return index_iterate (_base, _i - n); }
|
||||||
|
inline reference operator[] (uoff_t n) const { return *(*this + n); }
|
||||||
|
inline difference_type operator- (const index_iterate& i) const { return distance (_i, i._i); }
|
||||||
|
private:
|
||||||
|
RandomAccessIterator _base;
|
||||||
|
IndexIterator _i;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns an index_iterate for \p ibase over \p iindex.
|
||||||
|
template <typename RandomAccessIterator, typename IndexIterator>
|
||||||
|
inline index_iterate<RandomAccessIterator, IndexIterator> index_iterator (RandomAccessIterator ibase, IndexIterator iindex)
|
||||||
|
{
|
||||||
|
return index_iterate<RandomAccessIterator, IndexIterator> (ibase, iindex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts the indexes in \p xc to iterators in \p ic of base \p ibase.
|
||||||
|
template <typename IndexContainer, typename IteratorContainer>
|
||||||
|
inline void indexv_to_iteratorv (typename IteratorContainer::value_type ibase, const IndexContainer& xc, IteratorContainer& ic)
|
||||||
|
{
|
||||||
|
ic.resize (xc.size());
|
||||||
|
copy_n (index_iterator (ibase, xc.begin()), xc.size(), ic.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Converts the given const_iterator into an iterator.
|
||||||
|
///
|
||||||
|
template <typename Container>
|
||||||
|
inline typename Container::iterator unconst (typename Container::const_iterator i, Container&)
|
||||||
|
{ return const_cast<typename Container::iterator>(i); }
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
#define IBYI(Iter1, Iter2, Ctr1, Ctr2) \
|
||||||
|
template <typename Container1, typename Container2> \
|
||||||
|
inline typename Container2::Iter2 ibyi (typename Container1::Iter1 idx, Ctr1& ctr1, Ctr2& ctr2) \
|
||||||
|
{ \
|
||||||
|
assert (ctr1.size() == ctr2.size()); \
|
||||||
|
return ctr2.begin() + (idx - ctr1.begin()); \
|
||||||
|
}
|
||||||
|
|
||||||
|
IBYI(const_iterator, const_iterator, const Container1, const Container2)
|
||||||
|
IBYI(iterator, iterator, Container1, Container2)
|
||||||
|
IBYI(const_iterator, iterator, const Container1, Container2)
|
||||||
|
IBYI(iterator, const_iterator, Container1, const Container2)
|
||||||
|
|
||||||
|
#else // DOXYGEN
|
||||||
|
|
||||||
|
#error "This declaration is for doxygen only; it is not compiled."
|
||||||
|
|
||||||
|
/// Converts a const_iterator in one container into a const_iterator in another container.
|
||||||
|
template <typename Container1, typename Container2>
|
||||||
|
inline typename Container2::iterator ibyi (typename Container1::iterator idx, Container1& ctr1, Container2& ctr2) {}
|
||||||
|
|
||||||
|
#endif // DOXYGEN
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace ustl
|
324
pwn/flipper/dist/common/include/ustl/ulimits.h
vendored
Normal file
324
pwn/flipper/dist/common/include/ustl/ulimits.h
vendored
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "utypes.h"
|
||||||
|
#include "traits.h"
|
||||||
|
#if HAVE_CPP11
|
||||||
|
#include "uttraits.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
enum float_denorm_style {
|
||||||
|
denorm_indeterminate = -1,
|
||||||
|
denorm_absent,
|
||||||
|
denorm_present
|
||||||
|
};
|
||||||
|
|
||||||
|
enum float_round_style {
|
||||||
|
round_indeterminate = -1,
|
||||||
|
round_toward_zero,
|
||||||
|
round_to_nearest,
|
||||||
|
round_toward_infinity,
|
||||||
|
round_toward_neg_infinity
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename T>
|
||||||
|
struct __limits_digits { enum { value = sizeof(T)*8 };};
|
||||||
|
template <typename T>
|
||||||
|
struct __limits_digits10 { enum { value = sizeof(T)*8*643/2136+1 };};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \class numeric_limits ulimits.h ustl.h
|
||||||
|
/// \brief Defines numeric limits for a type.
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
struct numeric_limits {
|
||||||
|
static inline constexpr T min (void) { return T(); } // Returns the minimum value for type T.
|
||||||
|
static inline constexpr T max (void) { return T(); } // Returns the minimum value for type T.
|
||||||
|
static inline constexpr T lowest (void) { return T(); }
|
||||||
|
static inline constexpr T epsilon (void) { return T(); }
|
||||||
|
static inline constexpr T round_error (void) { return T(); }
|
||||||
|
static inline constexpr T infinity (void) { return T(); }
|
||||||
|
static inline constexpr T quiet_NaN (void) { return T(); }
|
||||||
|
static inline constexpr T signaling_NaN (void) { return T(); }
|
||||||
|
static inline constexpr T denorm_min (void) { return T(); }
|
||||||
|
static constexpr const bool is_specialized = false;
|
||||||
|
static constexpr const bool is_signed = tm::TypeTraits<T>::isSigned; ///< True if the type is signed.
|
||||||
|
static constexpr const bool is_integer = tm::TypeTraits<T>::isIntegral; ///< True if stores an exact value.
|
||||||
|
static constexpr const bool is_exact = tm::TypeTraits<T>::isIntegral; ///< True if stores an exact value.
|
||||||
|
static constexpr const bool is_integral = tm::TypeTraits<T>::isFundamental; ///< True if fixed size and cast-copyable.
|
||||||
|
static constexpr const bool is_iec559 = false;
|
||||||
|
static constexpr const bool is_bounded = false;
|
||||||
|
static constexpr const bool is_modulo = false;
|
||||||
|
static constexpr const bool has_infinity = false;
|
||||||
|
static constexpr const bool has_quiet_NaN = false;
|
||||||
|
static constexpr const bool has_signaling_NaN = false;
|
||||||
|
static constexpr const bool has_denorm_loss = false;
|
||||||
|
static constexpr const bool traps = false;
|
||||||
|
static constexpr const bool tinyness_before = false;
|
||||||
|
static constexpr const int radix = 0;
|
||||||
|
static constexpr const int min_exponent = 0;
|
||||||
|
static constexpr const int min_exponent10 = 0;
|
||||||
|
static constexpr const int max_exponent = 0;
|
||||||
|
static constexpr const int max_exponent10 = 0;
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_absent;
|
||||||
|
static constexpr const float_round_style round_style = round_toward_zero;
|
||||||
|
static constexpr const unsigned digits = __limits_digits<T>::value; ///< Number of bits in T
|
||||||
|
static constexpr const unsigned digits10 = 0;
|
||||||
|
static constexpr const unsigned max_digits10 = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct numeric_limits<T*> {
|
||||||
|
static inline constexpr T* min (void) { return nullptr; }
|
||||||
|
static inline constexpr T* max (void) { return reinterpret_cast<T*>(UINTPTR_MAX); }
|
||||||
|
static inline constexpr T* lowest (void) { return nullptr; }
|
||||||
|
static inline constexpr T* epsilon (void) { return nullptr; }
|
||||||
|
static inline constexpr T* round_error (void) { return nullptr; }
|
||||||
|
static inline constexpr T* infinity (void) { return nullptr; }
|
||||||
|
static inline constexpr T* quiet_NaN (void) { return nullptr; }
|
||||||
|
static inline constexpr T* signaling_NaN (void) { return nullptr; }
|
||||||
|
static inline constexpr T* denorm_min (void) { return nullptr; }
|
||||||
|
static constexpr const bool is_specialized = false;
|
||||||
|
static constexpr const bool is_signed = false;
|
||||||
|
static constexpr const bool is_integer = true;
|
||||||
|
static constexpr const bool is_exact = true;
|
||||||
|
static constexpr const bool is_integral = true;
|
||||||
|
static constexpr const bool is_iec559 = false;
|
||||||
|
static constexpr const bool is_bounded = true;
|
||||||
|
static constexpr const bool is_modulo = true;
|
||||||
|
static constexpr const bool has_infinity = false;
|
||||||
|
static constexpr const bool has_quiet_NaN = false;
|
||||||
|
static constexpr const bool has_signaling_NaN = false;
|
||||||
|
static constexpr const bool has_denorm_loss = false;
|
||||||
|
static constexpr const bool traps = false;
|
||||||
|
static constexpr const bool tinyness_before = false;
|
||||||
|
static constexpr const int radix = 2;
|
||||||
|
static constexpr const int min_exponent = 0;
|
||||||
|
static constexpr const int min_exponent10 = 0;
|
||||||
|
static constexpr const int max_exponent = 0;
|
||||||
|
static constexpr const int max_exponent10 = 0;
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_absent;
|
||||||
|
static constexpr const float_round_style round_style = round_toward_zero;
|
||||||
|
static constexpr const unsigned digits = __limits_digits<T*>::value;
|
||||||
|
static constexpr const unsigned digits10 = __limits_digits10<T*>::value;
|
||||||
|
static constexpr const unsigned max_digits10 = 0;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
template <> struct numeric_limits<float> {
|
||||||
|
static inline constexpr float min (void) { return FLT_MIN; }
|
||||||
|
static inline constexpr float max (void) { return FLT_MAX; }
|
||||||
|
static inline constexpr float lowest (void) { return -FLT_MAX; }
|
||||||
|
static inline constexpr float epsilon (void) { return FLT_EPSILON; }
|
||||||
|
static inline constexpr float round_error (void) { return 0.5f; }
|
||||||
|
static inline constexpr float infinity (void) { return __builtin_huge_valf(); }
|
||||||
|
static inline constexpr float quiet_NaN (void) { return __builtin_nanf(""); }
|
||||||
|
static inline constexpr float signaling_NaN (void) { return __builtin_nansf(""); }
|
||||||
|
static inline constexpr float denorm_min (void) { return __FLT_DENORM_MIN__; }
|
||||||
|
static constexpr const bool is_specialized = true;
|
||||||
|
static constexpr const bool is_signed = true;
|
||||||
|
static constexpr const bool is_integer = false;
|
||||||
|
static constexpr const bool is_exact = false;
|
||||||
|
static constexpr const bool is_integral = true;
|
||||||
|
static constexpr const bool is_iec559 = true;
|
||||||
|
static constexpr const bool is_bounded = true;
|
||||||
|
static constexpr const bool is_modulo = false;
|
||||||
|
static constexpr const bool has_infinity = __FLT_HAS_INFINITY__;
|
||||||
|
static constexpr const bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_signaling_NaN = __FLT_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_denorm_loss = true;
|
||||||
|
static constexpr const bool traps = false;
|
||||||
|
static constexpr const bool tinyness_before = true;
|
||||||
|
static constexpr const int radix = FLT_RADIX;
|
||||||
|
static constexpr const int min_exponent = FLT_MIN_EXP;
|
||||||
|
static constexpr const int min_exponent10 = FLT_MIN_10_EXP;
|
||||||
|
static constexpr const int max_exponent = FLT_MAX_EXP;
|
||||||
|
static constexpr const int max_exponent10 = FLT_MAX_10_EXP;
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_present;
|
||||||
|
static constexpr const float_round_style round_style = round_to_nearest;
|
||||||
|
static constexpr const unsigned digits = FLT_MANT_DIG;
|
||||||
|
static constexpr const unsigned digits10 = FLT_DIG;
|
||||||
|
static constexpr const unsigned max_digits10 = FLT_MANT_DIG;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct numeric_limits<double> {
|
||||||
|
static inline constexpr double min (void) { return DBL_MIN; }
|
||||||
|
static inline constexpr double max (void) { return DBL_MAX; }
|
||||||
|
static inline constexpr double lowest (void) { return -DBL_MAX; }
|
||||||
|
static inline constexpr double epsilon (void) { return DBL_EPSILON; }
|
||||||
|
static inline constexpr double round_error (void) { return 0.5; }
|
||||||
|
static inline constexpr double infinity (void) { return __builtin_huge_val(); }
|
||||||
|
static inline constexpr double quiet_NaN (void) { return __builtin_nan(""); }
|
||||||
|
static inline constexpr double signaling_NaN (void) { return __builtin_nans(""); }
|
||||||
|
static inline constexpr double denorm_min (void) { return __DBL_DENORM_MIN__; }
|
||||||
|
static constexpr const bool is_specialized = true;
|
||||||
|
static constexpr const bool is_signed = true;
|
||||||
|
static constexpr const bool is_integer = false;
|
||||||
|
static constexpr const bool is_exact = false;
|
||||||
|
static constexpr const bool is_integral = true;
|
||||||
|
static constexpr const bool is_iec559 = true;
|
||||||
|
static constexpr const bool is_bounded = true;
|
||||||
|
static constexpr const bool is_modulo = false;
|
||||||
|
static constexpr const bool has_infinity = __DBL_HAS_INFINITY__;
|
||||||
|
static constexpr const bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_signaling_NaN = __DBL_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_denorm_loss = true;
|
||||||
|
static constexpr const bool traps = false;
|
||||||
|
static constexpr const bool tinyness_before = true;
|
||||||
|
static constexpr const int radix = FLT_RADIX;
|
||||||
|
static constexpr const int min_exponent = DBL_MIN_EXP;
|
||||||
|
static constexpr const int min_exponent10 = DBL_MIN_10_EXP;
|
||||||
|
static constexpr const int max_exponent = DBL_MAX_EXP;
|
||||||
|
static constexpr const int max_exponent10 = DBL_MAX_10_EXP;
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_present;
|
||||||
|
static constexpr const float_round_style round_style = round_to_nearest;
|
||||||
|
static constexpr const unsigned digits = DBL_MANT_DIG;
|
||||||
|
static constexpr const unsigned digits10 = DBL_DIG;
|
||||||
|
static constexpr const unsigned max_digits10 = DBL_MANT_DIG;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct numeric_limits<long double> {
|
||||||
|
static inline constexpr long double min (void) { return LDBL_MIN; }
|
||||||
|
static inline constexpr long double max (void) { return LDBL_MAX; }
|
||||||
|
static inline constexpr long double lowest (void) { return -LDBL_MAX; }
|
||||||
|
static inline constexpr long double epsilon (void) { return LDBL_EPSILON; }
|
||||||
|
static inline constexpr long double round_error (void) { return 0.5l; }
|
||||||
|
static inline constexpr long double infinity (void) { return __builtin_huge_vall(); }
|
||||||
|
static inline constexpr long double quiet_NaN (void) { return __builtin_nanl(""); }
|
||||||
|
static inline constexpr long double signaling_NaN (void) { return __builtin_nansl(""); }
|
||||||
|
static inline constexpr long double denorm_min (void) { return __LDBL_DENORM_MIN__; }
|
||||||
|
static constexpr const bool is_specialized = true;
|
||||||
|
static constexpr const bool is_signed = true;
|
||||||
|
static constexpr const bool is_integer = false;
|
||||||
|
static constexpr const bool is_exact = false;
|
||||||
|
static constexpr const bool is_integral = true;
|
||||||
|
static constexpr const bool is_iec559 = true;
|
||||||
|
static constexpr const bool is_bounded = true;
|
||||||
|
static constexpr const bool is_modulo = false;
|
||||||
|
static constexpr const bool has_infinity = __LDBL_HAS_INFINITY__;
|
||||||
|
static constexpr const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_signaling_NaN = __LDBL_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_denorm_loss = true;
|
||||||
|
static constexpr const bool traps = false;
|
||||||
|
static constexpr const bool tinyness_before = true;
|
||||||
|
static constexpr const int radix = FLT_RADIX;
|
||||||
|
static constexpr const int min_exponent = LDBL_MIN_EXP;
|
||||||
|
static constexpr const int min_exponent10 = LDBL_MIN_10_EXP;
|
||||||
|
static constexpr const int max_exponent = LDBL_MAX_EXP;
|
||||||
|
static constexpr const int max_exponent10 = LDBL_MAX_10_EXP;
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_present;
|
||||||
|
static constexpr const float_round_style round_style = round_to_nearest;
|
||||||
|
static constexpr const unsigned digits = LDBL_MANT_DIG;
|
||||||
|
static constexpr const unsigned digits10 = LDBL_DIG;
|
||||||
|
static constexpr const unsigned max_digits10 = LDBL_MANT_DIG;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct numeric_limits<long double> {
|
||||||
|
static inline constexpr long double min (void) { return LDBL_MIN; }
|
||||||
|
static inline constexpr long double max (void) { return LDBL_MAX; }
|
||||||
|
static inline constexpr long double lowest (void) { return -LDBL_MAX; }
|
||||||
|
static inline constexpr long double epsilon (void) { return LDBL_EPSILON; }
|
||||||
|
static inline constexpr long double round_error (void) { return 0.5l; }
|
||||||
|
static inline constexpr long double infinity (void) { return __builtin_huge_vall(); }
|
||||||
|
static inline constexpr long double quiet_NaN (void) { return __builtin_nanl(""); }
|
||||||
|
static inline constexpr long double signaling_NaN (void) { return __builtin_nansl(""); }
|
||||||
|
static inline constexpr long double denorm_min (void) { return __LDBL_DENORM_MIN__; }
|
||||||
|
static constexpr const bool is_specialized = true;
|
||||||
|
static constexpr const bool is_signed = true;
|
||||||
|
static constexpr const bool is_integer = false;
|
||||||
|
static constexpr const bool is_exact = false;
|
||||||
|
static constexpr const bool is_integral = true;
|
||||||
|
static constexpr const bool is_iec559 = true;
|
||||||
|
static constexpr const bool is_bounded = true;
|
||||||
|
static constexpr const bool is_modulo = false;
|
||||||
|
static constexpr const bool has_infinity = __LDBL_HAS_INFINITY__;
|
||||||
|
static constexpr const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_signaling_NaN = __LDBL_HAS_QUIET_NAN__;
|
||||||
|
static constexpr const bool has_denorm_loss = true;
|
||||||
|
static constexpr const bool traps = false;
|
||||||
|
static constexpr const bool tinyness_before = true;
|
||||||
|
static constexpr const int radix = FLT_RADIX;
|
||||||
|
static constexpr const int min_exponent = LDBL_MIN_EXP;
|
||||||
|
static constexpr const int min_exponent10 = LDBL_MIN_10_EXP;
|
||||||
|
static constexpr const int max_exponent = LDBL_MAX_EXP;
|
||||||
|
static constexpr const int max_exponent10 = LDBL_MAX_10_EXP;
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_present;
|
||||||
|
static constexpr const float_round_style round_style = round_to_nearest;
|
||||||
|
static constexpr const unsigned digits = LDBL_MANT_DIG;
|
||||||
|
static constexpr const unsigned digits10 = LDBL_DIG;
|
||||||
|
static constexpr const unsigned max_digits10 = LDBL_MANT_DIG;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
#define _NUMERIC_LIMITS(type, minVal, maxVal, bSigned, bInteger, bIntegral) \
|
||||||
|
template <> struct numeric_limits<type> { \
|
||||||
|
static inline constexpr type min (void) { return minVal; } \
|
||||||
|
static inline constexpr type max (void) { return maxVal; } \
|
||||||
|
static inline constexpr type lowest (void) { return minVal; } \
|
||||||
|
static inline constexpr type epsilon (void) { return 0; } \
|
||||||
|
static inline constexpr type round_error (void) { return 0; } \
|
||||||
|
static inline constexpr type infinity (void) { return 0; } \
|
||||||
|
static inline constexpr type quiet_NaN (void) { return 0; } \
|
||||||
|
static inline constexpr type signaling_NaN (void) { return 0; } \
|
||||||
|
static inline constexpr type denorm_min (void) { return 0; } \
|
||||||
|
static constexpr const bool is_specialized = true; \
|
||||||
|
static constexpr const bool is_signed = bSigned; \
|
||||||
|
static constexpr const bool is_integer = bInteger; \
|
||||||
|
static constexpr const bool is_exact = bInteger; \
|
||||||
|
static constexpr const bool is_integral = bIntegral; \
|
||||||
|
static constexpr const bool is_iec559 = false; \
|
||||||
|
static constexpr const bool is_bounded = true; \
|
||||||
|
static constexpr const bool is_modulo = bIntegral; \
|
||||||
|
static constexpr const bool has_infinity = false; \
|
||||||
|
static constexpr const bool has_quiet_NaN = false; \
|
||||||
|
static constexpr const bool has_signaling_NaN = false; \
|
||||||
|
static constexpr const bool has_denorm_loss = false; \
|
||||||
|
static constexpr const bool traps = false; \
|
||||||
|
static constexpr const bool tinyness_before = false; \
|
||||||
|
static constexpr const int radix = 2; \
|
||||||
|
static constexpr const int min_exponent = 0; \
|
||||||
|
static constexpr const int min_exponent10 = 0; \
|
||||||
|
static constexpr const int max_exponent = 0; \
|
||||||
|
static constexpr const int max_exponent10 = 0; \
|
||||||
|
static constexpr const float_denorm_style has_denorm = denorm_absent; \
|
||||||
|
static constexpr const float_round_style round_style = round_toward_zero; \
|
||||||
|
static constexpr const unsigned digits = __limits_digits<type>::value; \
|
||||||
|
static constexpr const unsigned digits10 = __limits_digits10<type>::value; \
|
||||||
|
static constexpr const unsigned max_digits10 = 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// type min max signed integer integral
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
_NUMERIC_LIMITS (bool, false, true, false, false, true);
|
||||||
|
_NUMERIC_LIMITS (char, CHAR_MIN, CHAR_MAX, true, true, true);
|
||||||
|
_NUMERIC_LIMITS (int, INT_MIN, INT_MAX, true, true, true);
|
||||||
|
_NUMERIC_LIMITS (short, SHRT_MIN, SHRT_MAX, true, true, true);
|
||||||
|
_NUMERIC_LIMITS (long, LONG_MIN, LONG_MAX, true, true, true);
|
||||||
|
#if HAVE_THREE_CHAR_TYPES
|
||||||
|
_NUMERIC_LIMITS (signed char, SCHAR_MIN, SCHAR_MAX, true, true, true);
|
||||||
|
#endif
|
||||||
|
_NUMERIC_LIMITS (unsigned char, 0, UCHAR_MAX, false, true, true);
|
||||||
|
_NUMERIC_LIMITS (unsigned int, 0, UINT_MAX, false, true, true);
|
||||||
|
_NUMERIC_LIMITS (unsigned short,0, USHRT_MAX, false, true, true);
|
||||||
|
_NUMERIC_LIMITS (unsigned long, 0, ULONG_MAX, false, true, true);
|
||||||
|
_NUMERIC_LIMITS (wchar_t, 0, WCHAR_MAX, false, true, true);
|
||||||
|
#if HAVE_LONG_LONG
|
||||||
|
_NUMERIC_LIMITS (long long, LLONG_MIN, LLONG_MAX, true, true, true);
|
||||||
|
_NUMERIC_LIMITS (unsigned long long, 0, ULLONG_MAX, false, true, true);
|
||||||
|
#endif
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
/// Macro for defining numeric_limits specializations
|
||||||
|
#define NUMERIC_LIMITS(type, minVal, maxVal, bSigned, bInteger, bIntegral) \
|
||||||
|
namespace ustl { _NUMERIC_LIMITS (type, minVal, maxVal, bSigned, bInteger, bIntegral); }
|
||||||
|
|
||||||
|
} // namespace ustl
|
85
pwn/flipper/dist/common/include/ustl/ulist.h
vendored
Normal file
85
pwn/flipper/dist/common/include/ustl/ulist.h
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "uvector.h"
|
||||||
|
#include "uctralgo.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \class list ulist.h ustl.h
|
||||||
|
/// \ingroup Sequences
|
||||||
|
///
|
||||||
|
/// \brief Linked list, defined as an alias to vector.
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
class list : public vector<T> {
|
||||||
|
public:
|
||||||
|
typedef typename vector<T>::size_type size_type;
|
||||||
|
typedef typename vector<T>::iterator iterator;
|
||||||
|
typedef typename vector<T>::const_iterator const_iterator;
|
||||||
|
typedef typename vector<T>::reference reference;
|
||||||
|
typedef typename vector<T>::const_reference const_reference;
|
||||||
|
public:
|
||||||
|
inline list (void) : vector<T> () {}
|
||||||
|
inline explicit list (size_type n) : vector<T> (n) {}
|
||||||
|
inline list (size_type n, const T& v) : vector<T> (n, v) {}
|
||||||
|
inline list (const list<T>& v) : vector<T> (v) {}
|
||||||
|
inline list (const_iterator i1, const_iterator i2) : vector<T> (i1, i2) {}
|
||||||
|
inline size_type size (void) const { return vector<T>::size(); }
|
||||||
|
inline iterator begin (void) { return vector<T>::begin(); }
|
||||||
|
inline const_iterator begin (void) const { return vector<T>::begin(); }
|
||||||
|
inline iterator end (void) { return vector<T>::end(); }
|
||||||
|
inline const_iterator end (void) const { return vector<T>::end(); }
|
||||||
|
inline void push_front (const T& v) { this->insert (begin(), v); }
|
||||||
|
inline void pop_front (void) { this->erase (begin()); }
|
||||||
|
inline const_reference front (void) const { return *begin(); }
|
||||||
|
inline reference front (void) { return *begin(); }
|
||||||
|
inline void remove (const T& v) { ::ustl::remove (*this, v); }
|
||||||
|
template <typename Predicate>
|
||||||
|
inline void remove_if (Predicate p) { ::ustl::remove_if (*this, p); }
|
||||||
|
inline void reverse (void) { ::ustl::reverse (*this); }
|
||||||
|
inline void unique (void) { ::ustl::unique (*this); }
|
||||||
|
inline void sort (void) { ::ustl::sort (*this); }
|
||||||
|
void merge (list<T>& l);
|
||||||
|
void splice (iterator ip, list<T>& l, iterator first = nullptr, iterator last = nullptr);
|
||||||
|
#if HAVE_CPP11
|
||||||
|
inline list (list&& v) : vector<T> (move(v)) {}
|
||||||
|
inline list (std::initializer_list<T> v) : vector<T>(v) {}
|
||||||
|
inline list& operator= (list&& v) { vector<T>::operator= (move(v)); return *this; }
|
||||||
|
template <typename... Args>
|
||||||
|
inline void emplace_front (Args&&... args) { vector<T>::emplace (begin(), forward<Args>(args)...); }
|
||||||
|
inline void push_front (T&& v) { emplace_front (move(v)); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Merges the contents with \p l. Assumes both lists are sorted.
|
||||||
|
template <typename T>
|
||||||
|
void list<T>::merge (list& l)
|
||||||
|
{
|
||||||
|
this->insert_space (begin(), l.size());
|
||||||
|
::ustl::merge (this->iat(l.size()), end(), l.begin(), l.end(), begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moves the range [first, last) from \p l to this list at \p ip.
|
||||||
|
template <typename T>
|
||||||
|
void list<T>::splice (iterator ip, list<T>& l, iterator first, iterator last)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
first = l.begin();
|
||||||
|
if (!last)
|
||||||
|
last = l.end();
|
||||||
|
this->insert (ip, first, last);
|
||||||
|
l.erase (first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
template <typename T> using deque = list<T>;
|
||||||
|
#else
|
||||||
|
#define deque list ///< list has all the functionality provided by deque
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ustl
|
168
pwn/flipper/dist/common/include/ustl/umap.h
vendored
Normal file
168
pwn/flipper/dist/common/include/ustl/umap.h
vendored
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "uvector.h"
|
||||||
|
#include "ufunction.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
template <typename Pair, typename Comp>
|
||||||
|
struct pair_compare_first : public binary_function<Pair,Pair,bool> {
|
||||||
|
inline bool operator()(const Pair& a, const Pair& b) { return Comp()(a.first,b.first); }
|
||||||
|
};
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
struct pair_compare_first_key : public binary_function<pair<K,V>,K,bool> {
|
||||||
|
inline bool operator()(const pair<K,V>& a, const K& b) { return Comp()(a.first,b); }
|
||||||
|
inline bool operator()(const K& a, const pair<K,V>& b) { return Comp()(a,b.first); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \class map umap.h ustl.h
|
||||||
|
/// \ingroup AssociativeContainers
|
||||||
|
///
|
||||||
|
/// \brief A sorted associative container of pair<K,V>
|
||||||
|
///
|
||||||
|
template <typename K, typename V, typename Comp = less<K> >
|
||||||
|
class map : public vector<pair<K,V> > {
|
||||||
|
public:
|
||||||
|
typedef K key_type;
|
||||||
|
typedef V data_type;
|
||||||
|
typedef const K& const_key_ref;
|
||||||
|
typedef const V& const_data_ref;
|
||||||
|
typedef const map<K,V,Comp>& rcself_t;
|
||||||
|
typedef vector<pair<K,V> > base_class;
|
||||||
|
typedef typename base_class::value_type value_type;
|
||||||
|
typedef typename base_class::size_type size_type;
|
||||||
|
typedef typename base_class::pointer pointer;
|
||||||
|
typedef typename base_class::const_pointer const_pointer;
|
||||||
|
typedef typename base_class::reference reference;
|
||||||
|
typedef typename base_class::const_reference const_reference;
|
||||||
|
typedef typename base_class::const_iterator const_iterator;
|
||||||
|
typedef typename base_class::iterator iterator;
|
||||||
|
typedef typename base_class::reverse_iterator reverse_iterator;
|
||||||
|
typedef typename base_class::const_reverse_iterator const_reverse_iterator;
|
||||||
|
typedef pair<const_iterator,const_iterator> const_range_t;
|
||||||
|
typedef pair<iterator,iterator> range_t;
|
||||||
|
typedef pair<iterator,bool> insertrv_t;
|
||||||
|
typedef Comp key_compare;
|
||||||
|
typedef pair_compare_first<value_type,Comp> value_compare;
|
||||||
|
typedef pair_compare_first_key<K,V,Comp> value_key_compare;
|
||||||
|
public:
|
||||||
|
inline map (void) : base_class() {}
|
||||||
|
explicit inline map (size_type n) : base_class (n) {}
|
||||||
|
inline map (rcself_t v) : base_class (v) {}
|
||||||
|
inline map (const_iterator i1, const_iterator i2) : base_class() { insert (i1, i2); }
|
||||||
|
inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return *this; }
|
||||||
|
inline const_data_ref at (const_key_ref k) const { assert (find(k) != end()); return find(k)->second; }
|
||||||
|
inline data_type& at (const_key_ref k) { assert (find(k) != end()); return find(k)->second; }
|
||||||
|
inline const_data_ref operator[] (const_key_ref i) const { return at(i); }
|
||||||
|
data_type& operator[] (const_key_ref i);
|
||||||
|
inline key_compare key_comp (void) const { return key_compare(); }
|
||||||
|
inline value_compare value_comp (void) const { return value_compare(); }
|
||||||
|
inline size_type size (void) const { return base_class::size(); }
|
||||||
|
inline iterator begin (void) { return base_class::begin(); }
|
||||||
|
inline const_iterator begin (void) const { return base_class::begin(); }
|
||||||
|
inline iterator end (void) { return base_class::end(); }
|
||||||
|
inline const_iterator end (void) const { return base_class::end(); }
|
||||||
|
inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); }
|
||||||
|
inline void push_back (const_reference v) { insert (v); }
|
||||||
|
inline const_iterator find (const_key_ref k) const;
|
||||||
|
inline iterator find (const_key_ref k) { return const_cast<iterator> (const_cast<rcself_t>(*this).find (k)); }
|
||||||
|
inline const_iterator find_data (const_data_ref v, const_iterator first = nullptr, const_iterator last = nullptr) const;
|
||||||
|
inline iterator find_data (const_data_ref v, iterator first = nullptr, iterator last = nullptr) { return const_cast<iterator> (find_data (v, const_cast<const_iterator>(first), const_cast<const_iterator>(last))); }
|
||||||
|
const_iterator lower_bound (const_key_ref k) const { return ::ustl::lower_bound (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline iterator lower_bound (const_key_ref k) { return const_cast<iterator>(const_cast<rcself_t>(*this).lower_bound (k)); }
|
||||||
|
const_iterator upper_bound (const_key_ref k) const { return ::ustl::upper_bound (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline iterator upper_bound (const_key_ref k) { return const_cast<iterator>(const_cast<rcself_t>(*this).upper_bound (k)); }
|
||||||
|
const_range_t equal_range (const_key_ref k) const { return ::ustl::equal_range (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline range_t equal_range (const_key_ref k) { return ::ustl::equal_range (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline size_type count (const_key_ref v) const { const_range_t r = equal_range(v); return distance(r.first,r.second); }
|
||||||
|
insertrv_t insert (const_reference v);
|
||||||
|
inline iterator insert (const_iterator, const_reference v) { return insert(v).first; }
|
||||||
|
void insert (const_iterator i1, const_iterator i2) { for (; i1 != i2; ++i1) insert (*i1); }
|
||||||
|
inline void erase (const_key_ref k);
|
||||||
|
inline iterator erase (iterator ep) { return base_class::erase (ep); }
|
||||||
|
inline iterator erase (iterator ep1, iterator ep2) { return base_class::erase (ep1, ep2); }
|
||||||
|
inline void clear (void) { base_class::clear(); }
|
||||||
|
inline void swap (map& v) { base_class::swap (v); }
|
||||||
|
#if HAVE_CPP11
|
||||||
|
using initlist_t = std::initializer_list<value_type>;
|
||||||
|
inline map (map&& v) : base_class (move(v)) {}
|
||||||
|
inline map (initlist_t v) : base_class() { insert (v.begin(), v.end()); }
|
||||||
|
inline map& operator= (map&& v) { base_class::operator= (move(v)); return *this; }
|
||||||
|
insertrv_t insert (value_type&& v);
|
||||||
|
inline iterator insert (const_iterator, value_type&& v) { return insert(move(v)).first; }
|
||||||
|
inline void insert (initlist_t v) { insert (v.begin(), v.end()); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline insertrv_t emplace (Args&&... args) { return insert (value_type(forward<Args>(args)...)); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace_hint (const_iterator h, Args&&... args) { return insert (h, value_type(forward<Args>(args)...)); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline insertrv_t emplace_back (Args&&... args) { return insert (value_type(forward<Args>(args)...)); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the pair<K,V> where K = \p k.
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
inline typename map<K,V,Comp>::const_iterator map<K,V,Comp>::find (const_key_ref k) const
|
||||||
|
{
|
||||||
|
const_iterator i = lower_bound (k);
|
||||||
|
return (i < end() && Comp()(k,i->first)) ? end() : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the pair<K,V> where V = \p v, occuring in range [first,last).
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
inline typename map<K,V,Comp>::const_iterator map<K,V,Comp>::find_data (const_data_ref v, const_iterator first, const_iterator last) const
|
||||||
|
{
|
||||||
|
if (!first) first = begin();
|
||||||
|
if (!last) last = end();
|
||||||
|
for (; first != last && first->second != v; ++first) ;
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns data associated with key \p k.
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
typename map<K,V,Comp>::data_type& map<K,V,Comp>::operator[] (const_key_ref k)
|
||||||
|
{
|
||||||
|
iterator ip = lower_bound (k);
|
||||||
|
if (ip == end() || Comp()(k,ip->first))
|
||||||
|
ip = base_class::insert (ip, make_pair (k, V()));
|
||||||
|
return ip->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inserts the pair into the container.
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
typename map<K,V,Comp>::insertrv_t map<K,V,Comp>::insert (const_reference v)
|
||||||
|
{
|
||||||
|
iterator ip = lower_bound (v.first);
|
||||||
|
bool bInserted = ip == end() || Comp()(v.first, ip->first);
|
||||||
|
if (bInserted)
|
||||||
|
ip = base_class::insert (ip, v);
|
||||||
|
return make_pair (ip, bInserted);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
/// Inserts the pair into the container.
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
typename map<K,V,Comp>::insertrv_t map<K,V,Comp>::insert (value_type&& v)
|
||||||
|
{
|
||||||
|
iterator ip = lower_bound (v.first);
|
||||||
|
bool bInserted = ip == end() || Comp()(v.first, ip->first);
|
||||||
|
if (bInserted)
|
||||||
|
ip = base_class::insert (ip, move(v));
|
||||||
|
return make_pair (ip, bInserted);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Erases the element with key value \p k.
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
inline void map<K,V,Comp>::erase (const_key_ref k)
|
||||||
|
{
|
||||||
|
iterator ip = find (k);
|
||||||
|
if (ip != end())
|
||||||
|
erase (ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ustl
|
546
pwn/flipper/dist/common/include/ustl/umemory.h
vendored
Normal file
546
pwn/flipper/dist/common/include/ustl/umemory.h
vendored
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "unew.h"
|
||||||
|
#include "uatomic.h"
|
||||||
|
#include "uiterator.h"
|
||||||
|
#include "ulimits.h"
|
||||||
|
#include "upair.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
//{{{ auto_ptr -------------------------------------------------------
|
||||||
|
|
||||||
|
/// \class auto_ptr umemory.h ustl.h
|
||||||
|
/// \ingroup MemoryManagement
|
||||||
|
///
|
||||||
|
/// \brief A smart pointer.
|
||||||
|
///
|
||||||
|
/// Calls delete in the destructor; assignment transfers ownership.
|
||||||
|
/// This class does not work with void pointers due to the absence
|
||||||
|
/// of the required dereference operator. auto_ptr is deprecated in
|
||||||
|
/// c++11; use unique_ptr instead.
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
class auto_ptr {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef T& reference;
|
||||||
|
public:
|
||||||
|
/// Takes ownership of \p p.
|
||||||
|
inline explicit auto_ptr (pointer p = nullptr) : _p (p) {}
|
||||||
|
/// Takes ownership of pointer in \p p. \p p relinquishes ownership.
|
||||||
|
inline auto_ptr (auto_ptr<T>& p) : _p (p.release()) {}
|
||||||
|
/// Deletes the owned pointer.
|
||||||
|
inline ~auto_ptr (void) { delete _p; }
|
||||||
|
/// Returns the pointer without relinquishing ownership.
|
||||||
|
inline pointer get (void) const { return _p; }
|
||||||
|
/// Returns the pointer and gives up ownership.
|
||||||
|
inline pointer release (void) { pointer rv (_p); _p = nullptr; return rv; }
|
||||||
|
/// Deletes the pointer and sets it equal to \p p.
|
||||||
|
inline void reset (pointer p) { if (p != _p) { delete _p; _p = p; } }
|
||||||
|
/// Takes ownership of \p p.
|
||||||
|
inline auto_ptr<T>& operator= (pointer p) { reset (p); return *this; }
|
||||||
|
/// Takes ownership of pointer in \p p. \p p relinquishes ownership.
|
||||||
|
inline auto_ptr<T>& operator= (auto_ptr<T>& p) { reset (p.release()); return *this; }
|
||||||
|
inline reference operator* (void) const { return *_p; }
|
||||||
|
inline pointer operator-> (void) const { return _p; }
|
||||||
|
inline bool operator== (const pointer p) const { return _p == p; }
|
||||||
|
inline bool operator== (const auto_ptr<T>& p) const { return _p == p._p; }
|
||||||
|
inline bool operator< (const auto_ptr<T>& p) const { return p._p < _p; }
|
||||||
|
private:
|
||||||
|
pointer _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ unique_ptr
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
/// \class unique_ptr memory.h stl.h
|
||||||
|
/// \ingroup MemoryManagement
|
||||||
|
/// \brief A smart pointer.
|
||||||
|
/// Calls delete in the destructor; assignment transfers ownership.
|
||||||
|
/// This class does not work with void pointers due to the absence
|
||||||
|
/// of the required dereference operator.
|
||||||
|
template <typename T>
|
||||||
|
class unique_ptr {
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using pointer = element_type*;
|
||||||
|
using reference = element_type&;
|
||||||
|
public:
|
||||||
|
inline constexpr unique_ptr (void) : _p (nullptr) {}
|
||||||
|
inline constexpr explicit unique_ptr (pointer p) : _p (p) {}
|
||||||
|
inline unique_ptr (unique_ptr&& p) : _p (p.release()) {}
|
||||||
|
unique_ptr (const unique_ptr&) = delete;
|
||||||
|
inline ~unique_ptr (void) { delete _p; }
|
||||||
|
inline constexpr pointer get (void) const { return _p; }
|
||||||
|
inline pointer release (void) { auto rv (_p); _p = nullptr; return rv; }
|
||||||
|
inline void reset (pointer p = nullptr) { assert (p != _p || !p); auto ov (_p); _p = p; delete ov; }
|
||||||
|
inline void swap (unique_ptr& v) { ::ustl::swap (_p, v._p); }
|
||||||
|
inline constexpr explicit operator bool (void) const { return _p != nullptr; }
|
||||||
|
inline unique_ptr& operator= (pointer p) { reset (p); return *this; }
|
||||||
|
inline unique_ptr& operator= (unique_ptr&& p) { reset (p.release()); return *this; }
|
||||||
|
unique_ptr& operator=(const unique_ptr&) = delete;
|
||||||
|
inline constexpr reference operator* (void) const { return *get(); }
|
||||||
|
inline constexpr pointer operator-> (void) const { return get(); }
|
||||||
|
inline constexpr reference operator[] (size_t i) const { return get()[i]; }
|
||||||
|
inline constexpr bool operator== (const pointer p) const { return _p == p; }
|
||||||
|
inline constexpr bool operator== (const unique_ptr& p) const { return _p == p._p; }
|
||||||
|
inline constexpr bool operator< (const unique_ptr& p) const { return _p < p._p; }
|
||||||
|
private:
|
||||||
|
pointer _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
// array version
|
||||||
|
template<typename T>
|
||||||
|
class unique_ptr<T[]> {
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using pointer = element_type*;
|
||||||
|
using reference = element_type&;
|
||||||
|
public:
|
||||||
|
inline constexpr unique_ptr (void) : _p (nullptr) {}
|
||||||
|
inline constexpr explicit unique_ptr (pointer p) : _p (p) {}
|
||||||
|
inline unique_ptr (unique_ptr&& p) : _p (p.release()) {}
|
||||||
|
unique_ptr(const unique_ptr&) = delete;
|
||||||
|
inline ~unique_ptr (void) { delete [] _p; }
|
||||||
|
inline constexpr pointer get (void) const { return _p; }
|
||||||
|
inline pointer release (void) { auto rv (_p); _p = nullptr; return rv; }
|
||||||
|
inline void reset (pointer p) { assert (p != _p); auto ov (_p); _p = p; delete [] ov; }
|
||||||
|
inline void swap (unique_ptr& v) { ::ustl::swap (_p, v._p); }
|
||||||
|
inline constexpr explicit operator bool (void) const { return _p != nullptr; }
|
||||||
|
inline unique_ptr& operator= (pointer p) { reset (p); return *this; }
|
||||||
|
inline unique_ptr& operator= (unique_ptr&& p) { reset (p.release()); return *this; }
|
||||||
|
unique_ptr& operator=(const unique_ptr&) = delete;
|
||||||
|
inline constexpr reference operator* (void) const { return *_p; }
|
||||||
|
inline constexpr pointer operator-> (void) const { return _p; }
|
||||||
|
inline constexpr reference operator[] (size_t i) const { return _p[i]; }
|
||||||
|
inline constexpr bool operator== (const pointer p) const { return _p == p; }
|
||||||
|
inline constexpr bool operator== (const unique_ptr& p) const { return _p == p._p; }
|
||||||
|
inline constexpr bool operator< (const unique_ptr& p) const { return _p < p._p; }
|
||||||
|
private:
|
||||||
|
pointer _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_CPP14
|
||||||
|
|
||||||
|
template <typename T> struct __make_unique { using __single_object = unique_ptr<T>; };
|
||||||
|
template <typename T> struct __make_unique<T[]> { using __array = unique_ptr<T[]>; };
|
||||||
|
template <typename T, size_t N> struct __make_unique<T[N]> { struct __invalid_type {}; };
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline typename __make_unique<T>::__single_object
|
||||||
|
make_unique (Args&&... args) { return unique_ptr<T> (new T (forward<Args>(args)...)); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline typename __make_unique<T>::__array
|
||||||
|
make_unique (size_t n) { return unique_ptr<T> (new remove_extent_t<T>[n]()); }
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline typename __make_unique<T>::__invalid_type
|
||||||
|
make_unique (Args&&...) = delete;
|
||||||
|
|
||||||
|
#endif // HAVE_CPP14
|
||||||
|
#endif // HAVE_CPP11
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ shared_ptr
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
/// \class shared_ptr memory.h stl.h
|
||||||
|
/// \ingroup MemoryManagement
|
||||||
|
/// \brief A smart pointer.
|
||||||
|
/// Calls delete in the destructor; assignment shares ownership.
|
||||||
|
template <typename T>
|
||||||
|
class shared_ptr {
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using pointer = element_type*;
|
||||||
|
using reference = element_type&;
|
||||||
|
private:
|
||||||
|
struct container {
|
||||||
|
pointer p;
|
||||||
|
atomic<size_t> refs;
|
||||||
|
inline constexpr explicit container (pointer np) : p(np),refs(1) {}
|
||||||
|
inline ~container (void) noexcept { assert (!refs); delete p; }
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
inline constexpr shared_ptr (void) : _p (nullptr) {}
|
||||||
|
inline explicit shared_ptr (pointer p) : _p (new container (p)) {}
|
||||||
|
inline shared_ptr (shared_ptr&& p) : _p (p._p) { p._p = nullptr; }
|
||||||
|
inline shared_ptr (const shared_ptr& p): _p (p._p) { if (_p) ++_p->refs; }
|
||||||
|
inline ~shared_ptr (void) { reset(); }
|
||||||
|
inline constexpr size_t use_count (void) const { return _p ? _p->refs.load() : 0; }
|
||||||
|
inline constexpr bool unique (void) const { return use_count() == 1; }
|
||||||
|
inline constexpr pointer get (void) const { return _p ? _p->p : nullptr; }
|
||||||
|
void reset (pointer p = nullptr) {
|
||||||
|
assert (p != get() || !p);
|
||||||
|
auto ov = _p;
|
||||||
|
_p = p ? new container(p) : nullptr;
|
||||||
|
if (ov && !--ov->refs)
|
||||||
|
delete ov;
|
||||||
|
}
|
||||||
|
inline void swap (shared_ptr& v) { ::ustl::swap (_p, v._p); }
|
||||||
|
inline constexpr explicit operator bool (void) const { return get(); }
|
||||||
|
inline shared_ptr& operator= (pointer p) { reset (p); return *this; }
|
||||||
|
inline shared_ptr& operator= (shared_ptr&& p) { swap (p); return *this; }
|
||||||
|
inline shared_ptr& operator= (const shared_ptr& p) { reset(); _p = p._p; if (_p) ++_p->refs; return *this; }
|
||||||
|
inline constexpr reference operator* (void) const { return *get(); }
|
||||||
|
inline constexpr pointer operator-> (void) const { return get(); }
|
||||||
|
inline constexpr reference operator[] (size_t i) const { return get()[i]; }
|
||||||
|
inline constexpr bool operator== (const pointer p) const { return get() == p; }
|
||||||
|
inline constexpr bool operator== (const shared_ptr& p) const { return get() == p.get(); }
|
||||||
|
inline constexpr bool operator< (const shared_ptr& p) const { return get() < p.get(); }
|
||||||
|
private:
|
||||||
|
container* _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_CPP14
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
inline auto make_shared (Args&&... args)
|
||||||
|
{ return shared_ptr<T> (new T (forward<Args>(args)...)); }
|
||||||
|
|
||||||
|
#endif // HAVE_CPP14
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ scope_exit
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
class scope_exit {
|
||||||
|
public:
|
||||||
|
inline explicit scope_exit (F&& f) noexcept : _f(move(f)),_enabled(true) {}
|
||||||
|
inline scope_exit (scope_exit&& f) noexcept : _f(move(f._f)),_enabled(f._enabled) { f.release(); }
|
||||||
|
inline void release (void) noexcept { _enabled = false; }
|
||||||
|
inline ~scope_exit (void) noexcept (noexcept (declval<F>())) { if (_enabled) _f(); }
|
||||||
|
scope_exit (const scope_exit&) = delete;
|
||||||
|
scope_exit& operator= (const scope_exit&) = delete;
|
||||||
|
scope_exit& operator= (scope_exit&&) = delete;
|
||||||
|
private:
|
||||||
|
F _f;
|
||||||
|
bool _enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_CPP14
|
||||||
|
template <typename F>
|
||||||
|
auto make_scope_exit (F&& f) noexcept
|
||||||
|
{ return scope_exit<remove_reference_t<F>>(forward<F>(f)); }
|
||||||
|
#endif // HAVE_CPP14
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ unique_resource
|
||||||
|
|
||||||
|
template <typename R, typename D>
|
||||||
|
class unique_resource {
|
||||||
|
public:
|
||||||
|
inline explicit unique_resource (R&& resource, D&& deleter, bool enabled = true) noexcept
|
||||||
|
: _resource(move(resource)), _deleter(move(deleter)),_enabled(enabled) {}
|
||||||
|
inline unique_resource (unique_resource&& r) noexcept
|
||||||
|
: _resource(move(r._resource)),_deleter(move(r._deleter)),_enabled(r._enabled) { r.release(); }
|
||||||
|
unique_resource (const unique_resource&) = delete;
|
||||||
|
inline ~unique_resource() noexcept(noexcept(declval<unique_resource<R,D>>().reset()))
|
||||||
|
{ reset(); }
|
||||||
|
inline const D& get_deleter (void) const noexcept { return _deleter; }
|
||||||
|
inline R const& get (void) const noexcept { return _resource; }
|
||||||
|
inline R const& release (void) noexcept { _enabled = false; return get(); }
|
||||||
|
inline void reset (void) noexcept (noexcept(declval<D>())) {
|
||||||
|
if (_enabled) {
|
||||||
|
_enabled = false;
|
||||||
|
get_deleter()(_resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void reset (R&& r) noexcept (noexcept(reset())) {
|
||||||
|
reset();
|
||||||
|
_resource = move(r);
|
||||||
|
_enabled = true;
|
||||||
|
}
|
||||||
|
unique_resource& operator= (const unique_resource&) = delete;
|
||||||
|
unique_resource& operator= (unique_resource &&r) noexcept(noexcept(reset())) {
|
||||||
|
reset();
|
||||||
|
_deleter = move(r._deleter);
|
||||||
|
_resource = move(r._resource);
|
||||||
|
_enabled = r._enabled;
|
||||||
|
r.release();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline operator R const& (void) const noexcept { return get(); }
|
||||||
|
inline R operator-> (void) const noexcept { return _resource; }
|
||||||
|
inline add_lvalue_reference_t<remove_pointer_t<R>>
|
||||||
|
operator* (void) const { return *_resource; }
|
||||||
|
private:
|
||||||
|
R _resource;
|
||||||
|
D _deleter;
|
||||||
|
bool _enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_CPP14
|
||||||
|
|
||||||
|
template <typename R,typename D>
|
||||||
|
auto make_unique_resource (R&& r, D&& d) noexcept
|
||||||
|
{ return unique_resource<R,remove_reference_t<D>>(move(r), forward<remove_reference_t<D>>(d), true); }
|
||||||
|
|
||||||
|
template <typename R,typename D>
|
||||||
|
auto make_unique_resource_checked (R r, R invalid, D d) noexcept
|
||||||
|
{
|
||||||
|
bool shouldrun = !(r == invalid);
|
||||||
|
return unique_resource<R,D>(move(r), move(d), shouldrun);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_CPP14
|
||||||
|
#endif // HAVE_CPP11
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ construct and destroy
|
||||||
|
|
||||||
|
/// Calls the placement new on \p p.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline void construct_at (T* p)
|
||||||
|
{ new (p) T; }
|
||||||
|
|
||||||
|
/// Calls the placement new on \p p.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline void construct_at (T* p, const T& value)
|
||||||
|
{ new (p) T (value); }
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
/// Calls the move placement new on \p p.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline void construct_at (T* p, T&& value)
|
||||||
|
{ new (p) T (move<T>(value)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void construct (T* p)
|
||||||
|
{ construct_at(p); }
|
||||||
|
|
||||||
|
/// Calls the placement new on \p p.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void uninitialized_default_construct (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator>::value_type value_type;
|
||||||
|
#if HAVE_CPP11
|
||||||
|
if (is_pod<value_type>::value)
|
||||||
|
#else
|
||||||
|
if (numeric_limits<value_type>::is_integral)
|
||||||
|
#endif
|
||||||
|
memset (reinterpret_cast<void*>(first), 0, max(distance(first,last),0)*sizeof(value_type));
|
||||||
|
else
|
||||||
|
for (--last; intptr_t(first) <= intptr_t(last); ++first)
|
||||||
|
construct_at (&*first);
|
||||||
|
}
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void uninitialized_default_construct_n (ForwardIterator first, size_t n)
|
||||||
|
{ uninitialized_default_construct (first, first+n); }
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void construct (ForwardIterator first, ForwardIterator last)
|
||||||
|
{ uninitialized_default_construct (first, last); }
|
||||||
|
|
||||||
|
/// Calls the placement new on \p [first,last) with iterator_traits::value_type()
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void uninitialized_value_construct (ForwardIterator first, ForwardIterator last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator>::value_type value_type;
|
||||||
|
for (--last; intptr_t(first) <= intptr_t(last); ++first)
|
||||||
|
construct_at (&*first, value_type());
|
||||||
|
}
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void uninitialized_value_construct_n (ForwardIterator first, size_t n)
|
||||||
|
{ uninitialized_value_construct (first, first+n); }
|
||||||
|
|
||||||
|
/// Calls the destructor of \p p without calling delete.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline void destroy_at (T* p) noexcept
|
||||||
|
{ p->~T(); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void destroy (T* p) noexcept
|
||||||
|
{ destroy_at(p); }
|
||||||
|
|
||||||
|
// Helper templates to not instantiate anything for integral types.
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void dtors (T first, T last) noexcept
|
||||||
|
{ for (--last; intptr_t(first) <= intptr_t(last); ++first) destroy_at (&*first); }
|
||||||
|
template <typename T, bool bIntegral>
|
||||||
|
struct Sdtorsr {
|
||||||
|
inline void operator()(T first, T last) noexcept { dtors (first, last); }
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct Sdtorsr<T,true> {
|
||||||
|
inline void operator()(T, T) noexcept {}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
/// Calls the destructor on elements in range [first, last) without calling delete.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void destroy (ForwardIterator first, ForwardIterator last) noexcept
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<ForwardIterator>::value_type value_type;
|
||||||
|
#if HAVE_CPP11
|
||||||
|
Sdtorsr<ForwardIterator,is_pod<value_type>::value>()(first, last);
|
||||||
|
#else
|
||||||
|
Sdtorsr<ForwardIterator,numeric_limits<value_type>::is_integral>()(first, last);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
template <typename ForwardIterator>
|
||||||
|
inline void destroy_n (ForwardIterator first, size_t n) noexcept
|
||||||
|
{ destroy (first, first+n); }
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ Raw storage algorithms
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ Raw storage algorithms
|
||||||
|
|
||||||
|
template <typename T> inline T* cast_to_type (void* p, const T*) { return reinterpret_cast<T*>(p); }
|
||||||
|
|
||||||
|
/// \brief Creates a temporary buffer pair from \p p and \p n
|
||||||
|
/// This is intended to be used with alloca to create temporary buffers.
|
||||||
|
/// The size in the returned pair is set to 0 if the allocation is unsuccessful.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline pair<T*, ptrdiff_t> make_temporary_buffer (void* p, size_t n, const T* ptype)
|
||||||
|
{
|
||||||
|
return make_pair (cast_to_type(p,ptype), ptrdiff_t(p ? n : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_ALLOCA_H
|
||||||
|
/// \brief Allocates a temporary buffer, if possible.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
#define get_temporary_buffer(size, ptype) make_temporary_buffer (alloca(size_of_elements(size, ptype)), size, ptype)
|
||||||
|
#define return_temporary_buffer(p)
|
||||||
|
#else
|
||||||
|
#define get_temporary_buffer(size, ptype) make_temporary_buffer (malloc(size_of_elements(size, ptype)), size, ptype)
|
||||||
|
#define return_temporary_buffer(p) if (p) free (p), p = nullptr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Copies [first, last) into result by calling copy constructors in result.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename ForwardIterator>
|
||||||
|
ForwardIterator uninitialized_copy (InputIterator first, InputIterator last, ForwardIterator result)
|
||||||
|
{
|
||||||
|
for (; first < last; ++result, ++first)
|
||||||
|
construct_at (&*result, *first);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copies [first, first + n) into result by calling copy constructors in result.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename ForwardIterator>
|
||||||
|
ForwardIterator uninitialized_copy_n (InputIterator first, size_t n, ForwardIterator result)
|
||||||
|
{
|
||||||
|
for (++n; --n; ++result, ++first)
|
||||||
|
construct_at (&*result, *first);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calls construct on all elements in [first, last) with value \p v.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename T>
|
||||||
|
void uninitialized_fill (ForwardIterator first, ForwardIterator last, const T& v)
|
||||||
|
{
|
||||||
|
for (; first < last; ++first)
|
||||||
|
construct_at (&*first, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calls construct on all elements in [first, first + n) with value \p v.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename T>
|
||||||
|
ForwardIterator uninitialized_fill_n (ForwardIterator first, size_t n, const T& v)
|
||||||
|
{
|
||||||
|
for (++n; --n; ++first)
|
||||||
|
construct_at (&*first, v);
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
/// Moves [first, last) into result by calling move constructors in result.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename ForwardIterator>
|
||||||
|
ForwardIterator uninitialized_move (InputIterator first, InputIterator last, ForwardIterator result)
|
||||||
|
{
|
||||||
|
for (; first < last; ++result, ++first)
|
||||||
|
construct_at (&*result, move(*first));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moves [first, first + n) into result by calling move constructors in result.
|
||||||
|
/// \ingroup RawStorageAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename ForwardIterator>
|
||||||
|
ForwardIterator uninitialized_move_n (InputIterator first, size_t n, ForwardIterator result)
|
||||||
|
{
|
||||||
|
for (++n; --n; ++result, ++first)
|
||||||
|
construct_at (&*result, move(*first));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_CPP11
|
||||||
|
|
||||||
|
} // namespace ustl
|
||||||
|
|
||||||
|
//}}}-------------------------------------------------------------------
|
||||||
|
//{{{ initializer_list
|
||||||
|
#if HAVE_CPP11 && WITHOUT_LIBSTDCPP
|
||||||
|
|
||||||
|
namespace std { // Internal stuff must be in std::
|
||||||
|
|
||||||
|
/// Internal class for compiler support of C++11 initializer lists
|
||||||
|
template <typename T>
|
||||||
|
class initializer_list {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const_reference reference;
|
||||||
|
typedef const T* const_iterator;
|
||||||
|
typedef const_iterator iterator;
|
||||||
|
private:
|
||||||
|
/// This object is only constructed by the compiler when the {1,2,3}
|
||||||
|
/// syntax is used, so the constructor must be private
|
||||||
|
inline constexpr initializer_list (const_iterator p, size_type sz) noexcept : _data(p), _size(sz) {}
|
||||||
|
public:
|
||||||
|
inline constexpr initializer_list (void)noexcept : _data(nullptr), _size(0) {}
|
||||||
|
inline constexpr size_type size (void) const noexcept { return _size; }
|
||||||
|
inline constexpr const_iterator begin() const noexcept { return _data; }
|
||||||
|
inline constexpr const_iterator end() const noexcept { return begin()+size(); }
|
||||||
|
private:
|
||||||
|
iterator _data;
|
||||||
|
size_type _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr const T* begin (initializer_list<T> il) noexcept { return il.begin(); }
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr const T* end (initializer_list<T> il) noexcept { return il.end(); }
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // HAVE_CPP11
|
||||||
|
//}}}-------------------------------------------------------------------
|
96
pwn/flipper/dist/common/include/ustl/umultimap.h
vendored
Normal file
96
pwn/flipper/dist/common/include/ustl/umultimap.h
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "umap.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \class multimap umultimap.h ustl.h
|
||||||
|
/// \ingroup AssociativeContainers
|
||||||
|
///
|
||||||
|
/// \brief A sorted associative container that may container multiple entries for each key.
|
||||||
|
///
|
||||||
|
template <typename K, typename V, typename Comp = less<K> >
|
||||||
|
class multimap : public vector<pair<K,V> > {
|
||||||
|
public:
|
||||||
|
typedef K key_type;
|
||||||
|
typedef V data_type;
|
||||||
|
typedef const K& const_key_ref;
|
||||||
|
typedef const V& const_data_ref;
|
||||||
|
typedef const multimap<K,V,Comp>& rcself_t;
|
||||||
|
typedef vector<pair<K,V> > base_class;
|
||||||
|
typedef typename base_class::value_type value_type;
|
||||||
|
typedef typename base_class::size_type size_type;
|
||||||
|
typedef typename base_class::pointer pointer;
|
||||||
|
typedef typename base_class::const_pointer const_pointer;
|
||||||
|
typedef typename base_class::reference reference;
|
||||||
|
typedef typename base_class::const_reference const_reference;
|
||||||
|
typedef typename base_class::const_iterator const_iterator;
|
||||||
|
typedef typename base_class::iterator iterator;
|
||||||
|
typedef typename base_class::reverse_iterator reverse_iterator;
|
||||||
|
typedef typename base_class::const_reverse_iterator const_reverse_iterator;
|
||||||
|
typedef pair<const_iterator,const_iterator> const_range_t;
|
||||||
|
typedef pair<iterator,iterator> range_t;
|
||||||
|
typedef Comp key_compare;
|
||||||
|
typedef pair_compare_first<value_type,Comp> value_compare;
|
||||||
|
typedef pair_compare_first_key<K,V,Comp> value_key_compare;
|
||||||
|
public:
|
||||||
|
inline multimap (void) : base_class() {}
|
||||||
|
explicit inline multimap (size_type n) : base_class (n) {}
|
||||||
|
inline multimap (rcself_t v) : base_class (v) {}
|
||||||
|
inline multimap (const_iterator i1, const_iterator i2) : base_class() { insert (i1, i2); }
|
||||||
|
inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return *this; }
|
||||||
|
inline key_compare key_comp (void) const { return key_compare(); }
|
||||||
|
inline value_compare value_comp (void) const { return value_compare(); }
|
||||||
|
inline size_type size (void) const { return base_class::size(); }
|
||||||
|
inline iterator begin (void) { return base_class::begin(); }
|
||||||
|
inline const_iterator begin (void) const { return base_class::begin(); }
|
||||||
|
inline iterator end (void) { return base_class::end(); }
|
||||||
|
inline const_iterator end (void) const { return base_class::end(); }
|
||||||
|
inline const_iterator find (const_key_ref k) const;
|
||||||
|
inline iterator find (const_key_ref k) { return const_cast<iterator> (const_cast<rcself_t>(*this).find (k)); }
|
||||||
|
const_iterator lower_bound (const_key_ref k) const { return ::ustl::lower_bound (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline iterator lower_bound (const_key_ref k) { return const_cast<iterator>(const_cast<rcself_t>(*this).lower_bound (k)); }
|
||||||
|
const_iterator upper_bound (const_key_ref k) const { return ::ustl::upper_bound (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline iterator upper_bound (const_key_ref k) { return const_cast<iterator>(const_cast<rcself_t>(*this).upper_bound (k)); }
|
||||||
|
const_range_t equal_range (const_key_ref k) const { return ::ustl::equal_range (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline range_t equal_range (const_key_ref k) { return ::ustl::equal_range (begin(), end(), k, value_key_compare()); }
|
||||||
|
inline size_type count (const_key_ref v) const { const_range_t r = equal_range(v); return distance(r.first,r.second); }
|
||||||
|
inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); }
|
||||||
|
inline void push_back (const_reference v) { insert (v); }
|
||||||
|
inline iterator insert (const_reference v) { return base_class::insert (upper_bound (v.first), v); }
|
||||||
|
void insert (const_iterator i1, const_iterator i2) { for (; i1 != i2; ++i1) insert (*i1); }
|
||||||
|
inline void clear (void) { base_class::clear(); }
|
||||||
|
inline void erase (const_key_ref k) { erase (const_cast<iterator>(lower_bound(k)), const_cast<iterator>(upper_bound(k))); }
|
||||||
|
inline iterator erase (const_iterator ep) { return base_class::erase (ep); }
|
||||||
|
inline iterator erase (const_iterator ep1, const_iterator ep2) { return base_class::erase (ep1, ep2); }
|
||||||
|
inline void swap (multimap& v) { base_class::swap (v); }
|
||||||
|
#if HAVE_CPP11
|
||||||
|
using initlist_t = std::initializer_list<value_type>;
|
||||||
|
inline multimap (multimap&& v) : base_class (move(v)) {}
|
||||||
|
inline multimap (initlist_t v) : base_class() { insert (v.begin(), v.end()); }
|
||||||
|
inline multimap& operator= (multimap&& v) { base_class::operator= (move(v)); return *this; }
|
||||||
|
iterator insert (value_type&& v) { return base_class::insert (upper_bound (v.first), move(v)); }
|
||||||
|
inline iterator insert (const_iterator, value_type&& v) { return insert(move(v)); }
|
||||||
|
inline void insert (initlist_t v) { insert (v.begin(), v.end()); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace (Args&&... args) { return insert (value_type(forward<Args>(args)...)); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace_hint (const_iterator h, Args&&... args) { return insert (h, value_type(forward<Args>(args)...)); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace_back (Args&&... args) { return insert (value_type(forward<Args>(args)...)); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the pair<K,V> where K = \p k.
|
||||||
|
template <typename K, typename V, typename Comp>
|
||||||
|
inline typename multimap<K,V,Comp>::const_iterator multimap<K,V,Comp>::find (const_key_ref k) const
|
||||||
|
{
|
||||||
|
const_iterator i = lower_bound (k);
|
||||||
|
return (i < end() && Comp()(k, i->first)) ? end() : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ustl
|
86
pwn/flipper/dist/common/include/ustl/umultiset.h
vendored
Normal file
86
pwn/flipper/dist/common/include/ustl/umultiset.h
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "uvector.h"
|
||||||
|
#include "ualgo.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// \class multiset umultiset.h ustl.h
|
||||||
|
/// \ingroup AssociativeContainers
|
||||||
|
///
|
||||||
|
/// \brief Multiple sorted container.
|
||||||
|
/// Unlike set, it may contain multiple copies of each element.
|
||||||
|
///
|
||||||
|
template <typename T, typename Comp = less<T> >
|
||||||
|
class multiset : public vector<T> {
|
||||||
|
public:
|
||||||
|
typedef const multiset<T,Comp>& rcself_t;
|
||||||
|
typedef vector<T> base_class;
|
||||||
|
typedef typename base_class::value_type value_type;
|
||||||
|
typedef typename base_class::size_type size_type;
|
||||||
|
typedef typename base_class::pointer pointer;
|
||||||
|
typedef typename base_class::const_pointer const_pointer;
|
||||||
|
typedef typename base_class::reference reference;
|
||||||
|
typedef typename base_class::const_reference const_reference;
|
||||||
|
typedef typename base_class::const_iterator const_iterator;
|
||||||
|
typedef typename base_class::iterator iterator;
|
||||||
|
typedef typename base_class::reverse_iterator reverse_iterator;
|
||||||
|
typedef typename base_class::const_reverse_iterator const_reverse_iterator;
|
||||||
|
typedef pair<iterator,iterator> range_t;
|
||||||
|
typedef pair<const_iterator,const_iterator> const_range_t;
|
||||||
|
public:
|
||||||
|
inline multiset (void) : base_class() {}
|
||||||
|
inline explicit multiset (size_type n) : base_class (n) {}
|
||||||
|
inline explicit multiset (rcself_t v) : base_class (v) {}
|
||||||
|
inline multiset (const_iterator i1, const_iterator i2) : base_class() { insert (i1, i2); }
|
||||||
|
inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return *this; }
|
||||||
|
inline size_type size (void) const { return base_class::size(); }
|
||||||
|
inline iterator begin (void) { return base_class::begin(); }
|
||||||
|
inline const_iterator begin (void) const { return base_class::begin(); }
|
||||||
|
inline const_iterator cbegin (void) const { return base_class::cbegin(); }
|
||||||
|
inline iterator end (void) { return base_class::end(); }
|
||||||
|
inline const_iterator end (void) const { return base_class::end(); }
|
||||||
|
inline const_iterator cend (void) const { return base_class::cend(); }
|
||||||
|
inline Comp value_comp (void) const { return Comp(); }
|
||||||
|
inline Comp key_comp (void) const { return value_comp(); }
|
||||||
|
inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); }
|
||||||
|
inline const_iterator find (const_reference v) const { const_iterator i = ::ustl::lower_bound (begin(), end(), v, Comp()); return (i != end() && *i == v) ? i : end(); }
|
||||||
|
inline iterator find (const_reference v) { return const_cast<iterator>(const_cast<rcself_t>(*this).find (v)); }
|
||||||
|
inline const_iterator lower_bound (const_reference v) const { return ::ustl::lower_bound (begin(), end(), v, Comp()); }
|
||||||
|
inline iterator lower_bound (const_reference v) { return const_cast<iterator>(const_cast<rcself_t>(*this).lower_bound (v)); }
|
||||||
|
inline const_iterator upper_bound (const_reference v) const { return ::ustl::upper_bound (begin(), end(), v, Comp()); }
|
||||||
|
inline iterator upper_bound (const_reference v) { return const_cast<iterator>(const_cast<rcself_t>(*this).upper_bound (v)); }
|
||||||
|
inline const_range_t equal_range (const_reference v) const { return ::ustl::equal_range (begin(), end(), v, Comp()); }
|
||||||
|
inline range_t equal_range (const_reference v) { return ::ustl::equal_range (begin(), end(), v, Comp()); }
|
||||||
|
inline size_type count (const_reference v) const { const_range_t r = equal_range(v); return distance(r.first,r.second); }
|
||||||
|
inline void push_back (const_reference v) { insert (v); }
|
||||||
|
inline iterator insert (const_reference v) { return base_class::insert (upper_bound(v), v); }
|
||||||
|
inline iterator insert (const_iterator, const_reference v) { return insert(v); }
|
||||||
|
void insert (const_iterator i1, const_iterator i2) { for (; i1 < i2; ++i1) insert (*i1); }
|
||||||
|
inline iterator erase (const_iterator ep) { return base_class::erase (ep); }
|
||||||
|
inline iterator erase (const_iterator ep1, const_iterator ep2) { return base_class::erase (ep1, ep2); }
|
||||||
|
inline size_type erase (const_reference v) { range_t epr = equal_range (v); erase (epr.first, epr.second); return distance(epr.first, epr.second); }
|
||||||
|
inline void clear (void) { base_class::clear(); }
|
||||||
|
inline void swap (multiset& v) { base_class::swap (v); }
|
||||||
|
#if HAVE_CPP11
|
||||||
|
using initlist_t = std::initializer_list<value_type>;
|
||||||
|
inline explicit multiset (multiset&& v) : base_class (move(v)) {}
|
||||||
|
inline multiset (initlist_t v) : base_class() { insert (v.begin(), v.end()); }
|
||||||
|
inline multiset& operator= (multiset&& v) { base_class::operator= (move(v)); return *this; }
|
||||||
|
inline iterator insert (T&& v) { return base_class::insert (upper_bound(v), move(v)); }
|
||||||
|
inline iterator insert (const_iterator, T&& v) { return insert (move(v)); }
|
||||||
|
inline void insert (initlist_t v) { insert (v.begin(), v.end()); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace (Args&&... args) { return insert (T(forward<Args>(args)...)); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace_hint (const_iterator h, Args&&... args) { return insert (h, T(forward<Args>(args)...)); }
|
||||||
|
template <typename... Args>
|
||||||
|
inline iterator emplace_back (Args&&... args) { return insert (T(forward<Args>(args)...)); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ustl
|
1
pwn/flipper/dist/common/include/ustl/unew.h
vendored
Normal file
1
pwn/flipper/dist/common/include/ustl/unew.h
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include <new.h>
|
151
pwn/flipper/dist/common/include/ustl/unumeric.h
vendored
Normal file
151
pwn/flipper/dist/common/include/ustl/unumeric.h
vendored
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
/// Returns the sum of all elements in [first, last) added to \p init.
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename T>
|
||||||
|
inline T accumulate (InputIterator first, InputIterator last, T init)
|
||||||
|
{
|
||||||
|
while (first < last)
|
||||||
|
init += *first++;
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sum of all elements in [first, last) via \p op, added to \p init.
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename T, typename BinaryFunction>
|
||||||
|
inline T accumulate (InputIterator first, InputIterator last, T init, BinaryFunction binary_op)
|
||||||
|
{
|
||||||
|
while (first < last)
|
||||||
|
init = binary_op (init, *first++);
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assigns range [value, value + (last - first)) to [first, last)
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename ForwardIterator, typename T>
|
||||||
|
inline void iota (ForwardIterator first, ForwardIterator last, T value)
|
||||||
|
{
|
||||||
|
while (first < last)
|
||||||
|
*first++ = value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sum of products of respective elements in the given ranges.
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename T>
|
||||||
|
inline T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init)
|
||||||
|
{
|
||||||
|
while (first1 < last1)
|
||||||
|
init += *first1++ * *first2++;
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sum of products of respective elements in the given ranges.
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator1, typename InputIterator2, typename T,
|
||||||
|
typename BinaryOperation1, typename BinaryOperation2>
|
||||||
|
inline T inner_product
|
||||||
|
(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init,
|
||||||
|
BinaryOperation1 sumOp, BinaryOperation2 productOp)
|
||||||
|
{
|
||||||
|
while (first1 < last1)
|
||||||
|
init = sumOp (init, productOp (*first1++, *first2++));
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes result such that result[i] = sum (first...first+i)
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
if (first < last)
|
||||||
|
*result = *first++;
|
||||||
|
while (first < last)
|
||||||
|
*++result = *first++ + *result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes result such that result[i] = sumOp (first...first+i)
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||||
|
inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation sumOp)
|
||||||
|
{
|
||||||
|
if (first < last)
|
||||||
|
*result = *first++;
|
||||||
|
while (first < last)
|
||||||
|
*++result = sumOp (*first++, *result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes result such that result[i] = first[i] - first[i - 1]
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator>
|
||||||
|
inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
if (first < last)
|
||||||
|
*result++ = *first++;
|
||||||
|
while (first < last)
|
||||||
|
*result++ = *first - *(first - 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes result such that result[i] = differenceOp (first[i], first[i - 1])
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
||||||
|
inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation differenceOp)
|
||||||
|
{
|
||||||
|
if (first < last)
|
||||||
|
*result++ = *first++;
|
||||||
|
while (first < last)
|
||||||
|
*result++ = differenceOp (*first, *(first - 1));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns x^n.
|
||||||
|
/// Donald Knuth's Russian Peasant algorithm.
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
inline T power (T x, unsigned n)
|
||||||
|
{
|
||||||
|
T result (n % 2 ? x : 1);
|
||||||
|
while (n /= 2) {
|
||||||
|
x *= x;
|
||||||
|
if (n % 2)
|
||||||
|
result *= x;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns x^n, using \p op instead of multiplication.
|
||||||
|
/// Donald Knuth's Russian Peasant algorithm.
|
||||||
|
/// \ingroup NumericAlgorithms
|
||||||
|
///
|
||||||
|
template <typename T, typename BinaryOperation>
|
||||||
|
inline T power (T x, unsigned n, BinaryOperation op)
|
||||||
|
{
|
||||||
|
T result (n % 2 ? x : 1);
|
||||||
|
while (n /= 2) {
|
||||||
|
x = op (x, x);
|
||||||
|
if (n % 2)
|
||||||
|
result = op (result, x);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ustl
|
73
pwn/flipper/dist/common/include/ustl/upair.h
vendored
Normal file
73
pwn/flipper/dist/common/include/ustl/upair.h
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// This file is part of the uSTL library, an STL implementation.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
|
||||||
|
// This file is free software, distributed under the MIT License.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ualgobase.h"
|
||||||
|
|
||||||
|
namespace ustl {
|
||||||
|
|
||||||
|
class istream;
|
||||||
|
class ostream;
|
||||||
|
class ostringstream;
|
||||||
|
|
||||||
|
/// \class pair upair.h ustl.h
|
||||||
|
/// \ingroup AssociativeContainers
|
||||||
|
///
|
||||||
|
/// \brief Container for two values.
|
||||||
|
///
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
class pair {
|
||||||
|
public:
|
||||||
|
typedef T1 first_type;
|
||||||
|
typedef T2 second_type;
|
||||||
|
public:
|
||||||
|
/// Default constructor.
|
||||||
|
inline constexpr pair (void) : first (T1()), second (T2()) {}
|
||||||
|
/// Initializes members with \p a, and \p b.
|
||||||
|
inline pair (const T1& a, const T2& b) : first (a), second (b) {}
|
||||||
|
template <typename T3, typename T4>
|
||||||
|
inline pair (const pair<T3,T4>& p2) : first (p2.first), second (p2.second) {}
|
||||||
|
inline pair& operator= (const pair& p2) { first = p2.first; second = p2.second; return *this; }
|
||||||
|
template <typename T3, typename T4>
|
||||||
|
inline pair& operator= (const pair<T3,T4>& p2) { first = p2.first; second = p2.second; return *this; }
|
||||||
|
inline bool operator== (const pair& v)const { return first == v.first && second == v.second; }
|
||||||
|
inline bool operator< (const pair& v) const { return first < v.first || (first == v.first && second < v.second); }
|
||||||
|
inline void swap (pair& v) { ::ustl::swap(first,v.first); ::ustl::swap(second,v.second); }
|
||||||
|
inline void read (istream& is);
|
||||||
|
inline void write (ostream& os) const;
|
||||||
|
void text_write (ostringstream& os) const;
|
||||||
|
inline size_t stream_size (void) const;
|
||||||
|
#if HAVE_CPP11
|
||||||
|
pair (const pair&) = default;
|
||||||
|
pair (pair&&) = default;
|
||||||
|
template <typename T3, typename T4>
|
||||||
|
inline pair (T3&& a, T4&& b) : first (forward<T3>(a)), second (forward<T4>(b)) {}
|
||||||
|
template <typename T3, typename T4>
|
||||||
|
inline pair (pair<T3,T4>&& p2) : first (forward<T3>(p2.first)), second (forward<T4>(p2.second)) {}
|
||||||
|
inline pair& operator= (pair&& p2) { first = move(p2.first); second = move(p2.second); return *this; }
|
||||||
|
template <typename T3, typename T4>
|
||||||
|
inline pair& operator= (pair<T3,T4>&& p2) { first = forward<T3>(p2.first); second = forward<T4>(p2.second); return *this; }
|
||||||
|
inline void swap (pair&& v) { ::ustl::swap(first,v.first); ::ustl::swap(second,v.second); }
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
first_type first;
|
||||||
|
second_type second;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if HAVE_CPP11
|
||||||
|
|
||||||
|
/// Returns a pair object with (a,b)
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
inline constexpr pair<T1,T2> make_pair (T1&& a, T2&& b)
|
||||||
|
{ return pair<T1,T2> (forward<T1>(a), forward<T2>(b)); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Returns a pair object with (a,b)
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
inline constexpr pair<T1,T2> make_pair (const T1& a, const T2& b)
|
||||||
|
{ return pair<T1,T2> (a, b); }
|
||||||
|
|
||||||
|
} // namespace ustl
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user