c_language_family
#define c_language_family: \
II-------------------------------------------------------------------------------\\
II-------------------------------------------------------------------------------\\
II ,... ,, ,, \\
II .g8"""bgd .d' "" db `7MM \\
II .dP' `M dM` MM \\
II dM' ` mMMmm ,6"Yb. `7MMpMMMb.pMMMb. `7MM MM `7M' `MF' \\
II MM MM 8) MM MM MM MM MM MM VA ,V \\
II MM. MM ,pm9MM MM MM MM MM MM VA ,V \\
II `Mb. ,' MM 8M MM MM MM MM MM MM VVV \\
II `"bmmmd' .JMML.`Moo9^Yo..JMML JMML JMML..JMML..JMML. ,V \\
II (C language family) ,V \\
II OOb" \\
II-------------------------------------------------------------------------------\\
II-------------------------------------------------------------------------------\I
• a large number of language which descend from C and
retain much of the syntax and features
FILES: FILES:
Extensions:
c : C source file
cc : C++ source file
C : -||-
cp : -||-
cpp : -||-
cxx : -||-
c++ : -||-
HC : Holy C source code
i : C source code which must not be preprocessed
ii : C++ source code which must not be preprocessed
inc : C or C++ source code which is made to be #include-ed
h : header (not to be compiled or linked)
hpp : C++ specific header (not to be compiled or linked)
o : object file
gch : "GNU Compiled Header"; gcc style precompiled header file
pch : clang style precompiled header
Source_files:
• plain text files
Object_files:
• assembled machine code
• NOT linked (yet)
c__lang
#define c__lang\
#define c:: \
I--------------------------\
I--------------------------\
I \
I /$$$$$$ \
I /$$__ $$ \
I | $$ \__/ \
I | $$ \
I | $$ \
I | $$ $$ \
I | $$$$$$/ \
I \______/ \
I \
I--------------------------\
I--------------------------I
Some Were Meant for C - The Endurance of an Unmanageable Language by Stephen Kell
• the forefather of most modern languages
• technically descends from B, but nobody remembers or likes B,
its C that became highly influential and for a good reason
• created by Brian Kernighan and Dennis Ritchie, often abbreviated as K&R;
this is especially relevant because many conventions and whatnot carry K&R
in their name, implying "it is the original way of doing it"
• poetically, C happens to be the constant for the speed of light in physics
• minimalistic
• useful for teaching about hardware and compute costs
• all self-respecting languages can interface with C code due to historical reasons
• good libraries are hard to come by,
often resulting in the phenomenon known as "re-inventing the wheel"
• build-systems are in a state of "choose your own poison"
STANDARDS:
K&R
C89/ANSI C
C99
C11
C17
C23
• C90 and C95 exist, but they are completely irrelevant
PROGRAMS: PROGRAMS:
Preprocessors:
• most preprocessors are tightly integrated into compilers
fcpp:
• stand-alone ANSI compliant preprocessor
• from the creator of CURL
• due to not taking extra steps during translation such as GCC,
it can easily be used to preprocess different files (e.g. html, txt)
$ bat pp.txt
───────┬───────────────────────────────────
│ File: pp.txt
───────┼───────────────────────────────────
1 │ #define MyMACRO "Hello World"
2 │ puts(MyMACRO);
3 │ #ifndef MyMACRO
4 │ exit(1);
5 │ #endif
6 │ #include </etc/os-release>
───────┴───────────────────────────────────
$ fcpp -V pp.txt
#line 1 "pp.txt"
puts("Hello World");
#line 1 "/etc/os-release"
NAME=Gentoo
ID=gentoo
PRETTY_NAME="Gentoo Linux"
ANSI_COLOR="1;32"
HOME_URL="https://www.gentoo.org/"
SUPPORT_URL="https://www.gentoo.org/support/"
BUG_REPORT_URL="https://bugs.gentoo.org/"
VERSION_ID="2.14"
Implementations:
-------------------------------------------------------------------------------------------------------------------------
| COMPILERS |
-------------------------------------------------------------------------------------------------------------------------
| Name | Owner | C | C++ | Notes |
-------------------------------------------------------------------------------------------------------------------------
| GCC | GNU Project | X | X | default to this if starting out on Linux |
| Visual | Microsoft | | X | default to this if starting out on Windows |
| Intel | Intel | | X | |
| AOCC | AMD | X | X | |
| PGC++ | Nvidia | X | X | |
| Clang | LLVM Project | X | X | |
| Zapcc | Some guy | | X | |
| TCC | Fabrice B. | X | | "Tiny C Compiler"; used on low power systems; also an interpreter |
-------------------------------------------------------------------------------------------------------------------------
| INTERPRETERS |
-------------------------------------------------------------------------------------------------------------------------
| CINT | some guy | X | X | |
| TCC | Fabrice B. | X | | with the -run option |
| TermiC | some guy | X | X | gcc hacked into pretending to be in a REPL |
-------------------------------------------------------------------------------------------------------------------------
TCC:
#!/usr/bin/tcc -run
// TCC script example
signed main() { return 17; }
Debuggers:
------------------------------------------------
| Name | Owner | see more AT |
------------------------------------------------
| GDB | GNU Project | /GNU/gdb |
| Visual Studio | Microsoft | N/A |
------------------------------------------------
Profilers:
-----------------------------------------------------------------------------------
| Name | see more AT | Description |
-----------------------------------------------------------------------------------
| gprof | /GNU/gprof | Function call profiler with comprehensible statistics. |
| valgrind | /Debugging/ | General purpose modular execution virtualizer. |
| | valgrind | Mostly used for memory profiling. |
-----------------------------------------------------------------------------------
Build_systems:
• make
• pkg-config
• autoconf
• conan
• cmake
pkg-config
--libs
--cflags
COMMENTING: COMMENTING:
: multi line comment
SEMICOLONS: SEMICOLONS:
• every statement must end with a ';' { declaration; assignments; calls }
>a ';' by it self or directly after an other one will result in a nop (see AT assembly
LITERALS: LITERALS:
• a fix, const value known and specified at compile time
'[char]' : single (ASCII) char
<int> : decimal num (as in base 10, not decimal fraction)
0<int> : octal num
0x<int> : hex num
0b<int> : binary num
<int>.<int> : double float
Postfixes:
• explicit-ly signals the storage type (size) of an numeric literal
String:
"[...]" : char string
• NULL terminated
• an implicit '\00' is always concatenated (see AT "../Variables/Strings")
— adjacent string literals are concatenated auto-matically and without warning:
{
puts("cat" "bat");
}
escape_sequences: escape_sequences:
• char combinations holding special meaning inside literals
• allows for easy readable/writable special char-s
\a : beeps
\b : backspace
\f : form feed; new page; VERY outdated; nowadays behaves all over the places on different terminal emulators
\n : endline
\r : carriage return; moves the cursor to the first position of the current line
\t : tab character
\v : vertical tab
\e : delete
\" : " (!!!)
\' : '
\\ : \
\? : ?
\0 : null
\[d][d][d] : define char with octals
\x[d][d] : define char with hex; in practice digits are read for as long as possible {"\x05five" => "_ive"}
\u[d][d][d][d] : unicode char code (0-65535)
\U[d][d][d][d][d][d][d][d] : unicode char code (0-4294967295)
Structs:
• "compound literal"
• very convenient way of specifying struct values
• outstanding for passing into functions
(<typename>) {
(.<field> = <value>)+
}
// E.g.
typedef struct {
int i;
char * s;
} my_t;
my_t my_instance = (my_t) {
.i = 1,
.s = NULL,
};
// ...
extern void my_function(my_t t);
my_function((my_t) { .i = 10, .s = strdup("example") });
VARIABLES: VARIABLES:
[specifiers] [type] [name] : declares a variable
{
int i;
int h;
bool b;
}
• after plain declaration the variables value is undefined;
every large compiler is implemented to simply hand over memory,
therefor the value is going to be (a part of) whatever was previously allocated
• declared, but not assigned variables can technically be used as very shitty random numbers
Types:
— bool:
• standard since C23, requires stdbool.h otherwise
• "boolean"
• binary: true or false.
• 0 == false
• !0 == true
— int:
• "integer"
• whole number
• short <= int <= long <= long long
— chars:
• "character"
• char: single byte integer representing a letter or symbol in ascii
• wchar_t: wide character type; 2^N (typically 4) byte integer representing a letter or symbol in unicode
• char16_t: 16 bit wide character
• char32_t: 32 bit wide character
— string:
• an array of chars terminated by '\00'
• functions taking a char* with out taking length explicit-ly will expect a string
— floating point numbers:
• float: fraction; up to 7 decimals
• double: double-precision floating point value; fraction; up to 15 decimals
• long double
— void:
" \
The void type comprises of an empty set of values, \
it is an incomplete type that cannot be completed \
" - C89
• nothing
• functions marked void dont return anything;
in other words, they are procedures
— pointer:
void*
• any pointer can be converted to a void*
• used for accomplishing what could be described as dynamic typing
• library callback functions and especially callbacks heavily depend
on void pointers to allow for passing arbitrary (user) types
-----------------------------------------------------------------
| usual C type sizes on 64 bit computes |
-----------------------------------------------------------------
| C/C++ Declaration | Storage | Size (bits) | Size (bytes) |
-----------------------------------------------------------------
| bool | Byte | 8-bits | 1 byte |
| char | Byte | 8-bits | 1 byte |
| short | Word | 16-bits | 2 bytes |
| int | Double-word | 32-bits | 4 bytes |
| unsigned int | Double-word | 32-bits | 4 bytes |
| long | Quadword | 64-bits | 8 bytes |
| long long | Quadword | 64-bits | 8 bytes |
| char* | Quadword | 64-bits | 8 bytes |
| int* | Quadword | 64-bits | 8 bytes |
| float | Double-word | 32-bits | 4 bytes |
| double | Quadword | 64-bits | 8 bytes |
-----------------------------------------------------------------
(Traditionally the term "word" refers to the size of the processors registers and main data path.
By that definition a "word" would be 32 bit on your 32-bit system and 64-bit on your 64-bit system.
However when processor families were extended to add wider registers/operating modes
the manufacturers and users of those processors sometimes continued to use "word"
to refer to the word size of the original processor.
Intel documentation uses the term "word" to refer to a 16 bit quantity.
)
Assinging:
[variable] = [value]
[value]:
• other variable or literal (see ABOVE) with the same type
int i
i = 0;
int h;
h = i;
bool b
b = true;
Initialization:
[specifier] [type] [name] = [value]
• declaration and assignment in the same line
• most frequently used as a short-hand form
— its technically not equal with declaring and assigning afterwards
• with goto one can jump over a declaration and assignment (or none), but cannot
jump over an initialization
// legal
goto MY_LABEL;
int i;
i = 1;
MY_LABEL:
;
// not legal
goto MY_LABEL;
int i = 1;
MY_LABEL:
;
Auto:
auto [name] = [...] : [name] will have the type of what ever is on the right;
see specifics AT "/C++/?!"
Special_values:
nan - not a number
inf - infinity
npos - wasn't found { unsigned == -1 }
Type_defining:
typedef [variable declaration] [name] : declares complex variable called [name]
• makes a short hand alias of another type
{ typedef signed long long sll; }
Arrays:
<typename> [name][<int>](<int>...) : initializes array
[name][<int>] : refer to <int>th element of [name]; (0 indexed)
<int>[[name]] : same as ABOVE; more of a bug then a feature
• array types are considered to have the same const/volatile-qualification as their elements type
• char arrays are NULL byte terminated
• char arrays should only hold <int>-1 chars (for the ABOVE reason)
Specifiers:
signed : the most significant bit indicates whether the value is positive(0) or negative(1)
unsigned : the most significant bit is handled as a digit, therefor can never be negative
const : its value is immutable, ie. on paper cannot be changed;
if possible the compiler is going to replace mentions of a const with its value on compile-time,
it however wont replace (derefrenced) pointers pointing to its address; see AT "C++/Casting/Const cast"
extern : used to signal that the [type] is defined in an other translation unit;
modern linkers are in many cases are smart enough to know that by themselves;
good practice anyways; do not assign for Gods sake
register : a signal to the compiler that this variable should be kept in cpu register whenever possible;
used for optimization purposes; override-n in different contexts
static : heavily override-n in different contexts
— when used globally it means that the variable is used in multiple translation units
"Linker"
"Files/Object_files"
"Data_groups_and_objects/Static_members"
"../extern"
— when used inside a function body it specifies that functions life time exceeds the
scope; this is accomplished by the var actually being located on the heap;
effectively this means that the var preserves its value for the next calls to come
"Functions"
CASTING: CASTING:
• casting is the process of interpreting a var as a different type
• not proper conversation on incompatible types
(<typename>)[variable] : returns [variable] converted to <typename>;
but a different way, [variable] will be literally,
byte-by-byte interpreted as <typename>
POINTERS: POINTERS:
• holds only a memory address
• since its all memory address are the same size, can be casted (see ABOVE) the shit out of "safely" (from the pointers view); dont tho
• the address of a variable can be obtained by preceding the name of a variable with an ampersand sign (&), known as address-of operator
<typename> * (const) [name] : declares a pointer
• the asterisk can go anywhere between the type and the name
• can be assigned to any variable with matching [datatpye]
• that extra const is added by no mistake, specifying it will result in the pointer becoming read-only, ie. unreassignable
Function_pointers:
<typename> (*[name])([args]) : declares a function pointer (see AT "../Functions") <typename> is the return type
• can be assigned to any function with matching [args]
• the parentheses around the asterisk and [name] are necessary;
otherwise we would be declaring a function with a return type of some kind of variable pointer
• call it as follows:
(*[name])([arguments to pass])
[name]([arguments to pass])
• dereference a pointer with an '*' to access the value in that memory directly
Artimetrics:
• behaves differently that standard ints
[pointer] (+ || -) <int> : returns [pointer]s increased or decreased by <int> sizeof(*[pointer])s
[pointer] - [pointer] : returns the number if chars between the two memory locations; sign is respected
— summary:
pointer + int = pointer
pointer - int = pointer
pointer + pointer = N/A
pointer - pointer = int
COMPILING: COMPILING:
• alias building
• compiling is done by a compiler program
Compiling_process:
+-------------+ +--------------+ +-----------+ +------------+ +---------+
| Source Code | -------> | Preprocessor | --------> | Compiling | -------> | Assembling | -------> | Linking |
+-------------+ +--------------+ +-----------+ +------------+ +---------+
source_code:
• plain text written by a programmer
preprocessor:
• directives specified by the programmer are executed {macros are expanded}
• steps are taken to make the code easier to analyze
• the result is a transformed, but still recognizable source code
compiling:
• you have probably noticed that the process of compiling contains
a step also called compiling; hence the term is ambiguous
• the process of translating higher-level code into assembly (see AT "/Assembly")
assembling:
• the process of translating assembly into machine code (ie. 0-s and 1-s)
• results in an object file
• a platform specific header is added that contains metadata
• gaps are left for extern-al data, such as the address of a function or
the address of a global
linking:
• the gaps left after assembling are filled in
• the executable is finalized
— static:
• all required functions are stored directly inside the executable
• the code is self-contained
• fast as possible
• doesnt break
• larger executable sizes
*.a : static library file; archive of object files
• linkers have this tendency to think interms of object files;
what this means is that if you dump all your functions into
the same compialation unit and create a static library from that,
theres a chance your linker will copy over everything
even if it only really needs just one function;
for this reason, conventionally many libraries have compile units
per function/functionality
— dynamic:
• references to libraries are left in
• references are resolved at run-time by an interpreter
• smaller executable sizes
• easier to hack (MIT meaning)
• slightly slower
• can result in dependency-hells
• easier to hack (not MIT meaning)
*.so : dynamic library file
• compiling can be automated by make utilities;
see more detail on GNU make AT "/GNU/make"
Jumbo_builds: Jumbo_builds:
• "unity build"
• an attempt to make builds faster by grouping multiple translation units into one
• done by including complete C source files (not headers)
• eliminates the overhead of processing header files multiple times and having to access many small files
• heavier memory usage because of the increased sized of a single translation unit
• more unchanged code is being rebuilt, adding overhead
best used on large projects which are heavily modified between builds
PREPROCESSOR: PREPROCESSOR:
• the same is used for C, C++ and Objective-C
• evaluated compile time
• "pre-assembling"
• preprocessor directives must be alone on a line
• you can make them span multiple lines by placing a '\\' before a new line
#define MY_MACRO\
perform_thing();\
finalize_thing();
○ DIRECTIVES
#include : include external source file; (see BELOW)
#define [NAME] [...] : defines macro;
[NAME] will be replaced by [...] (unless inside qoutes);
recomended to make [NAME] all caps
#undef [NAME] : undefines macro
#line <int> "[name]" : sets the line number and source file name for the following line/lines (implementation specific)
(only) used by predefined macros and when giving compile time errors/warnings
#error "[str]" : abort compilation and display this line as an error (its not interpreted inside a false preprocessor logical statement)
#pragma [pdirective] : made to be impementation specific; if the compiler does not support a specific argument for #pragma, it is ignored
#if [const] : ignore the contence of the statement unless [const] is true
#ifdef [NAME] : ignore the contence of the statement unless macro [NAME] IS defined
#ifndef : ignore the contence of the statement unless macro [NAME] IS NOT defined
#else : do not ignore the contence of the statement if previous preprocessor logic failed
#elif [const] : do not ignore the contence of the statement if previous preprocessor logic failed and [const] is true
#endif : end preprocessor logical statement
## : macro concatenation operator;
can only be used inside a macro definition;
eliminates the white spaces around itself;
expanded after surrounding marcos are expanded
— Logic:
{
<start-token>
...
[#elif
...
]
[#else
...
]
#endif
}
starts-token:
• #if
• #ifdef
• #ifndef
— Including:
#include [%c][...][%c]
○ [%c]
• use <[lib]> to include an installed library
• use "[file]" to include local files
• literally copies the code from the included file
#include_next <...>
• very widely supported extension
• every dir leading to the file containing the directive is omitted from the search path
• "file" and <file> behave the same under it
Predefined_macros:
__FILE__ : string constant representing the full path and file name of the current input file
__LINE__ : current line
__DATE__ : current date; "mmm dd yyyy", where dd is padded with a ' ' if less than 10
__STDC__ : bool value signaling whether the compiler conforms to ISO C standard
__STDC_VERSION__ : long representing the C standard version; "yyyymmL"
__STDC_HOSTED__ : bool value signaling whether the compilers target is a hosted environment
__cplusplus : if defined it signals that C++ is being preprocessed
__OBJC__ : if defined it signals that Objective-C is being preprocessed
__ASSEMBLER__ : if defined it signals that Assembly is being preprocessed
HEADER_FILES:
• a header file is a C source file whose sole purpose is to list definitions
• should be created such that it can be #include-d from multiple regular source files
• required because C compilers are simple;
they operate on a single input file at the time,
header files tell them what symbols they should expect from different source files
• often considered an annoyance to deal with, especially for newbies
• header files by pure chance -or arguably divine intellect- happen to be the perfect
mechanism for self-documenting code;
reading a library's header should give a very clear understanding of what its capable of,
without having to dig through (most) implementation details or having to deploy
some tool to generate documentation from source code
— a healthy header file can contain the following:
• marcos
• enumerations
• structure definitions
• forward declarations
• extern symbol declarations
• static symbol definitions
Header_guards:
// K&R header guard
#ifndef <name>
#define <name>
[...]
#endif
// Compiler extension header guard
#pragma once
• a mechanism to prevent headers being included multiple times
• multiple includes would slow down compile times and
could result in redefinition errors {static symbols; struct-s}
• "#pragma once" is a very common compiler extension,
mechanically its equivalent to K&R guards
— K&R guards have the benefit of defining a macro that
indicates the existence of a library:
• another library could use that information to define extra symbols
to ease inter-operation
• another library could prevent redefining a struct that they both use
• user code could avoid pitfalls of two library implementations
slightly differing in behaviour
• K&R guards are highly recommended for libraries
— a common pattern is to leave an end comment on large blocks,
including header guards:
#ifndef <name>
#define <name>
[...]
#endif // <name>
• some people attempt making it more readable by shifting the define
#ifndef <name>
[...]
#define <name>
#endif
• however its important to realize that this will behave differently
for recursive inclusions
• both solutions will error out (most-likely),
however the later's error will be completely incomprehensible
KnR_headers:
• each source file within a project gets its own header
• ever source file can include the specific header it needs
• the de facto way of managing headers
{
┏━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━┓
┃ stuff.h ┃ ┃ stuff2.h ┃
┣━━━━━━━━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━━━━━━━━━━━┫
│ extern int myint; │ │ extern char mychar; │
└─────────────────────┘ └─────────────────────┘
.'| .'|
.---------------------------------'--|---------------------------' |
V V V
┏━━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ main.c ┃ ┃ stuff.c ┃ ┃ stuff2.c ┃
┣━━━━━━━━━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━━━━━━━━━━━━┫
│ #include "stuff.h"; │ │ #include "stuff.h"; │ │ #include "stuff2.h"; │
│ #include "stuff2.h"; │ │ │ │ │
│ { myint = 1; } │ │ int myint; │ │ char mychar; │
│ │ │ │ │ │
└──────────────────────┘ └─────────────────────┘ └──────────────────────┘
}
Global_headers:
• "god header"
• every declaration goes into a single header
• used for convenience during rapid prototyping or
for smaller projects where adding more headers where
adding more headers would only result in unnecessary noise
• generally considered bad practice, but there are some legitimate use cases
• does not scale well
• could result in "write-only" type project situations
{
┏━━━━━━━━━━━━━━━━━━━━━┓
┃ global.h ┃
┣━━━━━━━━━━━━━━━━━━━━━┫
│ extern int myint; │
│ extern char mychar; │
.'└─────────────────────┘
.-----' .''.
.' .-------------' '-----------.
.-------------------------------' | |
V V V
┏━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━━━━┓
┃ main.c ┃ ┃ stuff.c ┃ ┃ stuff2.c ┃
┣━━━━━━━━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━━━━━━━━━━━━┫ ┣━━━━━━━━━━━━━━━━━━━━━━┫
│ #include "stuff.h"; │ │ #include "global.h"; │ │ #include "global.h"; │
│ │ │ │ │ │
│ { myint = 1; │ │ int myint; │ │ char mychar; │
│ mychar = 'a' } │ │ │ │ │
└─────────────────────┘ └──────────────────────┘ └──────────────────────┘
}
INCLUDE_FILES:
• similar to header files, they are meant to be included from proper source files
• unlike header files they do not have guards
• they usually define data (and NOT interfaces)
• a common usecase is to hide large data definitions which would polute a source file,
hurting readability
• alternatively a small, but important constant getting its own file
{ "version.inc" which only contains a single string literal }
— gives space for the X macro pattern:
https://danilafe.com/blog/chapel_x_macros/
• inside the include file data entries are wrapped in macros
• the macros are not defined in the header or somewhere standard
• the programmer is expected to provide his own
definition of the macro before including
OBJECT_FILES: OBJECT_FILES:
Symbol_table:
• a symbol is either a function or a variable
• the syntax is not literal, however when the object table is
being translated to human readable form (see AT "?!/Objdump")
*this is common syntax
[symbol_body] [symbol_type] [symbol_name]
○ [symbol_name]
• in C, the literal name which the programmer has given to it (as overloading is not possible)
• in C++, the literal name which the programmer has given to it nested in other string to make
overloads uniquely identifiable
○ [symbol_type]
T
t
W
LINKER: LINKER:
• combines object files and links to libraries to create an executable
• the combination of object files is done by melting the assembly sections together
• can discard unused code, however it usually doesnt by default
— static
• extern libraries are copied to the assembly
• results in outstandingly large executables
— dynamic
• libraries are looked up and read at run time
• requires the user to have those libraries installed
• saves space
• generates overhead
BUILD_SYSTEMS:
• ill be honest, your options are not great
• a build system is collection of tools meant to automate the building process
Build_sh:
• "build.sh"
• not a proper build system
• placing a conventionally named shell script in the project root
which simply invokes compiler commands
• somewhat common solution
Bake:
https://github.com/agvxov/bake
• still not a proper build system
• a variation of build.sh where the build script is embedded in a source file,
and extracted by a small utility
• outstanding for rapid prototyping or packing single source programs
with their compilation instruction, for example on a blog
// @BAKE gcc -o @SHORT @FILE
// ^ bake directive; calling bake on it will execute it
signed main(void) { return 0; }
GNU_Make:
• minimalistic build system
• works very well as long as you assume a specific OS
• other build systems tend to depend on it, by creating Makefiles
• see AT (??)
• readable
• hackable (in the MIT sense)
• making it platform independent requires lots of effort
CMAKE:
• the general consensus is, that its bad, but the best option available
• the syntax is unreadable
• unreasonable learning curve
• over-complicated and confusing
• does not solve dependency management, but makes a limp-wristed effort
# How its recommended to compile cmake projects
$ cd project_root_directory/
$ mkdir build ; cd build
$ cmake ../
# however, this should be more than sufficient for normal users
$ cmake .
Autoconf:
./configure && make && make install
• "GNU automake"
• generates a GNU Makefile
• the core idea is simple, you ship your project with a portable shell script,
which will resolve system specific quirks while generating your Makefile
• the problem is that the tool-chain evolved into a convoluted mess,
where generated files generate file generator generators
• complex and quirky
• hard to debug
• uses a myriad of files, often confusing the user
• the configuration step is slow due to redundant checks
Files:
configure : Autotools signature;
each project has its own;
responsible for spitting out a make file;
preferably referred to as "./configure" for clarity
configure.[ac|in|scan]
Makefile.am
Makefile.in
config.h : contains macros
Tools:
autoconf : core tool;
Makefile.[ac|in|scan] -> ./configure
autoreconf : composite wrapper for other tools
automake : Makefile.am -> Makefile.in
autoscan : generates configure.scan
alocale : generates aclocal.m4
• I recommend you give up on the rest of them, like I did
OPERATORS: OPERATORS:
• the eval order of operands is unspecified as to fit the target architecture best;
what this means is that functions in expressions could be ran out of order
Logical:
&& and : and operator; {if(x<y && y<z){} if both are true}
|| or : or operator; {if(x<y || y<z){} if atleast one is true}
! not : not operator
^ xor : xor operator
== : equals operator
!= not_eq : not equals operator
. > : greater than operator
. >= : greater than or equal to operator
< : less than operator
<= : less than or equal to operator
Artimetric:
+ : add
++[...] : pre-increment; [...] = [...] + 1; faster then [...]++
[...]++ : post-increment; [...] = [...] + 1, but only after it was operated on
+= : add and assign { x+=y == x=x+y }
. - : subtract
. --[...] : pre-decrease; [...] = [...] - 1; faster then [...]--
[...]-- : post-decrease; [...] = [...] - 1, but only after it was operated on
. -= : subtract and assign { x-=y == x=x-y }
* : multiply
*= : multiply and assign { x-=y == x=x-y }
/ : divide
/= : divide and assign { x-=y == x=x-y }
% : reminder
%= : reminder and assign { x-=y == x=x-y }
Bitwise:
& bitand : bitwise and
| bitor : bitwise inclusive or
~ compl : bitwise not
^ : bitwise xor
<< : shift bits left (see more BELOW)
. >> : shift bits right (see more BELOW)
, : comma operator; used for providing more statements then expected;
returns the last statement; has the lowest precedence, so always use parenthesis
{ int a = (b++, b); }
sizeof([exp]) : returns size of [exp] in bytes, if [exp] is an array type returns the length of the array in bytes
• see more on shifting AT "Assembly/LANGUAGE_STATEMENT/logic/[shl && shr]"
• shift bit operations take two operands
[int1] [shift] [int2]
• [int1] is the value to be shifted
• [int2] is ALWAYS the number of bits to shift with
{ 0b00110010 >> 1 => 0b00011001 }
Assignment operators:
• perform binary operation and store the result in the LEFT operand
|= or_eq : bitwise inclusive or assignment
^= xor_eq : bitwise exclusive or assignment
<<= : left shift assignment
. >>= : right shift assignment
Misc:
& : address of (see AT "/C++/References")
LOGIC: LOGIC:
operator?:
<bool> ? <on-true> : <on-false>
• "ternary operator"
• mostly used as short syntax for a simple if statement
• <on-true> and <on-false> symbolize a value which will be returned
{
(10 > userInput) ? doThis() : doThat();
}
• one use it has, for which an if statement cannot be used
is assigning a const variable
{
bool running = init();
const char * state = running ? "started" : "crashed";
}
If:
if(<bool>) (<attribute>) {
<...>
}
(else if(<bool>) (<attribute>) {
<...>
})*
(else (<attribute>) {
<...>
})
<attribute>:
[[ likely ]] : mark the condition as likely to be true allowing for extra compiler optimizations
[[ unlikely ]] : mark the condition as not likely to be true allowing for extra compiler optimizations
Switch:
switch([variable]){
(case [value]:
[...]
(break)
)*
(default:
[...]
)
}
LOOPS: LOOPS:
while([logic]) {[code]} : while [logic] is true execute [code]
do { <...> } while ([condition]); : "do" first runs then takes a look at "while"; ie. do always runs atleast once
For:
for([def];[logic];[inc]) {} : (where to start;till when; how much to increment with) its weird cause the stuff in () can perform other stuff;
just use it as intended;
if [def], [logic] and [inc] are all empty then its an infinite loop
break : break out from current loop
continue : jump to the next loop cycle and continue execution
DATA_GROUPS_AND_OBJECTS: DATA_GROUPS_AND_OBJECTS:
• a container of variables
• their definition is only a schematic, so called instances or objects
must be created to access and modify their contents
<object>.<member> : accesses member
<object*>-><member> : accesses member of an object accessed through a pointer
same as dereferencing and then accessing normally { (*[pointer]).[member] }
○ on the distinction between operator '.' and "->"
• from a technical perspective, completely useless
• while writing C, you never actually care whether
you are accessing a field through a pointer or not
• arguably the worst features of C
• the problem it poses is one of encapsulation in a sense
• changing a definition to a pointer type or back,
will cascade into a syntax error on every member access
— K&R took some short-cuts to simplify their compiler:
https://github.com/mortdeus/legacy-cc
• there was no type checking
• the compiler was as oblivious to types as possible, similar to B
• every struct member lived in the same namespace
(this is the reason UNIX libraries and their reimplementation
have prefixes for their struct fields;
{ struct stat: st_dev, st_ino, st_mode, etc. }
)
// NOTE: lets assume a 64-bit system for simplicity
typedef struct {
int a; // simply means offset of 0 bytes
int b; // simply means offset of 4 bytes
} A_t;
typedef struct {
/* we are not allowed to name it 'a'
* because it was already used in our previous struct
*/
// int a;
int c; // simply means offset of 0 bytes
int d; // simply means offset of 4 bytes
} B_t
• this was the trick that allowed them to perform no type checking when
member access was requested by the programmer
B_t my_B;
/* later on, when we attempt to access a nonsensical field,
* no questions are asked, the associated offset value is
* fetched and compilation is carried out accordingly
*/
my_B.a = 10; // use my_B + 0 bytes; which happens to be member 'c'
• ANSI C blindly copied the K&R design even tho they emphasized type compatibility
and removed the struct member namespacing limitation
• as a result that is what every C compiler has adopted and it will never be changed
Data_unions:
union ([name]){ [...] }; : special class type; only as big as its largest element and all elements share the same memory
• the purpose of union is to save memory by using the same memory region for storing different objects at different times
• alternatively they can(, but not intended to) be used for type punning(/~converting)
• [name] is rarely used
Data_structures:
• an instance of the classical object pattern
• linguistically NOT OOP compatible, but given enough desperation,
such code-base can be implemented
struct <s_name>{ [...] }[name]; : declares struct;
notice the required ';' at the end;
[name] creates objects
[...] can contain any number
of primitive declarations
FUNCTIONS: FUNCTIONS:
([[ [attribute] ]]) ([specifier]) [return typename] [name]([[arg][, [...]]]) { [...] } : declares function
{
signed main(int argc, char** argv){
return 0;
}
function name` ` ` ` ` ` ` ` ` ` ` `\
return type| arguments \
| | _________A_________ }-> function head
V V / \ /
signed main(int argc, char** argv). . ./
{ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `\
return 0; <-- return statement }-> function body
} . . . . . . . . . . . . . . . . . . ./
}
• the part from the beginning till the curly braces is called the function head (or "header")
• the curly braces and their content is called the function body
• the function body contains code which is going to be executed upon calling the function
[specifier]:
static : this function is only visible inside its own compilation unit; a very C-y way of doing private
inline : the compiler replaces the definition of inline functions at compile time instead of referring function definition at runtime;
this makes the program take up more memory, consequentially inlining very large functions increase the chance of cache misses
and there for could harm performance
[return type]:
• any default or user defined type/group
• the function to return the execution to the function that it was called from have to return
• returning happens when a function executes the following statement:
return [value]
• [value]s typename must match the specified [return type]
• functions declared "void" dont have to explicitly contain a return statement;
they return successfully whenever they reach the end of the function
[arg]:
• argument
• optional
[specifier] <typename> [name]:
• like normal variable declarations
• copies the values passed in
<typename> [name] = [val]
• assigns default value to argument
• all arguments following an argument assigned a default value, will also have to have a default value
[specifier] <typename> &[name]:
• accesses the argument directly
• modifications are not limited to the scope
[specifier]:
• most have the same meaning
const : constant only in the context of the function, meaning can not be changed inside it; safety measure;
good for optimisation
Calling_functions:
[name]([arguments]) : calls function
Main:
<int> main() {[...]} : declares main
<int> main(int argc, char** argv) {[...]} : declares main and allows command line arguments to be accessed
<int> main(int argc, char** argv, char** envp) : declares main and allows command line arguments and (some) environment
variables to be accessed; not universal UNIX-like system specific
• <int> can be "signed int", "int" or "signed" (as "int" and "signed" are just aliases of "signed int")
• argc stands for "ARGument Count"; represents the number of command line arguments passed, ie. argvs size
• argv stands for "ARGument Vector"; an array of all command line arguments passed
• argv is nullptr terminated, this terminating nullptr is not represented in argc
• argv[argc] is always nullptr
• envp stands for "ENVironment Pointer"; a NULL terminated array of all environment variables available to the program
• called on run, ie. where execution starts (global variables are eval-ed beforehand)
GOTO: GOTO:
[name]: : defines label
goto [label]; : execution jumps to [label]
• goto statement must be in the same function as the label it is referring
• jumping out of scope will call the deconstructors
• considered bad practice, but in my opinion its the practice of Gods and should be added to python
MISC_KEYWORDS: MISC_KEYWORDS:
asm("[i1];""[...];"); : embed inline assembly code ([...]) in the program; make use to place a ';' after the instruction,
but INSIDE the parenthesis; every instruction ought to have its own parenthesis
register [variable declaration] : a signal to the compiler that this variable should be kept in cpu register whenever possible
register [type] [name] asm("[register]") : assign [name] directly to [register] { rax (%rax) }
DIGRAPH_CHARACTERS: DIGRAPH_CHARACTERS:
• later added as easier alternatives to trigraphs
<: : [
:> : ]
<% : {
%> : }
%: : #
TRIGRAPH_CHARACTERS: TRIGRAPH_CHARACTERS:
• allows to enter characters that are unavailable on some (practically nonexistent) platforms
• behave like if were a macros
??= : #
??( : [
??) : ]
??< : {
??> : }
??/ : \
??' : ^
??! : |
??- : ~
EXTENSIONS:
GNU:
Decimals:
• exactly what they sound like
_Decimal32
_Decimal64
_Decimal128
Case_ranges:
case ${N}..${M}: : the case applies for all numbers from ${N} to ${M}
IBM:
#include_next <...>
Duffs_device:
https://doc.cat-v.org/bell_labs/duffs_device
• "Duff's device"
• not a direct language feature, but emergent behaviour
• provides a method for forced loop-unrolling
• hand optimization
• important for non-optimizing compilers
• due to modern compiler optimizations, Duff's Device may or
may not result in actual performance gains
// I can explain it best with an incremental example. Consider:
do {
perform_stuff();
} while (counter++ < repeat_count);
// Here, after every call to perform_stuff() we have to
// perform a jump instruction to the top of the loop for every
// repetition. With the standards of modern software, the cost
// is small, however there are circumstances where it could be
// a legitimate performance concern.
// An optimization would be:
do {
perform_stuff();
perform_stuff();
perform_stuff();
perform_stuff();
counter += 4;
} while (counter < repeat_count);
// Now, we only need a jump after every 4 calls! Great, except
// if repeat_count is not a multiple of 4, we actually call
// perform_stuff() the wrong number of times...
// This is where Duff's Device comes into the picture.
switch (repeat_count % 4) {
case 0: do { perform_stuff(); counter++;
case 1: perform_stuff(); counter++;
case 2: perform_stuff(); counter++;
case 3: perform_stuff(); counter++;
} while (counter < repeat_count);
}
// The switch "eats away" some number of calls, guaranteeing
// (repeat_count - count) % 4 == 0 and perform_stuff() being
// called the desired number of times. (Unless it was 0,
// that's an edge case we do not account for in the example
// for simplicity.)
c_stl
#define c_stl::: \
I===============================================\
I===============================================\
I _____ _____ _____ _ \
I / __ \ / ___|_ _| | \
I | / \/ \ `--. | | | | \
I | | `--. \ | | | | \
I | \__/\ /\__/ / | | | |____ \
I \____/ \____/ \_/ \_____/ (C Standerd Library || C std)\
I===============================================\
I===============================================I
• int functions which do not return the result of some calculation,
return error codes by convention;
0 - success,
non 0 - failure
• C might have the most fucked stl out there of all programming languages;
its mostly a collection of random things someone wrote once
and have been addeded to the initial standard;
whats magickal is that it still manages to be more useful,
its holistic over consistent
--------------
assert: assert:
--------------
#include <assert.h>
[noreturn] void assert([bool]) : if [bool] is false, calls abort() and
writes a (compiler predefined) message to stderr
#define NDEBUG : ifdef, assert() becomes a nop; this is why most projects have debug builds by default
— it is common that the programmer wants to include a custom message with a failed assertion:
• a common way to do so is by using the comma operator
assert(("custom error message", 0));
|
V
commaing.out: commaing.cpp:21: int my_for(int): Assertion `(("custom error message"),0)' failed.
Aborted (core dumped)
• however the coma-operator throws a compiler warning
src/commaing.c:21:78: warning: left-hand operand of comma expression has no effect [-Wunused-value]
21 | assert(("custom error message", 0));
• so instead use a logical-and, which does not
assert("custom error message" && 0);
|
V
commaing.out: commaing.cpp:21: int my_for(int): Assertion `(("custom error message"),0)' failed.
Aborted (core dumped)
----------------
complex: complex:
----------------
#include <complex.h>
• for complex number handling
-------------
ctype: ctype:
-------------
#include <ctype.h>
• "Char TYPE"
Functions:
int:
• these functions return 0 on false and non 0 on true, because bool is not a standard C typename
int isalnum([char]) : returns whether [char] is alphanumeric (digit or alphabetic letter)
int isalpha([char]) : returns whether [char] is alphabetic letter
int islower([char]) : returns whether [char] is a lowercase letter
int isupper([char]) : returns whether [char] is a uppercase letter
int isdigit([char]) : returns whether [char] is a decimal digit (0-9)
int isxdigit([char]) : returns whether [char] is hexadecimal digit (0-9, a-f, A-F)
int isprint([char]) : returns whether [char] is printable
int iscntrl([char]) : returns whether [char] is a control character; (every nonprintable char)
int isblank([char]) : returns whether [char] is blank (space or tab)
int isspace([char]) : returns whether [char] is whitespace (' ', '\t', '\n', '\v', '\f' or 'r')
int isgraph([char]) : returns whether [char] has graphical representation (all printable chars except space and tab)
int ispunct([char]) : returns whether [char] is punctuation character (all graphical chars that are not alphanumeric (see ABOVE))
manipulation:
int tolower([char]) : returns lower case equivalent of [char]
int toupper([char]) : returns upper case equivalent of [char]
-------------
errno: errno:
-------------
#include <errno.h>
int errno : global integer; 0 on startup; its value should change whenever an error is encountered;
the meaning of values is implementation and library specific also not very well documented;
------------
fenv: fenv:
------------
#include <fenv.h>
Pragmas:
#pragma STDC FENV_ACCESS on : allow floating-point envirement access; make sure its set while using this header or expect undefined behaviour
#pragma STDC FENV_ACCESS off : disallow floating-point envirement access
Functions:
[rounding] fegetround() : returns currently applied [rounding]
int fesetround([rounding]) : applies [rounding]
int feclearexcept([excepts]) : clears [excepts] exceptions
int feraiseexcept([excepts]) : raises [excepts] exceptions
int fegetexceptflag([fexcept*], [except]) : stores [excepts] in *[fexcept*]
int fesetexceptflag([fexcept*], [except]) : sets [except] status bits to the states in [fexcept*]
int fetestexcept([excepts]) : returns what exceptions out of [excepts] are set, thus returning 0 if none
int fegetenv([fenv_t*]) : stores current floating-point environment in [fenv_t*]
int fesetenv([fenv_t*]) : sets the current floating-point environment to [fenv_t*]
int feholdexcept([fenv_t*]) : stores current floating-point environment in [fenv_t*] and resets it
int feupdateenv([fenv_t*]) : sets the current floating-point environment to [fenv_t*] and
raise the exceptions that were set before the call
Typedefs:
fexcept_t : unsigned short int; stores exception flags
Structs:
fenv_t : stores floating-point environment
FE_DFL_ENV : expands to default floating-point environment
[excepts]:
FE_DIVBYZERO : pole error exception; raised on division by 0 or log(0.0)
FE_INEXACT : inexact result exception; raised when the result can not be expressed exactly {1/3}
FE_INVALID : invalid argument exception {sqrt(-1.0)}
FE_OVERFLOW : overflow exception; raised when the result is too large to be represented in the return type
FE_UNDERFLOW : underflow exception; raised when the result is too small to be represented in the return type
FE_ALL_EXCEPT : all of the above exceptions
[rounding]:
FE_DOWNWARD
FE_UPWARD
FE_TONEAREST
FE_TOWARDZERO
--------------
floats: floats:
--------------
#include <float.h>
Macros:
FLT_RADIX : base of floats
FLT_MANT_DIG : length of mantissa for floats
DBL_MANT_DIG : length of mantissa for doubles
LDBL_MANT_DIG : length of mantissa for long doubles
DECIMAL_DIG : number of decimal digits that can be rounded into a floating-point and back without loss of precision
FLT_DIG : number of decimal digits that can be rounded into a floating-point and back without change in the number of decimal for floats
DBL_DIG : number of decimal digits that can be rounded into a floating-point and back without change in the number of decimal for doubles
LDBL_DIG : number of decimal digits that can be rounded into a floating-point and back without change in the number of decimal for long doubles
FLT_MIN_EXP : minimum value for the exponent that generates a normalized float
DBL_MIN_EXP : minimum value for the exponent that generates a normalized double
LDBL_MIN_EXP : minimum value for the exponent that generates a normalized long double
FLT_MIN_10_EXP : minimum value for the exponent of base 10 that generates a normalized float
DBL_MIN_10_EXP : minimum value for the exponent of base 10 that generates a normalized double
LDBL_MIN_10_EXP : minimum value for the exponent of base 10 that generates a normalized long double
FLT_MAX_EXP : maximum value for the exponent that generates a normalized float
DBL_MAX_EXP : maximum value for the exponent that generates a normalized double
LDBL_MAX_EXP : maximum value for the exponent that generates a normalized long double
FLT_MAX_10_EXP : maximum value for the exponent of base 10 that generates a normalized float
DBL_MAX_10_EXP : maximum value for the exponent of base 10 that generates a normalized double
LDBL_MAX_10_EXP : maximum value for the exponent of base 10 that generates a normalized long double
FLT_MAX : largest representable number with floats
DBL_MAX : largest representable number with doubles
LDBL_MAX : largest representable number with long doubles
FLT_EPSILON : difference between 1 and the next representable value with floats
DBL_EPSILON : difference between 1 and the next representable value with doubles
LDBL_EPSILON : difference between 1 and the next representable value with long doubles
FLT_MIN : smallest representable number with floats (toward 0)
DBL_MIN : smallest representable number with doubles (toward 0)
LDBL_MIN : smallest representable number with long doubles (toward 0)
FLT_ROUNDS : rounding behaviour; possible values = ([-1, undetermined], [0, toward zero], [1, to nearest],
[2, toward positive infinity], [3, toward negative infinity])
FLT_EVAL_METHOD : evaluation format; possible values = ([-1, undetermined], [0, evaluate just to the range and precision of the type],
[1, evaluate float and double as double, and long double as long double], [2 evaluate all as long double],
[-[num], indicate an implementation-defined behavior])
----------------
inttypes: inttypes:
----------------
#include <inttypes.h>
Macros:
• they extend to: "[length][specifier]" respectively of their size
• as both the name as the syntax suggests they are used meant to be used inside printf() and scanf() calls
• <int> == 8 || 16 || 32 || 64; responsible for [length] (see AT "C++/C std/<stdio.h>")
• [specifier] == d || i || o || u || x (see AT "C++/C std/<stdio.h>")
PRI[specifier]MAX
PRI[specifier]<int>
PRI[specifier]LEAST<int>
PRI[specifier]FAST<int>
PRI[specifier]PTR
SCN[specifier]MAX
SCN[specifier]<int>
SCN[specifier]LEAST<int>
SCN[specifier]FAST<int>
SCN[specifier]PTR
Functions:
• all these functions have a corresponding function mentioned, those all can be found AT "/C++/C std/<stdlib>"
intmax_t imaxabs([intmax_t]) : returns absolute value; (distance from 0);
corresponds to abs()
imaxdiv_t imaxdiv([intmax_t1], [intmax_t2]) : returns a imaxdiv_t struct containing [int1]/[int2] and the remainder;
corresponds to div()
intmax_t strtoimax([char*], [char**], <int>) : returns [char*] converted to intmax_t and sets [char**] to
the position after where the last digit was read from;
[char**] can be NULL; <int> is the numerical base;
corresponds to strtol()
uintmax_t strtoumax([char*], [char**], <int>) : same as ABOVE, but with uintmax_t
intmax_t wcstoimax([wchar_t*], [wchar_t**], <int>) : returns [wchar_t*] converted to intmax_t and sets [char**] to
the position after where the last digit was read from;
[wchar_t**] can be NULL; <int> is the numerical base;
corresponds to wcstol()
uintmax_t wcstoumax([wchar_t*], [wchar_t**], <int>) : same as ABOVE, but with uintmax_t
Structs:
imaxdiv_t : holds the results of a imaxdiv(); has two members quot(ient) and rem(inder)
--------------
iso646: iso646:
--------------
#include <iso646.h>
• adds macro aliases for operators
and
or
not
bitand
bitor
• this allows you to use bitand for address-of, which is very funny
--------------
limits: limits:
--------------
#include <limits.h>
Macros:
CHAR_BIT : number of bits in a char
SCHAR_MIN : smallest possible value for a signed char
SCHAR_MAX : largest possible value for a signed char
UCHAR_MAX : largest possible value for a unsigned char
CHAR_MIN : smallest possible value for a char (SCHAR_MIN || 0)
CHAR_MAX : largest possible value for a char (UCHAR_MAX || SCHAR_MAX)
MB_LEN_MAX : maximum number of bytes in a multibyte char
SHRT_MIN : smallest possible value for a short int
SHRT_MAX : largest possible value for a short int
USHRT_MAX : largest possible value for an unsigned short int
INT_MIN : smallest possible value for an int
INT_MAX : largest possible value for an int
UINT_MAX : largest possible value for an unsigned int
LONG_MIN : smallest possible value for a long
LONG_MAX : largest possible value for a long
ULONG_MAX : largest possible value for a unsigned long
LLONG_MIN : smallest possible value for a long long
LLONG_MAX : largest possible value for a long long
ULLONG_MAX : largest possible value for a unsigned long long
--------------
locale: locale:
--------------
#include <locale.h>
Structs:
lconv : struct that holds local information; meant to be used to extract current locale of the program
char *decimal_point : decimal point symbol
char *thousands_sep : thousands separator
char *grouping : where to put thousands_sep-s; { "\3\3\2" -> 1.000.000.00 }
char *int_curr_symbol : international currency symbol; { HUF }
char *currency_symbol : local currency symbol; { $ }
char *mon_thousands_sep : monetary thousands separator
char *mon_grouping : where to put thousands_sep-s in monetary values (see ABOVE)
char *positive_sign : positive sign
char *negative_sign : negative sign
char frac_digits : number of fractional digits to be written
char p_cs_precedes : 1 if the curreny_symbol precedes positive values, 0 if succeeds
char int_p_cs_precedes
char p_sep_by_space : 1 if a space separates currency_symbol from positive values
char int_p_sep_by_space
char n_cs_precedes : 1 if the curreny_symbol precedes negative values, 0 if succeeds
char int_n_cs_precedes
char n_sep_by_space : 1 if a space separates currency_symbol from negative values
char int_n_sep_by_space
char p_sign_posn : sign position:
char n_sign_posn 0 - parentheses surround the quantity and currency_symbol
char int_p_sign_posn 1 - the sign string precedes the quantity and currency_symbol
char int_n_sign_posn 2 - the sign string follows the quantity and currency_symbol
3 - the sign string immediately precedes the currency_symbol
4 - the sign string immediately follows the currency_symbol
Functions:
char* setlocale([category], [locale]) : sets [category] to [locale] for the program; returns char* to current locale
[category]:
LC_ALL : the entire locale
LC_COLLATE : char set order; affects the behavior of strcoll and strxfrm
LC_CTYPE : affects all functions of <cctype>, except isdigit and isxdigit, and the multibyte and wide character functions
LC_MONETARY : affects monetary formatting information returned by localeconv
LC_NUMERIC : affects the decimal-point formatting and information returned by localeconv
LC_TIME : affects the behavior of strftime
[locale]:
"C" : C locale
"" : environment default locale
lconv* localeconv() : returns lconv with currently applied locales for the program
------------
math: math:
------------
#include <math.h>
Functions:
Trigonometry:
double atan2([num1],[num2]) : returns the arc tangent of [num1]/[num2] in radians; to compute the value,
the function takes into account the sign of both arguments in order to determine the quadrant
• Each One Of The BELOW has a correspondind hyperbolic version, postfix them with an 'h' to call them { cosh() }
double cos([num]) : returns the cosine of [num] radians
double sin([num]) : returns the sine of [num] radians
double tan([num]) : returns the tangent of [num] radians
double acos([±1]) : returns the cosine of [+-1] in radians; if [+-1] is not between -1 and 1 [nan] is returned
double asin([±1]) : returns the sine of [+-1] in radians; if [+-1] is not between -1 and 1 [nan] is returned
double atan([num]) : returns the tangent of [num] in radians
Logarithmic:
exp
frexp
ldexp
log
log10
modf
exp2
expm1
ilogb
log1p
log2
logb
scalbn
scalbln
Power:
double pow([num1], [num2]) : returns [num1]^[num2]
double sqrt([num]) : returns square root of [num]
num cbrt([num]) : returns cubic root of [num]
num hypot([num1], [num2]) : i dont know what a hypotenuse is (?!)
Rounding:
• these functions have float and long double overloads
double ceil([double]) : returns the smallest integer thats not less then [num]; the return type is the same as [num]s
double floor([double]) : returns the largest integer thats not greater then [num]; the return type is the same as [num]s
double round([double]) : returns the nearest integer to [num]; the return type is the same as [num]s
double trunc([double]) : returns [num] rounded towards 0; the return type is the same as [num]s
long lround([double]) : returns the nearest integer to [num] casted to LONG INT
long long llround([double]) : returns the nearest integer to [num] casted to LONG LONG INT
double rint([double]) : returns [double] rounded according to the currently set rounding (see AT "../<fenv>");
may raise FE_INEXACT (see AT "../<fenv>")
long lrint([double]) : returns [double] rounded according to the currently set rounding (see AT "../<fenv>") then
rounded to the nearest integer and casted to long;
may raise FE_INEXACT (see AT "../<fenv>")
long long llrint([double]) : returns [double] rounded according to the currently set rounding (see AT "../<fenv>") then
rounded to the nearest integer and casted to long long
may raise FE_INEXACT (see AT "../<fenv>")
double nearbyint([double]) : returns [double] rounded according to the currently set rounding (see AT "../<fenv>");
will never raise FE_INEXACT (see AT "../<fenv>")
Remainder:
• function alternatives to the '%' operator for floating points
double fmod([float1], [float2]) : returns of what logically would be [float1] % [float2], rounded towards 0
(as the '%' operator doesnt support floating points)
double remainder([float1], : returns of what logically would be [float1] % [float2], rounded towards the neerest integer
[float2])
double remqou([float1], [float2], : same as ABOVE, but also stores the qoutient in [int*]
[int*])
Bool:
• these functions where macros originally, but C++ converted them to functions, hence the bool return type
bool isfinite([num]) : returns whether [num] is finite (meant for floats)
bool isinf([num]) : returns whether [num] is (+-)infinity
bool isnan([num]) : returns whether [num] is nan
bool isnormal([num]) : returns whether [num] is neither infinity, nan, 0 or subnormal
bool signbit([num]) : returns whether the sing of [num] is negative
bool isgreater([num1], [num2]) : returns whether [num1] is greater then [num2]
bool isgreaterequal([num1], [num2]) : returns whether [num1] is greater then or equal to [num2]
bool isless([num1], [num2]) : returns whether [num1] is less then [num2]
bool islessequal([num1], [num2]) : returns whether [num1] is less then or equal to [num2]
bool islessgreater([num1], [num2]) : returns whether [num1] is less then or greater then [num2]
bool isunordered([num1], [num2]) : ?!
Misc:
double nan() : returns quite nan
double copysign([num1], [num2]) : returns [num1] with the sign of [num2]
double fdim([num1], [num2]) : returns x-y if x>y, and 0 otherwise
double fmax([num1], [num2]) : returns the larger one of its arguments
double fmin([num1], [num2]) : returns the smaller one of its arguments
double nextafter([num1], [num2]) : returns the next representable value between [num1] and [num2]
double nexttoward([num1], [num2]) : returns the previous representable value between [num2] and [num1]
int fpclassify([num]) : returns an int indicating what type of value [num] is (see BELOW)
FP_INFINITE - Positive or negative infinity (overflow)
FP_NAN - Not-A-Number
FP_ZERO - Value of zero
FP_SUBNORMAL - Sub-normal value (underflow)
FP_NORMAL - Normal value (none of the above)
--------------
setjmp: setjmp:
--------------
#include <setjmp.h>
• basically an inter-function goto
• the C way of doing throw - catch
• values of variables wont change back, the values of register variables however are undefined behaviour
Typedefs:
jmp_buf : type aimed at saving the stack pointers for later restoration
Functions:
int setjmp([jmp_buf]) : saves current stack to [jmp_buf]; returns with 0 unless
it returned from longjmp() (see BELOW), in that case returns longjmp()s <int> argument
[[ noreturn ]] int longjmp([jmp_buf], <int>) : loads [jmp_buf], ie. jumps to it and makes setjmp() (see ABOVE) return <int>
{
#include <stdio.h>
#include <setjmp.h>
void f(int* a, int* b){
*a += 3;
*b += 5;
}
signed main(){
int* heap_var = new int(1);
int stack_var = 2;
jmp_buf buf;
int j = setjmp(buf);
printf("heap: %d\n"
"stack: %d\n"
"---\n",
*heap_var,
stack_var
);
if(j){
return 0;
}
f(heap_var, &stack_var);
longjmp(buf, 1);
}
}
--------------
signal: signal:
--------------
#include <signal.h>
typedef void (*FUNC)(int);
Functions:
void signal([signal], [FUNC]) : if [signal] is raised run [FUNC]; { signal(SIGINT, my_signal_handler); }
int raise([signal]) : raises [signal] for current program (to be handled by signal()); returns int 0 if successful
[signal]:
• int macros
SIGABRT : signal abort; actually sent by abort()
SIGFPE : signal floating point exception
SIGILL : signal illegal instruction
SIGINT : signal interrupt; [Ctrl] + [c]
SIGSEGV : signal segmentation violation
SIGTERM : signal terminate
[FUNC]:
• generic handlers
SIG_DFL : default handling
SIG_IGN : ignore
SIG_ERR : indicates that an error has occurred when returned by signal(); (see ABOVE)
--------------
stdarg: stdarg:
--------------
#include <stdarg.h>
va_list [name] : declare va_list
Macro_functions:
void va_start([va_list], [last named argument]) : initializes [va_list]; if [last named argument] is not the last named argument,
it will result in undefined behaviour; always should have a corresponding va_end()
Functions:
typename va_arg([va_list], <typename>) : returns next argument it hasn't returned yet casted as <typename>;
[va_list] should be initialized
void va_copy([va_list1], [va_list2]) : copy [va_list2] into [va_list1]; [va_list1] should be uninitialized,
[va_list2] should be initialized
void va_end([va_list]) : end using [va_list]; should always be called before returning
if a va_start() was called
-------------------------
<stdbool>
-------------------------
#include <stdbool.h>
• adds a pseudo-bool type
bool : some integer (compatible) type
true : 1
false : 0
------------------------
<stddef>
------------------------
#include <stddef.h>
Typedefs:
prtdiff_t : long; (meant represent the result of a pointer subtraction operation)
size_t : unsigned int
max_align_t : ?!
nullptr_t : a distinct type which can only hold the value nullptr
Macro_functions:
void offsetof([data_group], [member]) : returns offset of [member],
from the beginning of [data_group];
[data_group] cannot have virtual members
Macro_consts:
NULL : null pointer
----------------
-------------------------
<stdint>
-------------------------
#include <stdint.h>
Typedefs:
----------------------------------
| Signed | Unsigned |
----------------------------------
| intmax_t | uintmax_t |
| int8_t | uint8_t |
| int16_t | uint16_t |
| int32_t | uint32_t |
| int64_t | uint64_t |
| int_least8_t | uint_least8_t |
| int_least16_t | uint_least16_t |
| int_least32_t | uint_least32_t |
| int_least64_t | uint_least64_t |
| int_fast8_t | uint_fast8_t |
| int_fast16_t | uint_fast16_t |
| int_fast32_t | uint_fast32_t |
| int_fast64_t | uint_fast64_t |
| intptr_t | uintptr_t |
----------------------------------
Macros:
+---------------------------------------------+------------------------------------------------------+----------------------------------------------+
| Macro | Description | Defined as |
+---------------------------------------------+------------------------------------------------------+----------------------------------------------+
| INTMAX_MIN | Minimum value of intmax_t | -(263-1), or lower |
| INTMAX_MAX | Maximum value of intmax_t | 263-1, or higher |
| UINTMAX_MAX | Maximum value of uintmax_t | 264-1, or higher |
| INTN_MIN | Minimum value of exact-width signed type | Exactly -2(N-1) |
| INTN_MAX | Maximum value of exact-width signed type | Exactly 2(N-1)-1 |
| UINTN_MAX | Maximum value of exact-width unsigned type | Exactly 2N-1 |
| INT_LEASTN_MIN | Minimum value of minimum-width signed type | -(2(N-1)-1), or lower |
| INT_LEASTN_MAX | Maximum value of minimum-width signed type | 2(N-1)-1, or higher |
| UINT_LEASTN_MAX | Maximum value of minimum-width unsigned type | 2N-1, or higher |
| INT_FASTN_MIN | Minimum value of fastest minimum-width signed type | -(2(N-1)-1), or lower |
| INT_FASTN_MAX | Maximum value of fastest minimum-width signed type | 2(N-1)-1, or higher |
| UINT_FASTN_MAX | Maximum value of fastest minimum-width unsigned type | 2N-1, or higher |
| INTPTR_MIN | Minimum value of intptr_t | -(215-1), or lower |
| INTPTR_MAX | Maximum value of intptr_t | 215-1, or higher |
| UINTPTR_MAX | Maximum value of uintptr_t | 216-1, or higher |
| SIZE_MAX | Maximum value of size_t | 264-1, or higher |
| PTRDIFF_MIN | Minimum value of ptrdiff_t | -(216-1), or lower |
| PTRDIFF_MAX | Maximum value of ptrdiff_t | 216-1, or higher |
| SIG_ATOMIC_MIN | Minimum value of sig_atomic_t | if sig_atomic_t is signed: -127, or lower... |
| | | if sig_atomic_t is unsigned: 0 |
| SIG_ATOMIC_MAX | Maximum value of sig_atomic_t | if sig_atomic_t is signed: 127, or higher... |
| | | if sig_atomic_t is unsigned: 255, or higher | |
| WCHAR_MIN | Minimum value of wchar_t | if wchar_t is signed: -127, or lower... |
| | | if wchar_t is unsigned: 0 |
| WCHAR_MAX | Maximum value of wchar_t | if wchar_t is signed: 127, or higher... |
| | | if wchar_t is unsigned: 255, or higher |
| WINT_MIN | Minimum value of wint_t | if wint_t is signed: -32767, or lower... |
| | | if wint_t is unsigned: 0 |
| WINT_MAX | Maximum value of wint_t | if wint_t is signed: 32767, or higher... |
| | | if wint_t is unsigned: 65535, or higher |
+---------------------------------------------+------------------------------------------------------+----------------------------------------------+
Macros_functions:
INTMAX_C(<int>) : returns the closest representable value of intmax_t
UINTMAX_C(<int>) : returns the closest representable value of uintmax_t
INT[int1]_C([int2]) : returns the closest representable value of [int2] in int_least<int>_t ([int1] == 8 || 16 || 32 || 64)
UINT[int1]_C([int2]) : returns the closest representable value of [int2] uint_least[int1]_t ([int1] == 8 || 16 || 32 || 64)
--------------------------------
<stdio>
--------------------------------
# define stdio
# include <stdio.h>
• Input/Output library
Functions:
Generic FILE* operations:
FILE* fopen([file], [openmode]) : returns FILE* to [file] opened in [openmode] (both args are char*-s)
FILE* freopen([file], [openmode], [FILE*]) : opens [file] in [openmode] and associates it with [FILE*],
regardless off what was associated with what before
int fclose([FILE*]) : flushes (see ABOVE), closes file and disassociates it from [FILE*]
void setbuf([FILE*], [char*]) : associates buffer [char*] to be used with [FILE*]
if [char*] is NULL a buffer will get allocated automatically
int setvbuf([FILE*], [char*], : specifies buffering for [FILE*]; associates it with [char*]; enforces [buffermode];
[buffermode], [num]) [num] is the size of the buffer in bytes (see BELOW)
int fflush([FILE*]) : any unwritten data (see buffermode) is written to [FILE*];
if [FILE*] == NULL -> all open files are automatically flushed
when they are closed or on normal termination
int ungetc([char], [FILE*]) : puts back char to [FILE*], but only virtually (so that it can be read again)
int ferror([FILE*]) : returns whether error indicator is set for [FILE*]
int feof([FILE*]) : returns whether eof indicator is set for [FILE*]
void clearerr([FILE*]) : reset error and eof indicator for [FILE*]
output:
int fprintf([FILE*], [format](, [...])) : prints [format] (see BELOW) to [FILE*] (see buffermode tho);
returns number of printed chars on success or a negative number on fail
int vfprintf([FILE*], [format], [va_list]) : same as ABOVE, but instead of passing the arguments individually you
pass in a [va_list] (see AT stdarg)
int fputc([char], [FILE*]) : writes [char]/<int> to [FILE*] and advances position indicator by one;
|| putc([char], [FILE*]) putc and fputc are equivalent, except that putc may be implemented
as a macro in some libraries; returns char written or EOF
int fputs([char*], [FILE*]) : writes [char*] to [FILE*] and advances position indicator accordingly;
the null terminating char is not copied; returns a non negative value or EOF
size_t fwrite([pointer], [size_t1], : writes [size_t1]*[size_t2](array) bytes, from [pointer] to [FILE*];
[size_t2], [FILE*]) returns size_t number of chars written
input:
int fscanf([FILE*], [format](, [...])) : reads input from [FILE*] and stores them according to [format] (see BELOW)
into the additionally passed in arguments
int vfscanf([FILE*], [format], [va_list]) : same as ABOVE, but instead of passing the arguments individually you
pass in a [va_list] (see AT stdarg)
int fgetc([FILE*]) || getc([FILE*]) : returns the char currently pointed by internal file position indicator
of [FILE*] and advances it by one
char* fgets([char*], <int>, [FILE*]) : copies until the next EOL or <int> chars from the currently pointed by
internal file position indicator of [FILE*] into [char*] and advances it accordingly
size_t fread([pointer], [size_t1], : reads [size_t1]*[size_t2](array) bytes, from [FILE*] and
[site_t2], [FILE*]) stores them at where [pointer] points to
ssize_t getline([char**], [size_t], [FILE*]) : reads a whole line from [FILE*] and stores it in [char**];
[size_t] signals the size of [char**]; if the line is longer
getline() will call realloc() on [char**] and update [size_t];
appropriately; new line chars are preserved
position_indicator:
int fgetpos([FILE*], [fpos_t*]) : sets [fpos_t*] (see BELOW) to the current position in [FILE*]
long ftell([FILE*]) : returns the current position in [FILE*]
int fsetpos([FILE*], [fpos_t*]) : sets the current position in [FILE*] to [fpos_t*] (see BELOW)
int fseek([FILE*], [long], [base]) : set the position indicator to [base] + [long]; [base]:
SEEK_SET : beginning
SEEK_CUR : current position
SEEK_END : end
void rewind([FILE*]) : set position indicator to beginning
system_operations:
int remove([file]) : deletes [file]
int rename([file], [name]) : renames [file] to [name]
FILE* tmpfile() : returns FILE* to temporary ("wb+"); this file is guaranteed to have an
unique name and will be deleted on closure or on normal termination
char* tmpnam([char *]) : returns and changes [char*]s value to a string that is guaranteed to be different from
stdout/stdin/stderr operations:
int putchar([char]) : prints [char] to stdout
int puts([char*]) : prints [char*] to stdout and appends it with a '\n'
int printf([format](, [...])) : prints [format] (see BELOW) to stdout returns number of printed
chars on success or a negative number on fail
int vprintf([format], [va_list]) : same as ABOVE, but instead of passing the arguments individually
[va_list] is passed (see AT stdarg)
int getchar() : returns the char read from stdin
int gets([char*]) : reads chars from stdin until '\n' is met and stores them in [char*]
int scanf([format](, [...])) : reads input from stdin and stores them according to [format] (see BELOW)
into the additionally passed in arguments
int vscanf([format], [va_list]) : same as ABOVE, but instead of passing the arguments individually
[va_list] is passed (see AT stdarg)
void perror([char*]) : prints errno (see AT "../<errno>") interpreted as an error message to stderr;
[char*] is a custom message to be printed before errno, if NULL is submitted,
no custom message is shown
String operations:
int sprintf([char*], [format](, [...])) : same as printf(), but instead of printing to stdout,
it copies the resulting string into [char*];
its not the pointers value that gets modified,
its the memory at the pointers value,
therefor allocating memory is the programmers job
int vsprintf([char*], [format], [va_list]) : same as above, but instead of passing the arguments individually
[va_list] is passed (see AT stdarg)
int snprintf([char*], [num], : formats string as printf, but instead of printing to stdin,
[format](, [...])) it copies the resulting first [num] chars into [char*], the rest are discarded
int vnsprintf([char*], [num], : same as above, but instead of passing the arguments individually
[format], [va_list]) [va_list] is passed (see AT stdarg)
int sscanf([char*], [format](, [...])) : reads data from [char*] and stores them according to [format] (see BELOW)
into the additionally passed in arguments
int vsscnaf([char*], [format], [va_list]) : same as above, but instead of passing the arguments individually you pass in a [va_list] (see AT stdarg)
Typedefs:
fpos_f : used to specify a position within a file, not meant to be read directly
Structs:
FILE : object that contains informations to control a stream; has a internal position indicator, pointing somewhere its contents,
its knowing where to read from or write to; you should always declare pointers and assign them to the return
value of fopen() or tmpfile() (see ABOVE); on including <stdio> three instances are automatically created: stdin, stdout, stderr
Globals:
stdin : standard input stream
stdout : standard output stream
stderr : standard error stream
Macros:
NULL : expands to null pointer constant
EOF : expands to a negative int representing the eof
FILE_NAME_MAX : expands to the maximum amount of chars to represent a file name
FOPEN_MAX : expands to the maximum number of files that can be opened at once
TMP_MAX : expands to the number of unique temporary file names that are guaranteed to be possible
L_tmpnam : expands to the length of the filename tmpnam() (see ABOVE) generates
BUFIS : expands to the maximum buffer size usable with setvbuff() (see ABOVE)
[Openmode] flags:
"r" : read
"w" : write
"a" : append
"r+" : read/write; the file must exist
"w+" : read/write; a new file will be created
"a+" : read/append; a new file is created if it doesnt exist already
"b" : binary (flag must be appended to another flags)
[Buffermode] (flags):
_IOFBF : full buffering; data is written to [FILE*] when the buffer is full or fflush()-ed
_IOLBF : line buffering; data is written to [FILE*] once a newline char is found or when the buffer is full or fflush()-ed
_IONBF : no buffering; everything is written as soon as possible
Formaters:
typedef char* [format]
• "%%" -> '%'
printf && fprintf -> %[flags][width][precision][length]<specifier>
scanf && fscanf -> %(*)[max][length]<specifier>
* : ignore (not (You), the function discards inputted data)
specifiers:
d || i : decimal int
u : unsigned decimal int
o : unsigned octal int
x : unsigned hex int, lower case (1af)
X : unsigned hex int, upper case (1AF)
f : decimal float
a : hex float, lower case (0xb.f)
A : hex float, upper case (0xB.F)
e : scientific num, lower case (1.2e+2)
E : scientific num, upper case (1.2E+2)
c : char
s : C string
p : (pointer) address
n : store the number of characters in an unsigned int passed in
g : shortest representation, lower case (e or f)
G : shortest representation, upper case (E or F)
flags:
+ : always display sign
[space] : never display sign
# : prefix: o->0, x->0x, X->0X || always display decimal point with: a, A, e, E, f, F, g, G,
— : left-justify within [width]
0 : pad with '0'-s instead of spaces (see BELOW)
width:
• specifies the minimum width, pads with spaces by default
[num] : width
* : pass in the width as an argument of the printf(); must be passed in BEFORE the value to be printed
percision:
• specifies the minimum number of digits to be printed, to achieve this, numbers will get prefixed with '0'-s (d, i, o, u, x, X)
OR specifies the number of digits to be written after the decimal point (g, G)
OR specifies the number of chars to be printed (s)
.[num] : precision
.* : pass in the precision as an argument of the printf(); must be passed in BEFORE the value to be printed
max:
• the maximum amount of chars to write into the corresponding variable
length:
• alters the expected typename
• h, hh, l, ll, j, z, t, L,
-----------------------------------------------------------------------------------------------------------
| | specifiers |
| length |------------------------------------------------------------------------------------------------|
| | d, i, | u, o, x, | f, e, g, a, | c, s, | p | n |
+---------------------------------------------------------------------------------------------------------+
| (none) | int* | unsigned int* | float* | char* | void* | int* |
| hh | signed char* | unsigned char* | | | | signed char* |
| h | short int* | unsigned short int* | | | | short int* |
| l | long int* | unsigned long int* | double* | wchar_t* | | long int* |
| ll | long long int* | unsigned long long int* | | | | long long int* |
| j | intmax_t* | uintmax_t* | | | | intmax_t* |
| z | size_t* | size_t* | | | | size_t* |
| t | ptrdiff_t* | ptrdiff_t* | | | | ptrdiff_t* |
| L | | | long double* | | | |
+---------------------------------------------------------------------------------------------------------+
— stdio has the following, annoying inconsistency:
fprintf(FILE*, char*, ...) // file first, because it has to be
fputs(char*, FILE*); // file last
• for this and other smaller reasons you are advised to use dictate
https://github.com/agvxov/dictate
--------------------------------
<stdlib>
--------------------------------
#include <stdlib.h>
Functions:
— memory management:
void* calloc([size_t1], [size_t2]) : returns a pointer to [size_t1]*[size_t2] bytes of 0 initialized free memory block;
([size_t1] meant to be the length for an array and [size_t2] meant to be the member size)
void free([pointer]) : frees up memory at [pointer] which previously was returned by calloc(), malloc() or realloc
(otherwise it causes undefined behaviour)
void* malloc([size_t]) : returns a pointer to [size_t] bytes of free memory; NOT 0 initialized
void* realloc([pointer], [size_t]) : resized [pointer] to [size_t]; if needed the contents of *[pointer] is moved to a new location, which is returned
— string conversion:
double atof([char*]) : returns [char*] converted to double
int atoi([char*]) : returns [char*] converted to int
long atol([char*]) : returns [char*] converted to long
long long atoll([char*]) : returns [char*] converted to long long
double strtod([char*], [char**]) : returns [char*] converted to double and sets [char**] to the position
after where the last digit was read from; [char**] can be NULL
float strtof([char*], [char**]) : returns [char*] converted to float and sets [char**] to the position
after where the last digit was read from; [char**] can be NULL
long double strtold([char*], [char**]) : returns [char*] converted to long double and sets [char**] to the position
after where the last digit was read from; [char**] can be NULL
unsigned long strtoul([char*], [char**], : returns [char*] converted to unsigned long and sets [char**] to the position
<int>) after where the last digit was read from; [char**] can be NULL; <int> is the numerical base
long strtol([char*], [char**], <int>) : returns [char*] converted to long and sets [char**] to the position
after where the last digit was read from; [char**] can be NULL; <int> is the numerical base
unsigned long long strtoull([char*], : returns [char*] converted to unsigned long long and sets [char**] to the position
[char**], <int>) after where the last digit was read from; [char**] can be NULL; <int> is the numerical base
long long strtoll([char*], [char**], <int>) : returns [char*] converted to long long and sets [char**] to the position
after where the last digit was read from; [char**] can be NULL; <int> is the numerical base
random:
void srand([unsigned int]) : set seed for pseudo-random number generator
int rand() : returns a pseudo-random number between 0 and RAND_MAX
envirement:
void abort() : aborts the program, producing an abnormal termination
void _EXIT(<int>) : terminates program "normally" with <int> exit code; doesnt perform any clean up however
void quick_exit(<int>) : terminates program "normally" with <int> exit code; doesnt perform any clean up however, but does call
the functions specified by at_quick_exit()s (see BELOW)
void exit(<int>) : terminates program normally with <int> exit code
int atexit([void func]) : calls [void func] without arguments automatically on normal termination; if multiple atexit() functions were
called their [void func]s get executed in FIFO order
int at_quit_exit([void func]) : calls [void func] without arguments automatically on quick exit (see ABOVE); if multiple atexit() functions were
called their [void func]s get executed in FIFO order
char* getenv([char*]) : returns the value of environmental variable named [char*]; (or NULL)
int system([char*]) : executes [char*] system command (or atleast tries to)
math:
num abs([num]) : returns absolute value; (distance from 0)
long labs([long]) : as above, but with longs
long long llabs([long long], [long long]) : as above, but with long longs
div_t div([int1], [int2]) : returns a div_t struct containing [int1]/[int2] and the remainder
ldiv_t ldiv([long], [long]) : as above, but with longs
lldiv_t lldiv([long long], [long long]) : as above, but with long longs
char:
int mblen([char*], [size_t]) : returns length of multibyte char [char*], examining a maximum of [size_t] bytes
int mbtowc([wchar_t*], [char*], [size_t]) : converts a maximum of [size_t] bytes of multibyte char [char*] to wchar_t and places it to [wchar_t*]
int wctomb([char*], [wchar_t]) : converts [wchar_t] to multibyte char and places it into [char*]
size_t mbstowcs([wchar_t*], [char*], [size_t]) : converts multibyte string [char*] to a maximum of [size_t] wchar_t chars and places it to [wchar_t*]
size_t wcstombs([char*], [wchar_t*], [size_t]) : converts wide char string [wchar_t*] to a maximum of [size_t] bytes of multibyte chars and places it
to [char*]
misc:
void* bsearch([pointer1], [pointer2], : returns a pointer to an element of equal to [pointer1] from the memory block
[size_t1], [size_t2], from [pointer2] to [pointer2]+([size_t1]*[size_t2]); [pointer2] being the first element in an array to
[FUNC]) exemine, [size_t1] being the number of elements to exemine, [size_t2] being the size of the elemets in
bytes and [FUNC] being the function to which exemine by;
the returned element is not guaranteed to be the first in the array;
[FUNC] shall have the following prototype: int [name](const void* [key_name], const void* [elem_name]);
[FUNC] shall return 0 if the key and the elem match;
void qsort([pointer], [size_t1], : sorts the elements of an array using [FUNC]; [pointer] being the first element of the array to be sorted,
[size_t2], [FUNC]) [size_t1] being the number of elements, [size_t2] being the size of the elements in bytes and [FUNC]
being the function to sort by;
[FUNC] shall have the following prototype: int [name](const void* [arg1], const void* [arg2])
[FUNC] shall return:
<0 - [arg1] goes BEFORE [arg2]
0 - [arg1] and [arg2] are equilent
• 0 - [arg1] goes AFTER [arg2]
Structs:
div_t : holds the results of a div(); has two members quot(ient) and rem(inder)
ldiv_t : as above, but with ldiv()
lldiv_t : as above, but with lldiv()
Macros:
EXIT_FAILURE : expands to system dependent exit code signaling failure
EXIT_SUCCESS : expands to system dependent exit code signaling success
MB_CUR_MAX : expands to maximum number of bytes in a multibyte char
RAND_MAX : expands to the maximum value returned by rand()
------------------------
<string>
------------------------
#include <string.h>
Functions:
Copy:
• direct copies overlapping should be taken into account
void* memset([pointer], [char], [size_t]) : set first [size_t] bytes from [pointer] to [char]
void* memcpy([pointer1], [pointer2], [size_t]) : copies [size_t] (see AT <stddef>) bytes from [pointer2] to [pointer1] directly
void* memmove([pointer1], [pointer2], [size_t]) : copies [size_t] (see AT <stddef>) bytes from [pointer2] to [pointer1] with an intermediate buffer
char* strcpy([char1*], [char2*]) : copies [char2*] to [char1*] directly; the NULL byte also gets copied
char* strncpy([char1*], [char2*], [size_t]) : copies [size_t] (see AT <stddef>) bytes from [char2*] to [char1*] directly;
if the NULL byte is reached before [size_t] bytes were copied [char1*] is padded with 0s;
a NULL byte will also be appended to [char1*]
char* strcat([char1*], [char2*]) : append [char1*] with [char2*] directly; the NULL byte of [char1*] will get replaced with
[char2*]'s 0th char
char* strncat([char1*], [char2*], [size_t]) : append [char1*] with [char2*] first [size_t] and a NULL byte directly (does not pad with 0s)
Comparison:
int memcmp([pointer1], [pointer2], [size_t]) : compares the first [size_t] bytes of [pointer1] and [pointer2];
<0 -> the first non-matching byte has a lower value in [pointer1];
• 0 -> the first non-matching byte has a higher in [pointer1];
0 -> the two are equal
int strcmp([char1*], [char2*]) : same as above, except no [size_t] is provided as the function stops on the first (string terminating) '\00'
int strcoll([char1*], [char2*]) : same as above, but the function uses the locale character set order (see AT setlocale())
int strncmp([char1*], [char2*], [size_t]) : same as memcmp() (see ABOVE), but if it stops if a NULL byte is hit
int strxfrm([char1*], [char2*], [size_t]) : transforms [char2*] and places its first [char1*] in such a way that it returns the same
results with strcmp() and strcoll() (see ABOVE)
Searching:
void* memchr([pointer], [char], [size_t]) : returns a pointer to the where [char] is found in the first [size_t] bytes of [pointer] or NULL
char* strchr([char*], [char]) : returns a char* to where [char] is FIRST found in [char*] or NULL
char* strrchr([char*], [char]) : returns a char* to where [char] is LAST found in [char*] or NULL
char* strstr([char1*], [char2*]) : returns a char* to where [char2*] is found in [char1*] or NULL
size_t strcspn([char1*], [char2*]) : returns the number of chars BEFORE any of [char2*]s chars were found in [char1*] or [char1*]s length
char* strpbrk([char1*], [char2*]) : returns the number of chars BEFORE any of [char2*]s chars were found in [char1*] or NULL
size_t strspn([char1*], [char2*]) : returns the number of chars in [char1*] that match any of [char2*]s chars
Misc:
char* strerror(<int>) : returns a string containing an error message generated from <int>
size_t strlen([char*]) : returns the length of [char*] as size_t (NULL termination not included)
char* strtok([char1*], [char2*]) : returns a segment of [char1*] until delimeter [char2*] is found or NULL; the delimeter is not included;
alternatively on passing in NULL as [char1*] the function continues to split the last char* passed
------------------------
<tgmath>
------------------------
#include <tgmath.h>
• provides macro over loads of <math.h> and <complex.h>
-----------------------
<time>
-----------------------
#include <time.h>
Functions:
clock_t clock() : returns ticks passed since the launch of the program in clock_t
double difftime([time_t1], [time_t2]) : returns [time_t1] - [time_t2] in double
tm* gmtime([time_t*]) : returns [time_t] converted to tm*, representing GMT (UTC)
tm* localtime([time_t*]) : returns [time_t] converted to tm*, representing the local timezone
time_t mktime([tm*]) : returns [tm*] converted to time_t
time_t time([time_t*]) : returns number of seconds since epoch in time_t and also sets [time_t]
to that value (unless NULL was passed in)
char* ctime([time_t*]) : returns [time_t*] converted to human-readable string; "Www Mmm dd hh:mm:ss yyyy"
char* asctime([tm*]) : returns [tm*] converted to human-readable string; "Www Mmm dd hh:mm:ss yyyy"
size_t strftime([char*], [size_t], : copies [tm*] by the parameters of [format] (see BELOW) [size_t] chars (ie its max) to [char*]
[format], [tm*])
Structs:
tm : contains various time datas, all of which are ints
------------------------------------------------
| Member | Meaning | Range |
------------------------------------------------
| tm_sec | seconds after the minute | 0-61 |
| tm_min | minutes after the hour | 0-59 |
| tm_hour | hours since midnight | 0-23 |
| tm_mday | day of the month | 1-31 |
| tm_mon | months since January | 0-11 |
| tm_year | years since 1900 | N/A |
| tm_wday | days since Sunday | 0-6 |
| tm_yday | days since January 1 | 0-365 |
| tm_isdst | Daylight Saving Time flag | N/A |
------------------------------------------------
Typedefs:
time_t : long
clock_t : long
Macros:
CLOCKS_PER_SEC : expands to clock ticks per second
[format]:
%([modifier])[specifier]
• [format] is a char*
• '%' -> "%%"
[modifiers]:
E : uses locales alternative representation (usable with: c, C, x, X, y, Y)
O : uses locales alternative numeric symbols (usable with d, e, H, I, m, M, S, u, U, V, w, W, y)
[specifiers]:
• the specifiers marked with '°' are locale dependent (see AT <locale>)
° a : short weekday name
° A : full weekday name
° b : short month name
° B : full month name
° c : date and time ("Www Mmm dd hh:mm:ss yyyy")
C : year (integer) divided by 100
d : day of the month; 0 padded {"09"}
D : short date ("MM/DD/YY")
e : day of the month; space padded {" 9"}
F : short date ("YYYY-MM-DD")
g : week-based year, last two digits (every year starts from Monday and months are irrelevant)
G : week-based year
° h : same as b
H : hour in 24h format {18}
I : hour in 12h format {06}; 0 padded
j : day of the year; 0 padded {098}
m : month in decimal; 0 padded {04}
M : minutes; 0 padded {03}
n : new line
p : AM/PM
° r : 12h time {12:38:21 PM}
R : 24h time ("HH:MM")
S : seconds; 0 padded {04}
t : horizontal tab
T : ISO 8601 time format ("HH:MM:SS")
u : ISO 8601 decimal week day weekday (1-7)
U : week number; the first Sunday is the first day of week 1; 0 padded
V : ISO 8601 week number (0 padded)
w : week day in decimal; Sunday == 0
W : week number; the first Monday is the first day of week 1; 0 padded
° x : date
° X : time
y : last two digits of year; 0 padded {02}
Y : year
z : ISO 8601 offset from GMT (UTC) (1m == 1, 1h == 100)
° Z : timezone name
-----------------------
<uchar>
-----------------------
#include <uchar.h>
• "Unicode CHAR"
Functions:
size_t c16rtomb([char*], [char16_t], [mbstate_t]) : converts [char16_t] to multibyte char using [mbstate_t] and places it to [char*]
size_t 16rtomb([char*], [char32_t], [mbstate_t]) : converts [char32_t] to multibyte char using [mbstate_t] and places it to [char*]
size_t brtoc16([char16_t], [char*], [mbstate_t]) : converts multibyte char [char*] to char16_t using [mbstate_t] and places it to [char16_t]
size_t brtoc16([char32_t], [char*], [mbstate_t]) : converts multibyte char [char*] to char32_t using [mbstate_t] and places it to [char32_t]
Macros:
__STD_UTF_16__ : if defined char16_t has UTF-16 encoding
__STD_UTF_32__ : if defined char32_t has UTF-32 encoding
-----------------------
<wchar>
-----------------------
#include <wchar.h>
Functions:
Same as similarly named functions, but with wchar_t; (the arguments are not written out, but exist):
— stdio (mostly):
• try removing the 'w' to find the corresponding function
fgetwc()
fgetws()
fputwc()
fputws()
fwprintf()
fwscanf()
getwc()
getwchar()
putwc()
putwchar()
swprintf()
swscanf()
ungetwc()
vfwprintf()
vfwscanf()
vswprintf()
vswscanf()
vwprintf()
vwscanf()
wprintf()
wscanf()
— stdlib:
• try replacing the "wc" with "str" to find the corresponding function
wcstod()
wcstof()
wcstol()
wcstold()
wcstoll()
wcstoul()
wcstoull()
— string
• try replacing the "wcs" with "str" to find the corresponding function
wcscat()
wcschr()
wcscmp()
wcscoll()
kjscpy()
wcscspn()
wcslen()
wcsncat()
wcsncmp()
wcsncpy()
wcspbrk()
wcsrchr()
wcsspn()
wcsstr()
wcstok()
wcsxfrm()
wmemchr()
wmemcmp()
wmemcpy()
wmemmove()
wmemset()
— time
• try replacing the "wc" with "str" to find the corresponding function
wcstime()
Other:
wint_t btowc([char]) : returns [char] converted to wchar_t
int wctob([wint_t]) : returns [wint_t] converted to char or EOF
size_t mbrtowc([wchar_t*], [char*], : interprets [size_t] bytes at [char*] as a multibyte char and converts it
[size_t], [mbstate_t]) to wide char using [mbstate_t] and stores it in [wchar_t*]
size_t wcrtomb([char*], [wchar_t], [mbstate_t]) : converts wide char [wchar_t] to multibyte char using [mbstate_t] and places it to [char*]
size_t mbsrtowcs([wchar_t*], [char**], : converts multibyte string [char**] to a maximum of [size_t] wide chars
[size_t], [mbstate_t]) using [mbstate_t] and places it to [wchar_t*]
size_t wcstrtombs([char*], [wchar_t**], : converts wide char sting [wchar_t**] to a maximum of [size_t] bytes long multi byte string
[size_t], [mbstate_t*]) using [mbstate_t] and places it to [char*]
int mbsinit([mbstate_t*]) : returns whether [mbstate_t*] points to a valid mbstate_t object
Types:
wchar_t : C style wide character; distinct basic type in C++ therefor not actually defined in any header
wint_t : int capable of representing any wchar_t that is a member of the extended char set
Structs:
mbstate_t : hold the information required to transform multibyte chars to wchar_t; sometimes just an int or a union
Macros:
WCHAR_MAX : expands to the largest possible value of wchar_t
WCHAR_MIN : expands to the smallest possible value of wchar_t (== (WCHAR_MAX * -1) -1)
WEOF : wint_t EOF
------------------------
<wctype>
------------------------
#include <wctype.h>
Functions:
Same as similarly named functions in <ctype.h>, but with wint_t; (the arguments are not written out, but exist):
iswalnum()
iswalpha()
iswblank()
iswcntrl()
iswdigit()
iswgraph()
iswlower()
iswprint()
iswpunct()
iswspace()
iswupper()
iswxdigit()
towlower()
towupper()
Other:
iswctype([wint_t], [wctype_t]) : returns whether [wint_t] is [wctype]
towctrans([wint_t], [wctrans_t]): returns [wint_t] converted to what [wctrans_t] specifies
wctrans([char*]) : returns a wctrans_t specified by [char*] { wctrans_t c = wctrans("toupper"); }
wctype([char*]) : returns a wctype_t specified by [char*] { wctype_t d = wctype("digit"); }
Typedefs:
[wctype_t]:
• unsigned long
"alnum" == iswalnum()
"alpha" == iswalpha()
"blank" == iswblank()
"cntrl" == iswcntrl()
"digit" == iswdigit()
"graph" == iswgraph()
"lower" == iswlower()
"print" == iswprint()
"punct" == iswpunct()
"space" == iswspace()
"upper" == iswupper()
"xdigit" == iswxdigit()
[wctrans_t]:
• const int_least32_t
"tolower" == towlower()
"toupper" == towupper()
===============================================
unix_std
#define unix_std::: \
I====================================================================================================================\
I====================================================================================================================\
I _ _ _ _____ _ _ _ _ _ _ \
I | | | | (_) / ___| | | | | | | | (_) | \
I | | | |_ __ ___ __ \ `--.| |_ __ _ _ __ __| | __ _ _ __ __| | | | _| |__ _ __ __ _ _ __ _ _ \
I | | | | '_ \| \ \/ / `--. \ __/ _` | '_ \ / _` |/ _` | '__/ _` | | | | | '_ \| '__/ _` | '__| | | | \
I | |_| | | | | |> < /\__/ / || (_| | | | | (_| | (_| | | | (_| | | |___| | |_) | | | (_| | | | |_| | \
I \___/|_| |_|_/_/\_\ \____/ \__\__,_|_| |_|\__,_|\__,_|_| \__,_| \_____/_|_.__/|_| \__,_|_| \__, | \
I __/ | \
I |___/ \
I====================================================================================================================\
I====================================================================================================================I
------------------
<unistd.h>
------------------
#include <unistd.h>
• "UNIx STanDard library"
Functions:
int chdir([char*])
int sleep(<int>) : block execution for <int> seconds
int fork() : creates an identical copy of the program;
returns:
1-30000 - inside the original; the PID of the forked process
0 - inside the forked process
— 1 - on failure
execvpe(<char*>, char**-1, char**-2)
~~~~~~~~~
getopt:
~~~~~~~~~
int getopt(int argc, char *const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#include <getopt.h>
int getopt_long(int argc, char *const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char *const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
------------------
<fcntl.h>
------------------
#include <fcntl.h>
Function:
int open([char*], [O_FLAGS], ...) : returns the lowest file descriptor not in use opened according to [O_FLAGS];
the variadic arguments are dependent on [O_FLAGS]
this beauty allows one to open a file as stdin/stdout/stderr
Macros:
[O_FLAGS]:
O_RDONLY : "ReaD ONLY"
O_WRONLY : "WRite ONLY"
O_RDWR : "ReaD WRite"
O_APPEND : "Append"
O_CREAT : "CREATe"; create if file doesnt exists; requires a extra int argument specifying the permissions
dont forget to use an octal literal, chud
----------------
<stat.h>
----------------
#include <sys/stat.h>
man 2 stat
struct-s:
stat
Functions:
int stat(const char *restrict pathname,
struct stat *restrict statbuf)
c_
#define c_3th_party_libs\
#define 3th_party_c_libs::: \
I==================================================================================================\
I==================================================================================================\
I _____ _ _ ______ _ _ _ _ _ \
I |____ | | | | | | ___ \ | | | | (_) | (_) \
I _/ / | |_| |__ | |_/ /_ _ _ __| |_ _ _ | | _| |__ _ __ __ _ _ __ _ ___ ___ \
I :__ \ | __| '_ \ | __/ _` | '__| __| | | | | | | | '_ \| '__/ _` | '__| |/ _ \/ __| \
I .___/ / | |_| | | | | | | (_| | | | |_| |_| | | |___| | |_) | | | (_| | | | | __/\__ \ \
I \____/ \__|_| |_| \_| \__,_|_| \__|\__, | \_____/_|_.__/|_| \__,_|_| |_|\___||___/ \
I __/ | (C++ 3th Party Libraries) \
I |___/ \
I==================================================================================================\
I==================================================================================================I
• when searching for new libraries, check the pages of library managers,
even if you dont use the particular manager
C_package_managers:
CCAN : "Comprehensive C Archive Network" (after CPAN)
• seems to be a bloody mess
clib
CXX_package_managers:
• conan
• vcpkg
• hunter
• Buckaroo
• so, clearly C has a problem with package management
• the way i like to interpret it is that we have a problem with package management in general,
it just doesnt show usually from all the ducktape
— this boils down to multiple smaller problems:
• dependency resolving
• per-package options
• installation locations {global/local}
• package formats
• platform support
• notice that this applies to both system and language packages
• ideally a general solution should exist
— enter gentoo prefixes:
• guess what, all of this issues are addressed by portage;
wouldnt it be great if we could just use portage?
• a gentoo prefix is a local installation of portage
• i have a strong intuition that it could be used to manage C packages;
with a custom eclass and repository
— each library gets its own ebuild:
• this decouples the library from the package manager
(unlike what some C solutions, Node and Rust does)
• you can easily create private repositories
• libraries can be amalgamated into header only libraries,
based on USE flags
• currently in an unstable stage
-----------
stb: stb:
-----------
https://github.com/nothings/stb
• "Single-file public domain (or miT licensed) liBraries for C/C++"
(seriously now, the acronym is a mystery)
• carefully curated club of header only libraries
• you are advised to scan their list and return later when the use-case arises
----------------
libmagic: libmagic:
----------------
#include <magic.h>
man libmagic
• used for determining mimetypes
Functions:
magic_open([flags]) : returns magic_t according to [flags]
magic_load([magic_t], [char*]) : loads [magic_t] with [char*] database; pass NULL to use the default database
magic_close([magic_t]) : closes magic database used by [magic_t]
magic_file([magic_t], [char*]) : returns char* representing the eval of file [char*] with [magic_t]
Structs:
magic_t
### How to get the mimetype of a file in C ###
#include <magic.h>
#include <stddef.h>
magic_t my_mimetype_reader;
signed main(int argc, char * argv[]) {
if (argc != 2) {
printf("%s <file>\n", argv[0]);
return 1;
}
my_mimetype_reader = magic_open(MAGIC_MIME_TYPE);
if (magic_load(my_mimetype_reader, NULL) == -1) { return 1; }
const char * filename = magic_file(my_mimetype_reader, argv[1]);
if (filename == NULL) { return 1; }
puts(filename);
magic_close(my_mimetype_reader);
return 0;
}
#
-----------
sds
-----------
• string library
• the header is reasonably readable, consult it
• recommended
sds_strings:
• store their size
• compatible with functions taking const char *
• can preallocate
• can store '\0's, acting like a buffer
struct-s:
sds
Most_important_functions:
sds sdsnew(const char *)
void sdsfree(sds)
size_t sdslen(sds)
sds sdscat(sds, const char *)
sds sdscatsds(sds, sds)
void sdsclear(sds);
------------
Curl
------------
#include <curl/curl.h>
https://curl.se/libcurl/c/
• see "Linux/Networking/curl"
— libcurl has 3 different bunch of networking utilities, for different uses:
— easy
• for single requests at a time
— multi
• for performing multiple requests at the same time
— multi_socket
• variation of multi
• for performing hundreds or thousands of requests at the same time
• event-based
Functions:
Easy:
CURL* curl_easy_init() : returns CURL
curl_easy_cleanup([CURL]) : deletes [CURL]
int curl_easy_setopt([CURL], [option], [...]) : sets [CURL]s [opt] option to [...] (see [option] BELOW)
curl_easy_perform([CURL]) : performs a curl
curl_easy_getinfo([CURL], [infopt], ...) : stores the
Multi:
curl_multi_init() : returns CURL
curl_multi_add_handle([CURLM*], [CURL*]) : appends [CURLM*]s easy handle list with [CURL*]
curl_multi_remove_handle([CRULM*], [CURL*]) : removes [CURL*] from [&CURLM]s easy handle list
curl_multi_setopt(?!)
Structs:
• if it werent obvious, you should only have object pointers in your program { CURL *curl = curl_easy_init(); }
CURL : easy handle
CURLM : multi handle; container for easy handles (CURLs)
[opt]:
CURLOPT_CUSTOMREQUEST : http request type; [...] -> C string
CURLOPT_URL : the url; [...] -> C string, which shall contain the protocol
CURLOPT_WRITEFUNCTION : a function to write the response to; [...] -> function*; see AT ../WRITEFUNCTION;
CURLOPT_WRITEDATA : the custom argument to pass to CURLOPT_WRITEFUNCTION;
setting NULL while CURLOPT_WRITEFUNCTION is also NULL will segfault
[infopt]:
CURLINFO_RESPONSE_CODE : store the
WRITEFUNCTION:
typedef size_t (*)(char*, size_t, size_t, void*) WRITE_FUNCTION;
char* arg1 - data recieved in; never NULL terminated
size_t arg2 - "unit"; always 1
size_t arg3 - "amount"; size of data given in arg2
void* - userdata; set by CURLOPT_WRITEDATA
• on success it shall return arg2*arg3
• setting it to NULL will cause curl to use its default which is plain copy to a FILE*
MACROS:
CURLE_OK
---------------
sqlite3
---------------
• its great, do use it
• the performace is so good that repeated INSERTs
beat repeated mallocs out of the water
https://www.sqlite.org/cintro.html
Structs:
pass
Functions:
int sqlite3_open([char*], [sqlite3*])
int sqlite3_close([sqlite3*])
int sqlite3_exec([sqlite3*],
[const char*],
[int (*)(void*, int, char**, char**)],
[void*],
[char**]
)
callback:
int (*)(
void*, : data; 4th argument of exec
int, : column count
char** : column values (as string)
char** : column names
)
Macros:
SQLITE_OK : return val signaling success
---------------
libdill: libdill:
---------------
#include <libdill.h>
https://libdill.org/
• adds go like concurrency to C
• convenient
• very nice interface
• has native networking support for multiple protocols
• 64 bit Linux only
• I recommend it
Use_cases:
• interactive terminal interfaces with long running processes
where threading would be overkill
• non-FAANG tier servers
// @BAKE gcc -o $*.out $@ /home/anon/Swap/libdill/.libs/libdill.a -I/home/anon/Swap/libdill/ -lm -std=gnu23
#include <stdio.h>
#include <math.h>
#include <libdill.h>
coroutine
void worker(int ch) {
const size_t target = 100'000'000;
for (size_t i = 1; i < target; i++) {
if ((i % (target/100)) == 0) {
int percentage = i / (target/100);
chsend(ch, &percentage, sizeof(percentage), now() + 10);
}
int ignore = sin(0.5) * i * cos(1/i);
}
const int hundred = 100;
chsend(ch, &hundred, sizeof(100), now() + 10);
}
coroutine
void reporter(int ch) {
int percentage;
while (true) {
chrecv(ch, &percentage, sizeof(percentage), now() + 10);
printf("\033[0G[");
for (int i = 0; i < 10; i++) {
printf((i < (percentage / 10)) ? "=" : " ");
}
printf("] %d%%", percentage);
fflush(stdout);
if (percentage == 100) { break; }
}
}
int main() {
int ch[2];
chmake(ch);
int b = bundle();
bundle_go(b, worker(ch[0]));
bundle_go(b, reporter(ch[1]));
bundle_wait(b, -1);
hclose(b);
printf("\n");
return 0;
}
c_posix_libs
#define c_posix_libs:::: \
| ___ ___ ___ _____ __ \
| | _ \/ _ \/ __|_ _\ \/ / \
| | _/ (_) \__ \| | > < \
| |_| \___/|___/___/_/\_\ |
----------------
dirent.h
----------------
#include <dirent>
DIR *[name] : pointer to directory
readdir([pointer to dirctory])
--------
libgen
--------
#include <libgen.h>
man 0p libgen.h
• might be part of the C std
• "LIBrary GENeral purpose"
Functions:
• trailing '/' chars are not counted as part of the pathname
char* dirname(<char*>)
char* basename(<char*>)
?!:
• https://web.archive.org/web/20230723143439/https:
bgets() (similar to modern getdelim())
bufsplit()
copylist()
gmatch() (similar to modern fnmatch())
isencrypt()
mkdirp() (create directories in a path name)
rmdirp() (remove directories in a path name)
p2open() and p2close() (bi-directional communication with a sub-process — related to popen() and pclose())
pathfind()
regcmp() and regex() (regular expressions)
strfind(), strrspn(), strtrns()
strccpy(), strcadd(), strecpy(), streadd()
+----------+---------+----------+
| path | dirname | basename |
+----------+---------+----------+
| /usr/lib | /usr | lib |
| /usr/ | / | usr |
| usr | . | usr |
| / | / | / |
| . | . | . |
| .. | . | .. |
+----------+---------+----------+
readline
#define readline\
#define gnu_history\
#define gnu_readline:::: \
| ___ _ _ _ ___ _ _ _ \
| | _ \___ __ _ __| | | (_)_ _ ___ / / || (_)__| |_ ___ _ _ _ _ \
| | / -_| _` / _` | |__| | ' \/ -_|/ /| __ | (_-< _/ _ \ '_| || | \
| |_|_\___\__,_\__,_|____|_|_||_\___/_/ |_||_|_/__/\__\___/_| \_, | \
| |__/ |
{
#include <stdio.h>
or
#include <cstdio>
}
#include <readline/readline.h>
#include <readline/history.h>
GNU Readline library
• de facto standard for ordinary commandline applications
• makes handling meta chars { arrows; backspace; delete; tab } a piece of cake
• widely used { bash }
• the two headers can be used independently
Files:
history:
~/.history : where user command history is saved and read from
readline:
${INPUTRC} : environment variable naming a file to read config from
~/.inputrc : personal config file; only read if ${INPUTRC} is not set
/etc/.inputrc : system-wide config file;
only read if ~/.inputrc doesnt exist or cannot be read
Readline_Config:
• done throught a config file
• all directives must have their own line
• empty lines are ignored
#[...]
[shortcut]: [universal-argument] : sets a key binding [shortcut] for executing [universal argument]
set [variable] [value] : sets [variable] to [value]
○ [shortcut]
• a list of key separated by '-'s or GNU Emacs style syntax between quotes
{ C-Control-u: [...]
"\C-u": [...]
}
— symbolic char names:
DEL
ESC
ESCAPE
LFD
NEWLINE
RET
RETURN
RUBOUT
SPACE
SPC
TAB
○ [universal-argument]
beginning-of-line (C-a)
end-of-line (C-e)
forward-char (C-f)
backward-char (C-b)
forward-word (M-f)
backward-word (M-b)
previous-screen-line
next-screen-line
clear-display (M-C-l)
clear-screen (C-l)
redraw-current-line
accept-line (Newline, Return)
previous-history (C-p)
next-history (C-n)
beginning-of-history (M-<)
end-of-history (M->)
reverse-search-history (C-r)
forward-search-history (C-s)
non-incremental-reverse-search-history (M-p)
non-incremental-forward-search-history (M-n)
history-search-backward
history-search-forward
history-substring-search-backward
history-substring-search-forward
yank-nth-arg (M-C-y)
yank-last-arg (M-., M-_)
operate-and-get-next (C-o)
end-of-file (usually C-d)
delete-char (C-d)
backward-delete-char (Rubout)
forward-backward-delete-char
quoted-insert (C-q, C-v)
tab-insert (M-TAB)
self-insert (a, b, A, 1, !, ...)
transpose-chars (C-t)
transpose-words (M-t)
upcase-word (M-u)
downcase-word (M-l)
capitalize-word (M-c)
overwrite-mode
kill-line (C-k)
backward-kill-line (C-x Rubout)
unix-line-discard (C-u)
kill-whole-line
kill-word (M-d)
backward-kill-word (M-Rubout)
unix-word-rubout (C-w)
unix-filename-rubout
delete-horizontal-space (M-\)
kill-region
copy-region-as-kill
copy-backward-word
copy-forward-word
yank (C-y)
yank-pop (M-y)
digit-argument (M-0, M-1, ..., M--)
universal-argument
complete (TAB)
possible-completions (M-?)
insert-completions (M-*)
menu-complete
menu-complete-backward
delete-char-or-list
start-kbd-macro (C-x ()
end-kbd-macro (C-x ))
call-last-kbd-macro (C-x e)
print-last-kbd-macro ()
re-read-init-file (C-x C-r)
abort (C-g)
do-lowercase-version (M-A, M-B, M-x, ...)
prefix-meta (ESC)
undo (C-_, C-x C-u)
revert-line (M-r)
tilde-expand (M-&)
set-mark (C-@, M-<space>)
exchange-point-and-mark (C-x C-x)
character-search (C-])
character-search-backward (M-C-])
skip-csi-sequence
insert-comment (M-#)
dump-functions
dump-variables
dump-macros
emacs-editing-mode (C-e)
vi-editing-mode (M-C-j)
○ [variable]
bell-style : decides what happens when an application tries to ring the bell
none - do nothing
visible - flash the screen
audiable - give off sound; default
bind-tty-special-chars : whether to attempt binding control chars
[bool] - on default
blink-matching-paren : whether to highlight the corresponding parenthesis
[bool] - off default (by briefly moving the cursor) when a corresponding one
is inserted
colored-copletion-refix : whether to color auto completion common prefix appropriate to filetype;
[bool] - off default dependent on ${LS_COLOR} environment variable
colored-stats : whether to color auto completion suggestions appropriate to filetype;
[bool] - off default dependent on ${LS_COLOR} environment variable
comment-begin [string = "#"] : the string that is inserted in vi mode when the insert-comment command is executed
completion-display-width [int = -1] : the number of column to be used for auto suggestion; a negative number signals unlimited
completion-ignore-case : whether to make auto completion case insensitive
[bool] - off default
completion-map-case : whether to make '-' == '_' when completion-ignore-case is on
[bool] - off default
completion-prefix-display-length [int = 0] : number of chars to display from common prefixes
without replacing with "..." on auto completion
disable-completion : whether to disable auto completion altogether
[bool] - off default
echo-control-characters : whether to echo control chars { ^C }
[bool] - on default
editing-mode : sets short-cut style
emacs - GNU Emacs; default
vi - Vi (see AT /Programs/Text/Vim)
enable-bracketed-paste : whether to buffer pastes; prevents pastes from being interpreted as control chars
[bool] - on default
expand-tilde : whether to expand tildes when auto completing
history-preserve-point : ?!
history-size <int> : maximum history size; not set by default
visible-stats : whether to display GNU file (the program; see AT /Linux/File_managing/file)
information when listing possible auto completions
○ [bool]
on/On
off/Off
Conditional_instructions:
• modelled after C preprocessor directives, therefor no in-depth explanation is included here; see AT "C++/Preprocessor"
$if [condition]
$else
$endif
$include [file]
○ [condition]:
mode=[m]
emacs
vi
term=<string> : where <string> the name of a specific terminal emulator(s executable);
the name is tested till hyphens and the full word
{ "sun" matches both "sun" and "sun-cmd" }
[application] : set by the application { Bash }
Shortcuts:
• default-s
[alt] + <int> : specifies repeat count (for next shortcut)
[ctrl] + [l] : flushes terminal
[ctrl] + [r] : reverse search command history from current position
[Up arrow] || [ctrl] + [p] : previous command in history
[Down arrow] || [ctrl] + [n]: next command in history
[ctrl] + [z] : moves current foreground process to the back
Movement:
[ctrl] + [b] : "back"; moves backwards one char
[ctrl] + [f] : "forward"; moves forwards one char
[alt] + [b] : "word back"; moves backwards one word
[alt] + [f] : "word forward"; moves forwards one word
[ctrl] + [a] : == [home]
[ctrl] + [e] : == [end]
Editing:
[ctrl] + [d] : "delete"; delete-s char under the cursor
[alt] + [d] : "word delete"; delete-s until the end of the current word
[ctrl] + [k] : "kill"; cuts all text from right of the cursor
[ctrl] + [u] : cuts all text from left of the cursor
[ctrl] + [w] : cuts till the first space from left of the cursor
[ctrl] + [y] : "yank"; pastes whatever was cut most recently with [ctrl] + [k] || [ctrl] + [u] || [ctrl] + [w]
[alt] + [.] : pastes the last argument of the last command run
Macros:
#define rl_ivoidfunc_t rl_hook_func_t
• see AT "./Typedef"
RL_STATE_NONE : readline has not yet been called, nor has it begun to initialize
RL_STATE_INITIALIZING : readline is initializing its internal data structures
RL_STATE_INITIALIZED : readline has completed its initialization
RL_STATE_TERMPREPPED : readline has modified the terminal modes to do its own input and redisplay
RL_STATE_READCMD : readline is reading a command from the keyboard
RL_STATE_METANEXT : readline is reading more input after reading the meta-prefix character
RL_STATE_DISPATCHING : readline is dispatching to a command
RL_STATE_MOREINPUT : readline is reading more input while executing an editing command
RL_STATE_ISEARCH : readline is performing an incremental history search
RL_STATE_NSEARCH : readline is performing a non-incremental history search
RL_STATE_SEARCH : readline is searching backward or forward through the history for a string
RL_STATE_NUMERICARG : readline is reading a numeric argument
RL_STATE_MACROINPUT : readline is currently getting its input from a previously-defined keyboard macro
RL_STATE_MACRODEF : readline is currently reading characters defining a keyboard macro
RL_STATE_OVERWRITE : readline is in overwrite mode
RL_STATE_COMPLETING : readline is performing word completion
RL_STATE_SIGHANDLER : readline is currently executing the readline signal handler
RL_STATE_UNDOING : readline is performing an undo
RL_STATE_INPUTPENDING : readline has input pending due to a call to rl_execute_next()
RL_STATE_TTYCSAVED : readline has saved the values of the terminal’s special characters
RL_STATE_CALLBACK : readline is currently using the alternate (callback) interface
RL_STATE_VIMOTION : readline is reading the argument to a vi-mode "motion" command
RL_STATE_MULTIKEY : readline is reading a multiple-keystroke command
RL_STATE_VICMDONCE : readline has entered vi command (movement) mode at least one time during the current call to readline()
RL_STATE_DONE : readline has read a key sequence bound to accept-line and is about to return the line to the caller
Globals:
char* rl_line_buffer : the line typed so far
int rl_point : cursor position inside rl_line_buffer
int rl_end : size of rl_line_buffer
int rl_mark :
int rl_done : setting this to non-zero causes readline to return the line immediately
int rl_num_chars_to_read : the maximum number of chars to read before returning
int rl_pending_input : set to add a single char to the input stream
int rl_dispatching : non-zero if a function was called with a keybinding (meant to be tested)
int rl_erase_empty_line :
char* rl_prompt : the prompt readline() uses and set by its argument; do not modify directly
char* rl_display_prompt : the string displayed as the prompt; usually *this == rl_prompt unless a function { incremental search }
modifies it temporarily
int rl_already_prompted : ?!
const char* rl_library_version : int encoding of the current version of the library as 0xMMmm where MM
is the major version number and mm is the minor version number
int rl_gnu_readline_p : always set to 1, denoting that this is gnu readline rather than some emulation
const char* rl_terminal_name : terminal _type_ { xterm-256color }
const char * rl_readline_name :
FILE* rl_instream : FILE to read input from; if NULL stdin is default-ed
FILE* rl_outstream : FILE to write output to; if NULL stdout is default-ed
int rl_prefer_env_winsize : if non-zero, readline gives values found in the ${LINES} and ${COLUMNS}
environment variables greater precedence than values fetched from the kernel
when computing the screen dimensions
char* rl_executing_macro :
int rl_explicit_arg :
int rl_numeric_arg :
int rl_editing_mode : editing mode
0 = Vi
1 = Emacs
Keymap rl_executing_keymap : current keymap
Keymap rl_binding_keymap : keymap in which last key binding occurred
Function_pointes:
rl_command_func_t* rl_last_func : the last command function readline() has executed
rl_hook_func_t* rl_startup_hook : function to call before readline() prints the prompt (invoked on every call)
rl_hook_func_t* rl_pre_input_hook : function to call after readline() has printed to prompt,
but before input is being read (invoked on every call)
rl_hook_func_t* rl_event_hook : function to call repeatedly when readline() is waiting for input;
by default, called max 10 times a second
rl_getc_func_t* rl_getc_function :
rl_voidfunc_t* rl_redisplay_function :
rl_vintfunc_t* rl_prep_term_function :
rl_voidfunc_t* rl_deprep_term_function :
Structs:
Keymap
Functions:
History:
Readline:
char* readline([char*]) : prompts user with [char*], lets him input a line than returns it;
the return-ed value is malloc-ed; its the users responsibility to
free it
int rl_add_defun([const char*], : adds a named functionality to readline();
[rl_command_func_t], <int>) ie. (if <int> != -1 &&) if [const char*] is present in the inputrc as a [universal-argument]
its binding detected by readline() will always call [rl_command_func_t]
rl_redisplay() : display rl_line_buffer if the screen doesnt reflect its value
rl_forced_update_display() : display rl_line_buffer
Init:
rl_bind_key([char], [func*]) : calls [func*] if [char] is inserted to readline();
binding '\t' to rl_insert() makes TAB insert itself
Sush:
rl_catch_signals = 0;
rl_catch_sigwinch = 0;
rl_prep_term_function = NULL;
rl_deprep_term_function = NULL;
rl_change_environment = 0;
Typedef:
typedef int rl_command_func_t (int, int);
typedef char *rl_compentry_func_t (const char *, int);
typedef char **rl_completion_func_t (const char *, int, int);
typedef char *rl_quote_func_t (char *, int, char *);
typedef char *rl_dequote_func_t (char *, int);
typedef int rl_compignore_func_t (char **);
typedef void rl_compdisp_func_t (char **, int, int);
typedef int rl_hook_func_t (void);
typedef int rl_getc_func_t (FILE *);
typedef int rl_linebuf_func_t (char *, int);
typedef int rl_intfunc_t (int);
typedef int rl_icpfunc_t (char *);
typedef int rl_icppfunc_t (char **);
typedef void rl_voidfunc_t (void);
typedef void rl_vintfunc_t (int);
typedef void rl_vcpfunc_t (char *);
typedef void rl_vcppfunc_t (char **);
curses
#define curses\
#define ncurses:::: \
I------------------------------------------------------------------------------------------\
I _ _ _____ _ _______ _____ _____ _____ \
I | \ | / __ \ | | | ___ \/ ___| ___/ ___| \
I | \| | / \/ | | | |_/ /\ `--.| |__ \ `--. \
I | . ` | | | | | | / `--. \ __| `--. \ \
I | |\ | \__/\ |_| | |\ \ /\__/ / |___/\__/ / \
I \_| \_/\____/\___/\_| \_|\____/\____/\____/ (ncurses) \
I------------------------------------------------------------------------------------------I
#include <ncurses.h>
• the de facto standard for creating TUIs/pseudo-GUIs
• since terminals are line oriented,
Ncurses always has the y coordinate before
the x coordinate
• has a wide char version and a multi-threaded version
The_NCurses_Universe:
(0;0) X
+-------- Ether --------------------------------------->
|┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|┃ Screen ┃
|┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|┃┌──────────────────────────────────┐┃
|┃│ stdscr │┃
|┃├──────────────────────────────────┤┃
|┃│ │┃
|┃│ ┌──────────┐ │┃
|┃│ │ Window 1 │ │┃ ...
|┃│ ├──────────┤ │┃
|┃│ │ │ │┃
|┃│ │ │ │┃
|┃│ └──────────┘ │┃ ┌──────────┐
|┃│ │┃ │ Window 2 │
|┃│ │┃ ├──────────┤
|┃└──────────────────────────────────┘┃ │ │
|┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ │
| └──────────┘
|
|
|
| ...
|
Y |
|
V
Under_a_microscope:
+ +
cchar_t | cchar_t | cchar_t
. -+---------+---------+---------+-
cchar_t | cchar_t | cchar_t
. -+---------+---------+---------+-
cchar_t | cchar_t | cchar_t
+ +
cchar_t : the atom of the ncurses universe;
a char + meta data {color; boldness}
Ether : is the valid playground of ncurses;
it's visually comprehensible dimension maps to a coordinate system
which starts at the top left corner (with 0;0) and continue-s to infinity;
each coordinate maps to a cchar_t;
negative and fractional coordinates are defined to be non-existent/invalid
Screen : is the physical view port; the part of the Ether that the user see;
by changing the terminals size (or zoom), the size of the screen can change,
but it never moves from the upper left corner
_WINDOW_ : is a high level concept defined by ncurses; it is implemented as struct;
WINDOWs have:
• virtual screen of NxM
• virtual cursor
• position on the screen
Basic usage:
• modify the virtual screen arbitrary
• issue a refresh, to copy the virtual screen to the WINDOW's position in the screen
WINDOWs allow for:
• relative coordinate referencing
• writing to different places of the screen without
having to worry about the changed cursor position
• writing only a part of the screen (for performance)
stdscr : "STandard SCReen"; WINDOW* created on library initialization;
corresponds to the Screen (in size and position), hence the name;
changes its size alongside the screen automatically
Window 1 : is theoretical USER CREATED window; it could be used, say,
to render an ascii converted GIF of a MAGESTIC FUCKING HORSE
Window 2 : is also theoretical USER CREATED window;
it is outside of the Screen, but is completely valid;
if the Screen were to be resized so it fits inside, it would show up normally
Querying:
getbegyx(WINDOW*, int, int)
x──────────┐
│ Window │
├──────────┤
│text█ │ getyx(WINDOW*, int, int)
│ │
└──────────x
getmaxyx(WINDOW*, int, int)
you dont have to query stdscr's size,
COLS and LINES already hold those values you want
Refreshing:
• the act of copying the contents of a WINDOWs virtual screen to the terminal representation
• it make sense so atomic text copying dont waste cycles displaying partial states
Visible Virtual
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
┌──────────┐ ┌──────────┐
│ stdscr │ │ stdscr │
├──────────┤ ├──────────┤
│ │ │ │
│ │ │ │
└──────────┘ └──────────┘
addstr("Quoka");
┌──────────┐ ┌──────────┐
│ stdscr │ │ stdscr │
├──────────┤ ├──────────┤
│ │ │Quoka │
│ │ │ │
└──────────┘ └──────────┘
refresh("Quoka");
┌──────────┐ ┌──────────┐
│ stdscr │ │ stdscr │
├──────────┤ ├──────────┤
│Quoka │ │Quoka │
│ │ │ │
└──────────┘ └──────────┘
Subwindows:
• subwindows share memory with their parent windows
• they seem to be only legal inside the their parent windows
• the idea is to grant relative addressing to a part of a window with minimal memory overhead
• have to be deleted before their parents
rant:
• i think they should make implementing scrolling easy too
• ncurses came out in 1993, yet they are buggy as shit
• the problem seems to be that whoever defined them did it very poorly,
so implementing them is a shot in the dark even if all guide lines are followed;
. see:
$ man 3 subwin
"\
The subwindow functions (subwin, derwin, mvderwin, wsyncup, wsyncdown, \
wcursyncup, syncok) are flaky, incompletely implemented, and not well test‐ \
ed. \
\
The System V curses documentation is very unclear about what wsyncup and \
wsyncdown actually do. It seems to imply that they are only supposed to \
touch exactly those lines that are affected by ancestor changes. The lan‐ \
guage here, and the behavior of the curses implementation, is patterned on \
the XPG4 curses standard. The weaker XPG4 spec may result in slower up‐ \
dates. \
"
• do not waste your time with anything, but the most basic of usages:
new, update, refresh, delete
FUNCTIONS:
PREFIXES:
w : adding the 'w' prefix will apply the function to a specific window;
which must be passed in as an argument preceding the originals
Initialization:
• input taking modes are inherited, ie. doesnt reset on program start up,
there for one of the input mode setting functions (cbreak(); nocbreak(); raw(); noraw())
shall be called explicitly before the first input is taken
• ncurses uses the locale of the calling program by default;
to change this behaviour setlocale() (see AT "/C++/C std/<locale.h>")
initscr() : initialize screen; must be called to be able to use screen manipulation functions
start_color() : initialize colors; must be called to be able to use color manipulation functions
endwin() : frees memory; quits curses
input:
cbreak() : dont wait for enter;
makes characters typed by the user
immediately available to the program;
control chars are unaffected
nocbreak() : disables cbreak mode
raw() : dont wait for enter;
makes characters typed by the user
immediately available to the program;
control chars are also taken uninterpreted
noraw() : disables raw mode
halfdelay(<int>) : like cbreak, but if no input is provided,
it returns ERR after <int> tenths of seconds;
<int> must be between 1 and 255
curs_set(<int>) : sets cursor visibility; return previous cursor visibility
0 - invisible
1 - visible
2 - very visible
echo() : echo user input
noecho() : do not echo user input
keypad([window],[bool]) : makes function keys {arrow key} return a single value
nodelay([window], : whether getch() should not wait for input; if TRUE, on no input provide getch() will return an error
[TRUE|FALSE])
nl() : translate '\n' to "\n\r"; windows default
nonl() : do not translate '\n' to "\n\r"; *nix default
intrflush([WINDOW*], [bool]) : flush on interrupt; "giving the effect of faster response to the interrupt,\
but causing curses to have the wrong idea of what is on the screen"
Output:
refresh() : updates main screen to represent window layout; typically called after each newwin() and delwin()
wrefresh([WINDOW*]) : updates the [WINDOW*] window part of the screen to represent the window buffer
(w)addch([char]) : prints [char]
(w)echochar([char]) : equivalent to: { addch([char]); refresh(); }, but faster
(w)add_wch([cchar_t]) : prints [cchar_t]
(w)echo_wchar([cchar_t]) : equivalent to: { add_wch([cchar_t]); refresh(); }, but faster
(w)addstr([char*]) : prints C-string [char*]
(w)addwstr([wchar_t*]) : prints wide C-string [wchar_t*]
(w)move([int1], [int2]) : moves cursor to the supplied coordinates
(w)printw([format](, [...])) : prints [format]; be haves identical to printf(), see AT "/C++/C std/stdio.h"
mv[print function]([row],[col],[...]) : prints [...] to [row][col]; (overwrites what was there before)
Deletion:
(w)erase() : copies blanks to every position in the window, clearing the screen
(w)clear()
(w)clrtoeol()
Input:
char (w)getch() : returns char
getstr() : gets string; resets halfdelay(), which is logical considering its a series of getch() calls,
but why the fuck isnt that documented anywhere?
(w)scanw([format](, [...])) : reads format; analogous to scanf (see AT "C++/C_Standard_Library/stdio.h")
Cchar:
• (w)add_wch() (see AT "../Output")
• (w)echo_wchar() (see AT "../Output")
getcchar([cchar_t*], [wchar_t*], [attr_t*], : reads the internal state of [cchar_t*] and stores it in the rest of the arguments;
[short*], [void*]) [wchar_t*] is for text; [attr_t*] is for text attributes;
[short*] is for color pair information; [void*] is implementation defined
setcchar([cchar_t*], [wchar_t*], [attr_t*], : writes the internal state of [cchar_t*], so it reflects the rest of the arguments;
[short*], [void*]) [wchar_t*] is for text; [attr_t*] is for text attributes;
[short*] is for color pair information; [void*] is implementation defined
Window:
— background:
• every window has one
• resebled by a [chtype]
• this [chtype]s will be displayed one very blank position
and its attributes part will be displayed on every non-blank position
newwin([int1], [int2], [int3], [int4]) : returns WINDOW* starting at [int3], [int4] and with [int1] lines and [int2] cols
delwin([WINDOW*]) : deletes [WINDOW*]
box([WINDOW*], [char1], [char2]) : draws the appropriate chars to the outer borders of [win];
wrapper function of wborder([WINDOW*], [char1], [char1], [char2], [char2],
'┌', '┐', '└', '┘')
if 0s are passed in it becomes wborder([WINDOW*], '|', '-', '┌', '┐', '└', '┘')
wborder([WINDOW*], [char1], [char1], : draws the appropriate chars to the outer borders of [win];
[char3], [char4], [char5], [char6], [char1] corresponding to the left line,
[char7], [char8]) [char2] corresponding to the right line,
[char3] corresponding to the top line,
[char4] corresponding to the bottom line,
and [char5]-[char8] corresponding to the corners in a
left to right, top to bottom manner
bkgd([chtype]) : sets stdscrs background to [chtype]
wbkgd([WINDOW*], [chtype]) : sets [WINDOW*]s background to [chtype]
bkgdset([chtype]) : sets stdscrs background to [chtype]; [chtype]s attributes will become
the attributes of any given non-blank char (instead of just being displayed on the same position)
wbkgdset([WINDOW*], [chtype]) : sets [WINDOW*]s background to [chtype]; [chtype]s attributes will become
the attributes of any given non-blank char (instead of just being displayed on the same position)
getyx([WINDOW*], &[int1], &[int2]) : modifies [int1]'s and [int2]'s value to resemble the starting coordinates of [WINDOW*]'s cursor
getbegyx([WINDOW*], &[int1], &[int2]) : modifies [int1]'s and [int2]'s value to resemble the starting coordinates of [WINDOW*]
getmaxyx([WINDOW*], &[int1], &[int2]) : modifies [int1]'s and [int2]'s value to resemble the ending coordinates of [WINDOW*]
Attribute:
• see attribute values AT ../Masks/Attributes
(w)attron([attribute]) : turns ON [attribute] with out affecting other attributes
(w)attroff([attribute]) : turns OFF [attribute] with out affecting other attributes
(w)attrset([attribute]) : turns OFF all attributes then turns ON [attribute]
(w)attr_get() : ?!
init_pair(<int>, [COLOR1], [COLOR2]) : declares a color pair with the id number <int>; [COLOR<int>] is a predefined mask,
see AT ../Masks/Colors; [COLOR1] is the foreground (text) color, [COLOR2] is the background color
Structs:
WINDOW : a window; each cell (row/column) in a WINDOW is stored as a cchar_t (see BELOW)
cchar_t : a special wide char type with extra information
Objects:
stdscr : standard screen; WINDOW*
Masks:
Attributes:
PREFIXES:
W : makes attribute apply to wide chars
WA_* and A_* attributes shall NOT be mixed_up/or-ed
(W)A_NORMAL : Normal display (no highlight)
(W)A_STANDOUT : Best highlighting mode of the terminal.
(W)A_UNDERLINE : Underlining
(W)A_REVERSE : Reverse video
(W)A_BLINK : Blinking
(W)A_DIM : Half bright
(W)A_BOLD : Extra bright or bold
(W)A_PROTECT : Protected mode
(W)A_INVIS : Invisible or blank mode
(W)A_ALTCHARSET : Alternate character set
(W)A_CHARTEXT : Bitmask to extract a character
COLOR_PAIR(<int>) : Color−pair id number <int>; for color-pairs see AT init_pair()
Colors:
COLOR_BLACK
COLOR_RED
COLOR_GREEN
COLOR_YELLOW
COLOR_BLUE
COLOR_MAGENTA
COLOR_CYAN
COLOR_WHITE
Keys:
Name Key name
──────────────────────────────────────────────────────────────
KEY_BREAK Break key
KEY_DOWN The four arrow keys ...
KEY_UP
KEY_LEFT
KEY_RIGHT
KEY_HOME Home key (upward+left arrow)
KEY_BACKSPACE Backspace
KEY_F0 Function keys; space for 64 keys is reserved.
KEY_F(n) For 0 ≤ n ≤ 63
KEY_DL Delete line
KEY_IL Insert line
KEY_DC Delete character
KEY_IC Insert char or enter insert mode
KEY_EIC Exit insert char mode
KEY_CLEAR Clear screen
KEY_EOS Clear to end of screen
KEY_EOL Clear to end of line
KEY_SF Scroll 1 line forward
KEY_SR Scroll 1 line backward (reverse)
KEY_NPAGE Next page
KEY_PPAGE Previous page
KEY_STAB Set tab
KEY_CTAB Clear tab
KEY_CATAB Clear all tabs
KEY_ENTER Enter or send
KEY_SRESET Soft (partial) reset
KEY_RESET Reset or hard reset
KEY_PRINT Print or copy
KEY_LL Home down or bottom (lower left)
KEY_A1 Upper left of keypad
KEY_A3 Upper right of keypad
KEY_B2 Center of keypad
KEY_C1 Lower left of keypad
KEY_C3 Lower right of keypad
KEY_BTAB Back tab key
KEY_BEG Beg(inning) key
KEY_CANCEL Cancel key
KEY_CLOSE Close key
KEY_COMMAND Cmd (command) key
KEY_COPY Copy key
KEY_CREATE Create key
KEY_END End key
KEY_EXIT Exit key
KEY_FIND Find key
KEY_HELP Help key
KEY_MARK Mark key
KEY_MESSAGE Message key
KEY_MOUSE Mouse event read
KEY_MOVE Move key
KEY_NEXT Next object key
KEY_OPEN Open key
KEY_OPTIONS Options key
KEY_PREVIOUS Previous object key
KEY_REDO Redo key
KEY_REFERENCE Ref(erence) key
KEY_REFRESH Refresh key
KEY_REPLACE Replace key
KEY_RESIZE Screen resized
KEY_RESTART Restart key
KEY_RESUME Resume key
KEY_SAVE Save key
KEY_SBEG Shifted beginning key
KEY_SCANCEL Shifted cancel key
KEY_SCOMMAND Shifted command key
KEY_SCOPY Shifted copy key
KEY_SCREATE Shifted create key
KEY_SDC Shifted delete char key
KEY_SDL Shifted delete line key
KEY_SELECT Select key
KEY_SEND Shifted end key
KEY_SEOL Shifted clear line key
KEY_SEXIT Shifted exit key
KEY_SFIND Shifted find key
KEY_SHELP Shifted help key
KEY_SHOME Shifted home key
KEY_SIC Shifted input key
KEY_SLEFT Shifted left arrow key
KEY_SMESSAGE Shifted message key
KEY_SMOVE Shifted move key
KEY_SNEXT Shifted next key
KEY_SOPTIONS Shifted options key
KEY_SPREVIOUS Shifted prev key
KEY_SPRINT Shifted print key
KEY_SREDO Shifted redo key
KEY_SREPLACE Shifted replace key
KEY_SRIGHT Shifted right arrow
KEY_SRSUME Shifted resume key
KEY_SSAVE Shifted save key
KEY_SSUSPEND Shifted suspend key
KEY_SUNDO Shifted undo key
KEY_SUSPEND Suspend key
KEY_UNDO Undo key
Wide_char_aliases:
WACS_BLOCK : solid square block
WACS_BOARD : board of squares
WACS_BTEE : bottom tee
WACS_BULLET : bullet
WACS_CKBOARD : checker board (stipple)
WACS_DARROW : arrow pointing down
WACS_DEGREE : degree symbol
WACS_DIAMOND : diamond
WACS_GEQUAL : greater-than-or-equal-to
WACS_HLINE : horizontal line
WACS_LANTERN : lantern symbol
WACS_LARROW : arrow pointing left
WACS_LEQUAL : less-than-or-equal-to
WACS_LLCORNER : lower left-hand corner
WACS_LRCORNER : lower right-hand corner
WACS_LTEE : left tee
WACS_NEQUAL : not-equal
WACS_PI : Greek pi
WACS_PLMINUS : plus/minus
WACS_PLUS : plus
WACS_RARROW : arrow pointing right
WACS_RTEE : right tee
WACS_S1 : scan line 1
WACS_S3 : scan line 3
WACS_S7 : scan line 7
WACS_S9 : scan line 9
WACS_STERLING : pound-sterling symbol
WACS_TTEE : top tee
WACS_UARROW : arrow pointing up
WACS_ULCORNER : upper left-hand corner
WACS_URCORNER : upper right-hand corner
WACS_VLINE : vertical line
WACS_T_BTEE : thick tee pointing up
WACS_T_HLINE : thick horizontal line
WACS_T_LLCORNER : thick lower left corner
WACS_T_LRCORNER : thick lower right corner
WACS_T_LTEE : thick tee pointing right
WACS_T_PLUS : thick large plus
WACS_T_RTEE : thick tee pointing left
WACS_T_TTEE : thick tee pointing down
WACS_T_ULCORNER : thick upper left corner
WACS_T_URCORNER : thick upper right corner
WACS_T_VLINE : thick vertical line
WACS_D_BTEE : double tee pointing up
WACS_D_HLINE : double horizontal line
WACS_D_LLCORNER : double lower left corner
WACS_D_LRCORNER : double lower right corner
WACS_D_LTEE : double tee pointing right
WACS_D_PLUS : double large plus
WACS_D_RTEE : double tee pointing left
WACS_D_TTEE : double tee pointing down
WACS_D_ULCORNER : double upper left corner
WACS_D_URCORNER : double upper right corner
WACS_D_VLINE : double vertical line
chtype:
• stores a char and attributes
• can be created by or-ing together a char and any number of attributes
{ chtype interest_mark = 'A' }
IN_PRACTICE:
Hello_World:
{
#include <ncurses.h>
int scr_h, scr_w;
char greeting[] = "Hello Ncurses!";
signed main(){
initscr();
noecho();
curs_set(0);
getmaxyx(stdscr, scr_h, scr_w);
WINDOW* myWindow = newwin(3, ( sizeof(greeting)-1 ) + 4,
( scr_h / 2 ) - 1, (scr_w - ( sizeof(greeting)-1) ) / 2);
refresh();
box(myWindow, 0, 0);
mvwaddstr(myWindow, 1, 2, greeting);
wrefresh(myWindow);
while(1){}
endwin();
return 0;
}
}
### Resizing Hello World in NCurses ###
• ncurses is very moody about SIGWINCH, more specifically some terminal emulators will not
update their terminfo correctly if its handled, while in others interrupting getch
causes it to return the error code ERR
• BELOW is NOT the correct way to do it; scroll further for the correct way
{
#include <signal.h>
#include <ncurses.h>
int scr_h, scr_w;
WINDOW* myWindow;
char greeting[] = "Hello Ncurses!";
void display(int sig = 0){
if(sig != 0){
delwin(myWindow);
endwin();
refresh();
clear();
}
getmaxyx(stdscr, scr_h, scr_w);
myWindow = newwin(3, ( sizeof(greeting)-1 ) + 4,
( scr_h / 2 ) - 1, (scr_w - ( sizeof(greeting)-1) ) / 2);
refresh();
box(myWindow, 0, 0);
mvwaddstr(myWindow, 1, 2, greeting);
wrefresh(myWindow);
}
signed main(){
initscr();
noecho();
curs_set(0);
signal(SIGWINCH, display);
display();
while(1){}
endwin();
return 0;
}
}
• the correct way to do it is to handle KEY_RESIZE, which is a special input read by wgetch()
• KEY_RESIZE does not require keypad()
• KEY_RESIZE seems to litter the input buffer, so it is advised to flush it afterwards with flushinp();
• the following IS the intended way to do it; however, its still broken in some terminals
{
#include <signal.h>
#include <ncurses.h>
int scr_h, scr_w;
WINDOW* myWindow = NULL;
char greeting[] = "Hello Ncurses!";
void display(){
if(myWindow){
delwin(myWindow);
endwin();
erase();
refresh();
clear();
}
getmaxyx(stdscr, scr_h, scr_w);
myWindow = newwin(3, ( sizeof(greeting)-1 ) + 4,
( scr_h / 2 ) - 1, (scr_w - ( sizeof(greeting)-1) ) / 2);
refresh();
box(myWindow, 0, 0);
mvwaddstr(myWindow, 1, 2, greeting);
wrefresh(myWindow);
}
signed main(){
initscr();
noecho();
curs_set(0);
display();
while(1){
if(wgetch(stdscr) == KEY_RESIZE){
display();
flushinp();
}
}
endwin();
return 0;
}
}
#
### Using GNU Readline and Ncurses together ###
#include <ncurses.h>
#include <readline/readline.h>
#define WINDOW_WIDTH 32
#define WINDOW_HEIGHT 3
int scr_h, scr_w;
WINDOW * myWindow;
int input_available = false;
char input;
static inline
void init(){
initscr();
noecho();
curs_set(0);
getmaxyx(stdscr, scr_h, scr_w);
myWindow = newwin(WINDOW_HEIGHT, WINDOW_WIDTH,
( scr_h / 2 ) - 1, ( scr_w - WINDOW_WIDTH) / 2);
refresh();
box(myWindow, 0, 0);
rl_bind_key('\t', rl_insert);
rl_catch_signals = 0;
rl_catch_sigwinch = 0;
rl_prep_term_function = NULL;
rl_deprep_term_function = NULL;
rl_change_environment = 0;
rl_getc_function = +[](FILE* ignore){
input_available = false;
return (int)input;
};
rl_input_available_hook = +[]{
return input_available;
};
rl_redisplay_function = +[]{
wmove(myWindow, 1, 1);
wclrtoeol(myWindow);
box(myWindow, 0, 0);
waddstr(myWindow, rl_line_buffer);
wrefresh(myWindow);
return;
};
rl_callback_handler_install("", +[](char *line){
wmove(stdscr, 0, 0);
wclrtoeol(stdscr);
waddstr(stdscr, line);
wrefresh(stdscr);
return;
});
}
signed main(){
init();
wrefresh(myWindow);
while(1){
input = wgetch(myWindow);
input_available = true;
rl_callback_read_char();
}
}
#
### Colors in Ncurses ###
0. For any color operation start_color() must be called:
start_color();
8-bit:
For displaying 8 bit colors, Ncurses requires so called color-pairs.
Color-pairs must be defined/"initialized" before usage and then must be applied as an attribute.
Each color-pair has a unique number (on conflict the newer over writes the old one)
and which is used for addressing.
1. Creating a color-pair:
{
initpair(1, COLOR_MAGENTA, COLOR_GREEN);
}
2. Turning the attibute on:
{
wattron(myWindow, COLOR_PAIR(1));
}
Now anything printed will appear with the colors set.
You can turn the attribute off similar to how you turned it on:
{
wattroff(myWindow, COLOR_PAIR(1))
}
naming the color pair via a define or enum is recommended
#
. ### Wide char support in Ncurses ###
1. Right System Locale:
You have to be using a UTF-8 locale (Mine is en_US.UTF-8;
I imagine others will have different choices).
Type ‘locale’ at a shell prompt to be sure.
2. Right Terminal:
You have to have a term program that can display non-ASCII characters.
Most of them can handle that these days, but there are still a few holdouts.
rxvt-unicode and konsole, popular term programs on Linux, are both good.
3. Right Console Font:
You have to use a console font which contains glyphs
for the non-ASCII characters that you use.
Again, most default console fonts can handle that these days,
but it’s still another gotcha,
and if you routinely pick some random blambot font to use
on the console you’re likely to miss out.
Try typing a non-ASCII character at the console prompt
just to make sure you see it.
If you don’t know how to type non-ASCII characters from the keyboard,
that’s beyond the scope of what’s covered here and you’ll need to go
and read some documentation
and possibly set some keyboard preferences.
Anyway, if you see it, then you’ve got the first, second,
and third things covered.
4. Right Ncurses Package:
You have to have ncurses configured to deal with wide characters.
For most linux distributions, that means:
Your ncurses distribution is based on version 5.4 or later (mine is 5.9),
but NOT on version 11.
I have no idea where version 11 came from,
but it’s definitely a fork based on a pre-5.4 ncurses version,
and hasn’t got the Unicode extensions.
Also, you must have the ‘ncursesw’ versions,
which are configured and compiled for wide characters.
How this works depends on your distribution,
but for Debian, you have to get both the ‘ncursesw’ package
to run ncurses programs that use wide characters
and the ‘ncursesw-dev’ package to compile them.
The current versions are ncursesw5 and ncursesw5-dev.
But there’s an apparent packaging mistake where the wide-character dev package, ncursesw-dev,
does not contain any documentation for the wide-character functions.
If you want the man pages for the wide-character curses functions, you must also install ncurses-dev,
which comes with a “wrong” version of ncurses that doesn’t have the wide-character functions.
Don’t think too much about why anyone would do this; you’ll only break your head.
The short version of the story is that you pretty much have to install ncurses, ncurses-dev, ncursesw, and ncursesw-dev,
all at the same time, and then just be very very careful about not ever using the library versions
that don’t actually have the wide character functions in them.
5. Program Locale:
Your program has to call “setlocale” immediately after it starts up,
before it starts curses or does any I/O.
If it doesn’t call setlocale, your program will remain in the ‘C’ locale,
which assumes that the terminal cannot display any characters outside
the ASCII set.
If you do any input or output, or start curses before calling setlocale,
you will force your runtime to commit to some settings
before it knows the locale,
and then setlocale when you do call it won’t have all of the desired effects.
Your program is likely to print ASCII transliterations
for characters outside the ASCII range if this happens.
{
setlocale(LC_ALL, "");
}
6. Use Specified macro:
You have to #define _XOPEN_SOURCE_EXTENDED in your source
before any library #include statements.
The wide character curses functions are part of a standard called
the XOPEN standard, and preprocessing conditionals check this symbol
to see whether your program expects to use that standard.
If this symbol is found, and you’ve included the right headers (see item Seven)
then macroexpansion will configure the headers you include
to actually contain definitions
for the documented wide-character functions.
But it’s not just the ‘curses’ headers that depend on it;
you will get bugs and linking problems with other libraries
if you have this symbol defined for some includes but not others,
so put it before all include statements.
Unfortunately, the XOPEN_SOURCE_EXTENDED macro is not mentioned
in the man pages of many of the functions that won’t link if you don’t do it.
You’d have to hunt through a bunch of not-very-obviously related ‘see also’ pages
before you find one that mentions it,
and then it might not be clear that it relates to the function
you were interested in.
Trust me, it does. Without this macro, you can use the right headers
and still find that there are no wide-curses definitions in them to link to.
7. Right Ncurses header
You have to include the right header file
rather than the one the documentation tells you to include.
This isn’t a joke.
The man page tells you that you have to include “curses.h”
to get any of the wide-character functions working,
but the header that actually contains
the wide-character function definitions is “ncursesw/curses.h“.
I hope this gets fixed soon,
but it’s been this way for several years
so some idiot may think this isn’t a bug.
8. Linking Ncurses
You have to use the `-lncursesw` compiler option
(as opposed to the -lncurses option)
when you’re linking your executable.
Earlier versions of gcc contained a bug
that `-WError` and `-WAll` would cause linking
to fail on the ncursesw library,
but this appears to have been fixed.
9. Use Wide Char Functions
Use the wide-character versions of everything, not just a few things.
This is harder than it ought to be,
because the library doesn’t issue link warnings warn you
about mixing functionality,
and the documentation doesn’t specifically say which of the things
it recommends won’t work correctly with wide characters.
That means cchar_t rather than chtype,
wide video attributes rather than standard video attributes,
and setcchar rather than OR to combine attributes
with character information.
#
#define SDL\
#define SDL2:::: \
I--------------------------------------------------------------------------\
I ______ ______ _____ _____ \
I .' ____ \ |_ _ `.|_ _| / ___ `. \
I | (___ \_| | | `. \ | | |_/___) | \
I _.____`. | | | | | | _ .'____.' \
I | \____| | _| |_.' /_| |__/ |/ /_____ \
I \______.'|______.'|________||_______| (sdl2) \
I \
I--------------------------------------------------------------------------I
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
• "Simple Directmedia Layer 2"
• as it says its a media layer if anyone tells you to make games in it,
stab them on the spot as they are the literal devil;
SDL can be used to develop high performance engines,
please do not develop high performance engines for your own sake;
try raylib instead
INITIALIZATION: INITIALIZATION:
SDL_Init([flag]) : initializes SDL; must be called to be able to use (most of) SDL
----------------------------------------------------------
| Flag | Initialized subsystem(s) |
----------------------------------------------------------
| SDL_INIT_HAPTIC | Force feedback subsystem |
| SDL_INIT_AUDIO | Audio subsystem |
| SDL_INIT_VIDEO | Video subsystem |
| SDL_INIT_TIMER | Timer subsystem |
| SDL_INIT_JOYSTICK | Joystick subsystem |
| SDL_INIT_EVERYTHING | All subsystems |
| SDL_INIT_NOPARACHUTE | Dont catch fatal signals |
----------------------------------------------------------
• use '|' to initialize more at a time { SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO); }
• SDL2 redirects stdout and stderr to appropriate files; to re-redirect it do:
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
WINDOW_RELATED_STUFF: WINDOW_RELATED_STUFF:
SDL_Window* [name] : equals NULL if window could not be created;
SDL_CreateWindow( [char*], [int-1] [int-2], : title, x cord, y cord
[int width], [int height], [WINDOW FLAG]);
[WINDOW FLAGS]:
SDL_WINDOW_FULLSCREEN
SDL_WINDOW_OPENGL
SDL_WINDOW_SHOWN
SDL_WINDOW_HIDDEN
SDL_WINDOW_BORDERLESS
SDL_WINDOW_RESIZABLE
SDL_WINDOW_MINIMIZED
SDL_WINDOW_MAXIMIZED
SDL_WINDOW_INPUT_GRABBED
SDL_WINDOW_INPUT_FOCUS
SDL_WINDOW_MOUSE_FOCUS
SDL_WINDOW_FULLSCREEN_DESKTOP
SDL_WINDOW_FOREIGN
SDL_WINDOW_ALLOW_HIGHDPI
SDL_WINDOW_MOUSE_CAPTURE
SDL_WINDOW_ALWAYS_ON_TOP
SDL_WINDOW_SKIP_TASKBAR
SDL_WINDOW_UTILITY
SDL_WINDOW_TOOLTIP
SDL_WINDOW_POPUP_MENU
SDL_WINDOW_VULKAN
{
SDL_Window* window = SDL_CreateWindow( "MyWindow", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
1920, 1080, SDL_WINDOW_SHOWN)
}
SDL_SetWindowTitle([SDL_Window], [c-string]) : sets window title;
SDL_RaiseWindow([SDL_Window]) : Use this function to raise a window above other windows and set the input focus;
SDL_DestroyWindow([SDL_Window]) : always should be called;
--------------------
SDL_renderer: SDL_renderer:
--------------------
#include <SDL_renderer.h>
SDL_Renderer* [name];
Functions:
Managing:
SDL_CreateRenderer([SDL_Window instance], [int index (???)], [RENDERER FLAGS]) :returns pointer to renderer
[RENDERER FLAGS]:
SDL_RENDERER_SOFTWARE
SDL_RENDERER_ACCELERATED
SDL_RENDERER_PRESENTVSYNC
SDL_RENDERER_TARGETTEXTURE
{ SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, NULL);}
SDL_RenderCopy([SDL_Renderer* instance], [SDL_Texture* instance], : 1 puts out the texture fullsized; 2 will adjust texture to rect size;
[SDL_Rect reference {1}], [SDL_Rect reference {2}]);
SDL_RenderClear([renderer]); : empties the [renderer]; sets the whole thing to RendererDrawColor;
SDL_RenderPresent([renderer]); : displays [renderer] in the window it belongs to
SDL_DestroyRenderer( [SDL_Renderer instance] ); : always should be called;
Drawing:
• the passed in renderer is always the renderer used for rendering (duh)
SDL_SetRendererDrawColor([SDL_Renderer], [int red], [int green], [int blue], [int alpha channel; ==opicity; usually 255])
int color = [int variable] % 255;
Use this function to set the color used for drawing operations (Rect, Line and Clear).
Returns 0 on success or a negative error code on failure;
SDL_RenderDrawLine([SDL_Renderer*], [int_x1], [int2], [int3], [int4]) : draws single pixel wide line from point [[int1]; [int2]] to point [[int3]; [int4]]
SDL_RenderDrawLines([SDL_Renderer*], [SDL_Point*], <int>) : draws single pixel wide lines connecting the lines in point array [SDL_Point] in accending order; count is the number of ponts from the array to connect
SDL_RenderDrawRect([SDL_Renderer*], [SDL_Rect*]) : draws single pixel wide out line of [SDL_Rect]
SDL_RenderFillRect([SDL_Renderer*], [SDL_Rect*]) : draws [SDL_Rect]
SDL_RenderDrawRects([SDL_Renderer*], [SDL_Rect*], <int>) : draws single pixel wide out line of the first <int> rectangles at array [SDL_Rect*]
SDL_RenderFillRects([SDL_Renderer*], [SDL_Rect*], <int>) : draws the first <int> rectangles at array [SDL_Rect*]
------------------
SDL_Rect.h:
------------------
#include <SDL_rect.h>
Stucts:
SDL_Point [name] : initializes [name] point
Members:
int x
int y
SDL_FPoint [name] : initializes [name] floating-point point
Members:
float x
float y
SDL_Rect [name] : initializes [name] rectangle
Members:
int x : the x coordinate of the lower left corner
int y : the y coordinate of the lower left corner
int w
int h
SDL_FRect [name] : initializes [name] floating-point rectangle
Members:
float x : the x coordinate of the lower left corner
float y : the y coordinate of the lower left corner
float w
float h
Functions:
SDL_PointInRect([SDL_Point], [SDL_Rect]) : returns an SDL_bool indicating whether [SDL_Point] is inside [SDL_Rect]
• the logic is "return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE;",
so the upper and right border are not actually considered part of the rectangle
{"logical table" for a 4x4 rect:
4░░░░
3███░
2███░
1███░
01234
}
SDL_RectEmpty([SDL_Rect]) : returns an SDL_bool indicating whether [SDL_Rect] is smaller or equals to 0x0
SDL_RectEquals([SDL_Rect1], [SDL_Rect2]) : returns an SDL_bool indicating whether all elements of the two rectangles are equal
----------------
SURFACE:
SDL_Surface* [name]
SLD_Surface* SDL_LoadBMP([file (C style string)]); : [file] must be bit map (.bmp)
@ SLD_Surface* IMG_Load([file (C style string)]); : [file] can be almost any image file (.png && .jpg included)
TEXTURE:
SDL_Texture* [name];
SDL_CreateTextureFromSurface([SDL_Renderer* instance], [SDL_Surface* instance]);
SDL_QueryTexture([*texture], NULL, NULL, &[int1], &[int2]); : changes [int1]'s value to [textures]'s width, and [int2]'s value
to [texture]'s hight; meant to be used with a rect's .w and .h
SDL_RenderCopy([renderer], [texture], &[rent1], &[rect2]); : copy [texture] to [renderer]; [rect1] determines how much will be showed of
the texture, think of it as it were placed over the texture, what ever is under
it will be shown; [rect2] determines where it will be displayed,
and how big will it be; passing NULL as [rect1] will make the renderer use
the entire texture; passing NULL as [rect2] will use the entire renderer for display
SDL_RenderCopyEx([...], [...], [...], [...], [rotation], [point], [flip]);
------------------------------------------------------- : the first 4 parameters are the same as ABOVE; int [rotation] rotates the image;
| [flip] value | Purpose | [point] is the center point of the rotation; [flip] is for flipping
|---------------------|-------------------------------|
| SDL_FLIP_NONE | no flipping |
| SDL_FLIP_HORIZONTAL | flip the texture horizontally |
| SDL_FLIP_VERTICAL | flip the texture vertically |
-------------------------------------------------------
EVENT:
SDL_Event event;
types:
SDL_FIRSTEVENT
SDL_QUIT : when the little 'x' is clicked
SDL_PollEvent(&[event]); : pulls event if one is available; changes [event].type
Shared:
SDL_CreateWindowAndRenderer( [int width], [int height], [window flags (see ABOVE)],
[SDL_Window reference], [SDL_Renderer reference]);
Misc:
SDL_Delay( <int> ); : waits/sleep <int> MILLISECONDS(!);
SDL_Quit(); : quites SDL; does not quit the program
### SDL2 Hello World ###
{
#include <SDL.h>
signed main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("HW", 0, 0, 800, 800, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
while (1) { ; }
return 0;
}
}
#
raylib
#define raylib:::: \
I------------------------------------\
I \
I ______ _ _ _ \
I | ___ \ | (_) | \
I | |_/ /__ _ _ _| |_| |__ \
I | // _` | | | | | | '_ \ \
I | |\ \ (_| | |_| | | | |_) | \
I \_| \_\__,_|\__, |_|_|_.__/ \
I __/ | \
I |___/ \
I------------------------------------I
https://www.raylib.com/examples.html
https://github.com/
• easy to use graphical library
• specifically made for indie video game development
• just read the header bro
• i cannot create a better cheatsheet than the offical raylib one;
after 5 years this is the first time; well done raypeople;
instead i will copy paste it and convert it to fit cdd
module: rcore
void InitWindow(int width, int height, const char *title);
void CloseWindow(void);
bool WindowShouldClose(void);
bool IsWindowReady(void);
bool IsWindowFullscreen(void);
bool IsWindowHidden(void);
bool IsWindowMinimized(void);
bool IsWindowMaximized(void);
bool IsWindowFocused(void);
bool IsWindowResized(void);
bool IsWindowState(unsigned int flag);
void SetWindowState(unsigned int flags);
void ClearWindowState(unsigned int flags);
void ToggleFullscreen(void);
void ToggleBorderlessWindowed(void);
void MaximizeWindow(void);
void MinimizeWindow(void);
void RestoreWindow(void);
void SetWindowIcon(Image image);
void SetWindowIcons(Image *images, int count);
void SetWindowTitle(const char *title);
void SetWindowPosition(int x, int y);
void SetWindowMonitor(int monitor);
void SetWindowMinSize(int width, int height);
void SetWindowMaxSize(int width, int height);
void SetWindowSize(int width, int height);
void SetWindowOpacity(float opacity);
void SetWindowFocused(void);
void *GetWindowHandle(void);
int GetScreenWidth(void);
int GetScreenHeight(void);
int GetRenderWidth(void);
int GetRenderHeight(void);
int GetMonitorCount(void);
int GetCurrentMonitor(void);
Vector2 GetMonitorPosition(int monitor);
int GetMonitorWidth(int monitor);
int GetMonitorHeight(int monitor);
int GetMonitorPhysicalWidth(int monitor);
int GetMonitorPhysicalHeight(int monitor);
int GetMonitorRefreshRate(int monitor);
Vector2 GetWindowPosition(void);
Vector2 GetWindowScaleDPI(void);
const char *GetMonitorName(int monitor);
void SetClipboardText(const char *text);
const char *GetClipboardText(void);
void EnableEventWaiting(void);
void DisableEventWaiting(void);
void ShowCursor(void);
void HideCursor(void);
bool IsCursorHidden(void);
void EnableCursor(void);
void DisableCursor(void);
bool IsCursorOnScreen(void);
void ClearBackground(Color color);
void BeginDrawing(void);
void EndDrawing(void);
void BeginMode2D(Camera2D camera);
void EndMode2D(void);
void BeginMode3D(Camera3D camera);
void EndMode3D(void);
void BeginTextureMode(RenderTexture2D target);
void EndTextureMode(void);
void BeginShaderMode(Shader shader);
void EndShaderMode(void);
void BeginBlendMode(int mode);
void EndBlendMode(void);
void BeginScissorMode(int x, int y, int width, int height);
void EndScissorMode(void);
void BeginVrStereoMode(VrStereoConfig config);
void EndVrStereoMode(void);
VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device);
void UnloadVrStereoConfig(VrStereoConfig config);
Shader LoadShader(const char *vsFileName, const char *fsFileName);
Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode);
bool IsShaderReady(Shader shader);
int GetShaderLocation(Shader shader, const char *uniformName);
int GetShaderLocationAttrib(Shader shader, const char *attribName);
void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType);
void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count);
void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat);
void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture);
void UnloadShader(Shader shader);
Ray GetMouseRay(Vector2 mousePosition, Camera camera);
Matrix GetCameraMatrix(Camera camera);
Matrix GetCameraMatrix2D(Camera2D camera);
Vector2 GetWorldToScreen(Vector3 position, Camera camera);
Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera);
Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height);
Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera);
void SetTargetFPS(int fps);
float GetFrameTime(void);
double GetTime(void);
int GetFPS(void);
void SwapScreenBuffer(void);
void PollInputEvents(void);
void WaitTime(double seconds);
void SetRandomSeed(unsigned int seed);
int GetRandomValue(int min, int max);
int *LoadRandomSequence(unsigned int count, int min, int max);
void UnloadRandomSequence(int *sequence);
void TakeScreenshot(const char *fileName);
void SetConfigFlags(unsigned int flags);
void OpenURL(const char *url);
void TraceLog(int logLevel, const char *text, ...);
void SetTraceLogLevel(int logLevel);
void *MemAlloc(unsigned int size);
void *MemRealloc(void *ptr, unsigned int size);
void MemFree(void *ptr);
void SetTraceLogCallback(TraceLogCallback callback);
void SetLoadFileDataCallback(LoadFileDataCallback callback);
void SetSaveFileDataCallback(SaveFileDataCallback callback);
void SetLoadFileTextCallback(LoadFileTextCallback callback);
void SetSaveFileTextCallback(SaveFileTextCallback callback);
unsigned char *LoadFileData(const char *fileName, int *dataSize);
void UnloadFileData(unsigned char *data);
bool SaveFileData(const char *fileName, void *data, int dataSize);
bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName);
char *LoadFileText(const char *fileName);
void UnloadFileText(char *text);
bool SaveFileText(const char *fileName, char *text);
bool FileExists(const char *fileName);
bool DirectoryExists(const char *dirPath);
bool IsFileExtension(const char *fileName, const char *ext);
int GetFileLength(const char *fileName);
const char *GetFileExtension(const char *fileName);
const char *GetFileName(const char *filePath);
const char *GetFileNameWithoutExt(const char *filePath);
const char *GetDirectoryPath(const char *filePath);
const char *GetPrevDirectoryPath(const char *dirPath);
const char *GetWorkingDirectory(void);
const char *GetApplicationDirectory(void);
bool ChangeDirectory(const char *dir);
bool IsPathFile(const char *path);
FilePathList LoadDirectoryFiles(const char *dirPath);
FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs);
void UnloadDirectoryFiles(FilePathList files);
bool IsFileDropped(void);
FilePathList LoadDroppedFiles(void);
void UnloadDroppedFiles(FilePathList files);
long GetFileModTime(const char *fileName);
unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize);
unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize);
char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize);
unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize);
AutomationEventList LoadAutomationEventList(const char *fileName);
void UnloadAutomationEventList(AutomationEventList *list);
bool ExportAutomationEventList(AutomationEventList list, const char *fileName);
void SetAutomationEventList(AutomationEventList *list);
void SetAutomationEventBaseFrame(int frame);
void StartAutomationEventRecording(void);
void StopAutomationEventRecording(void);
void PlayAutomationEvent(AutomationEvent event);
bool IsKeyPressed(int key);
bool IsKeyPressedRepeat(int key);
bool IsKeyDown(int key);
bool IsKeyReleased(int key);
bool IsKeyUp(int key);
int GetKeyPressed(void);
int GetCharPressed(void);
void SetExitKey(int key);
bool IsGamepadAvailable(int gamepad);
const char *GetGamepadName(int gamepad);
bool IsGamepadButtonPressed(int gamepad, int button);
bool IsGamepadButtonDown(int gamepad, int button);
bool IsGamepadButtonReleased(int gamepad, int button);
bool IsGamepadButtonUp(int gamepad, int button);
int GetGamepadButtonPressed(void);
int GetGamepadAxisCount(int gamepad);
float GetGamepadAxisMovement(int gamepad, int axis);
int SetGamepadMappings(const char *mappings);
bool IsMouseButtonPressed(int button);
bool IsMouseButtonDown(int button);
bool IsMouseButtonReleased(int button);
bool IsMouseButtonUp(int button);
int GetMouseX(void);
int GetMouseY(void);
Vector2 GetMousePosition(void);
Vector2 GetMouseDelta(void);
void SetMousePosition(int x, int y);
void SetMouseOffset(int offsetX, int offsetY);
void SetMouseScale(float scaleX, float scaleY);
float GetMouseWheelMove(void);
Vector2 GetMouseWheelMoveV(void);
void SetMouseCursor(int cursor);
int GetTouchX(void);
int GetTouchY(void);
Vector2 GetTouchPosition(int index);
int GetTouchPointId(int index);
int GetTouchPointCount(void);
void SetGesturesEnabled(unsigned int flags);
bool IsGestureDetected(unsigned int gesture);
int GetGestureDetected(void);
float GetGestureHoldDuration(void);
Vector2 GetGestureDragVector(void);
float GetGestureDragAngle(void);
Vector2 GetGesturePinchVector(void);
float GetGesturePinchAngle(void);
void UpdateCamera(Camera *camera, int mode);
void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom);
module: rshapes
void SetShapesTexture(Texture2D texture, Rectangle source);
void DrawPixel(int posX, int posY, Color color);
void DrawPixelV(Vector2 position, Color color);
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color);
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color);
void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color);
void DrawLineStrip(Vector2 *points, int pointCount, Color color);
void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color);
void DrawCircle(int centerX, int centerY, float radius, Color color);
void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color);
void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color);
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2);
void DrawCircleV(Vector2 center, float radius, Color color);
void DrawCircleLines(int centerX, int centerY, float radius, Color color);
void DrawCircleLinesV(Vector2 center, float radius, Color color);
void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color);
void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color);
void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color);
void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color);
void DrawRectangle(int posX, int posY, int width, int height, Color color);
void DrawRectangleV(Vector2 position, Vector2 size, Color color);
void DrawRectangleRec(Rectangle rec, Color color);
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color);
void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);
void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);
void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4);
void DrawRectangleLines(int posX, int posY, int width, int height, Color color);
void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color);
void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color);
void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color);
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color);
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color);
void DrawTriangleFan(Vector2 *points, int pointCount, Color color);
void DrawTriangleStrip(Vector2 *points, int pointCount, Color color);
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color);
void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color);
void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color);
void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color);
void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color);
void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color);
void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color);
void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color);
void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color);
void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color);
void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color);
void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color);
void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color);
Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t);
Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t);
Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t);
Vector2 GetSplinePointBezierQuad(Vector2 p1, Vector2 c2, Vector2 p3, float t);
Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t);
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2);
bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2);
bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec);
bool CheckCollisionPointRec(Vector2 point, Rectangle rec);
bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius);
bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3);
bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount);
bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint);
bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold);
Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
module: rtextures
Image LoadImage(const char *fileName);
Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize);
Image LoadImageSvg(const char *fileNameOrString, int width, int height);
Image LoadImageAnim(const char *fileName, int *frames);
Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize);
Image LoadImageFromTexture(Texture2D texture);
Image LoadImageFromScreen(void);
bool IsImageReady(Image image);
void UnloadImage(Image image);
bool ExportImage(Image image, const char *fileName);
unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize);
bool ExportImageAsCode(Image image, const char *fileName);
Image GenImageColor(int width, int height, Color color);
Image GenImageGradientLinear(int width, int height, int direction, Color start, Color end);
Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer);
Image GenImageGradientSquare(int width, int height, float density, Color inner, Color outer);
Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2);
Image GenImageWhiteNoise(int width, int height, float factor);
Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale);
Image GenImageCellular(int width, int height, int tileSize);
Image GenImageText(int width, int height, const char *text);
Image ImageCopy(Image image);
Image ImageFromImage(Image image, Rectangle rec);
Image ImageText(const char *text, int fontSize, Color color);
Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint);
void ImageFormat(Image *image, int newFormat);
void ImageToPOT(Image *image, Color fill);
void ImageCrop(Image *image, Rectangle crop);
void ImageAlphaCrop(Image *image, float threshold);
void ImageAlphaClear(Image *image, Color color, float threshold);
void ImageAlphaMask(Image *image, Image alphaMask);
void ImageAlphaPremultiply(Image *image);
void ImageBlurGaussian(Image *image, int blurSize);
void ImageResize(Image *image, int newWidth, int newHeight);
void ImageResizeNN(Image *image, int newWidth,int newHeight);
void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill);
void ImageMipmaps(Image *image);
void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp);
void ImageFlipVertical(Image *image);
void ImageFlipHorizontal(Image *image);
void ImageRotate(Image *image, int degrees);
void ImageRotateCW(Image *image);
void ImageRotateCCW(Image *image);
void ImageColorTint(Image *image, Color color);
void ImageColorInvert(Image *image);
void ImageColorGrayscale(Image *image);
void ImageColorContrast(Image *image, float contrast);
void ImageColorBrightness(Image *image, int brightness);
void ImageColorReplace(Image *image, Color color, Color replace);
Color *LoadImageColors(Image image);
Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount);
void UnloadImageColors(Color *colors);
void UnloadImagePalette(Color *colors);
Rectangle GetImageAlphaBorder(Image image, float threshold);
Color GetImageColor(Image image, int x, int y);
void ImageClearBackground(Image *dst, Color color);
void ImageDrawPixel(Image *dst, int posX, int posY, Color color);
void ImageDrawPixelV(Image *dst, Vector2 position, Color color);
void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color);
void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color);
void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color);
void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color);
void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color);
void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color);
void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color);
void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color);
void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color);
void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color);
void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint);
void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color);
void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint);
Texture2D LoadTexture(const char *fileName);
Texture2D LoadTextureFromImage(Image image);
TextureCubemap LoadTextureCubemap(Image image, int layout);
RenderTexture2D LoadRenderTexture(int width, int height);
bool IsTextureReady(Texture2D texture);
void UnloadTexture(Texture2D texture);
bool IsRenderTextureReady(RenderTexture2D target);
void UnloadRenderTexture(RenderTexture2D target);
void UpdateTexture(Texture2D texture, const void *pixels);
void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels);
void GenTextureMipmaps(Texture2D *texture);
void SetTextureFilter(Texture2D texture, int filter);
void SetTextureWrap(Texture2D texture, int wrap);
void DrawTexture(Texture2D texture, int posX, int posY, Color tint);
void DrawTextureV(Texture2D texture, Vector2 position, Color tint);
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint);
void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint);
void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint);
void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint);
Color Fade(Color color, float alpha);
int ColorToInt(Color color);
Vector4 ColorNormalize(Color color);
Color ColorFromNormalized(Vector4 normalized);
Vector3 ColorToHSV(Color color);
Color ColorFromHSV(float hue, float saturation, float value);
Color ColorTint(Color color, Color tint);
Color ColorBrightness(Color color, float factor);
Color ColorContrast(Color color, float contrast);
Color ColorAlpha(Color color, float alpha);
Color ColorAlphaBlend(Color dst, Color src, Color tint);
Color GetColor(unsigned int hexValue);
Color GetPixelColor(void *srcPtr, int format);
void SetPixelColor(void *dstPtr, Color color, int format);
int GetPixelDataSize(int width, int height, int format);
module: rtext
Font GetFontDefault(void);
Font LoadFont(const char *fileName);
Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount);
Font LoadFontFromImage(Image image, Color key, int firstChar);
Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount);
bool IsFontReady(Font font);
GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type);
Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod);
void UnloadFontData(GlyphInfo *glyphs, int glyphCount);
void UnloadFont(Font font);
bool ExportFontAsCode(Font font, const char *fileName);
void DrawFPS(int posX, int posY);
void DrawText(const char *text, int posX, int posY, int fontSize, Color color);
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint);
void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint);
void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint);
void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint);
void SetTextLineSpacing(int spacing);
int MeasureText(const char *text, int fontSize);
Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing);
int GetGlyphIndex(Font font, int codepoint);
GlyphInfo GetGlyphInfo(Font font, int codepoint);
Rectangle GetGlyphAtlasRec(Font font, int codepoint);
char *LoadUTF8(const int *codepoints, int length);
void UnloadUTF8(char *text);
int *LoadCodepoints(const char *text, int *count);
void UnloadCodepoints(int *codepoints);
int GetCodepointCount(const char *text);
int GetCodepoint(const char *text, int *codepointSize);
int GetCodepointNext(const char *text, int *codepointSize);
int GetCodepointPrevious(const char *text, int *codepointSize);
const char *CodepointToUTF8(int codepoint, int *utf8Size);
int TextCopy(char *dst, const char *src);
bool TextIsEqual(const char *text1, const char *text2);
unsigned int TextLength(const char *text);
const char *TextFormat(const char *text, ...);
const char *TextSubtext(const char *text, int position, int length);
char *TextReplace(char *text, const char *replace, const char *by);
char *TextInsert(const char *text, const char *insert, int position);
const char *TextJoin(const char **textList, int count, const char *delimiter);
const char **TextSplit(const char *text, char delimiter, int *count);
void TextAppend(char *text, const char *append, int *position);
int TextFindIndex(const char *text, const char *find);
const char *TextToUpper(const char *text);
const char *TextToLower(const char *text);
const char *TextToPascal(const char *text);
int TextToInteger(const char *text);
module: rmodels
void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color);
void DrawPoint3D(Vector3 position, Color color);
void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color);
void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color);
void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color);
void DrawCube(Vector3 position, float width, float height, float length, Color color);
void DrawCubeV(Vector3 position, Vector3 size, Color color);
void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
void DrawCubeWiresV(Vector3 position, Vector3 size, Color color);
void DrawSphere(Vector3 centerPos, float radius, Color color);
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color);
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color);
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color);
void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color);
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color);
void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color);
void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color);
void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color);
void DrawPlane(Vector3 centerPos, Vector2 size, Color color);
void DrawRay(Ray ray, Color color);
void DrawGrid(int slices, float spacing);
Model LoadModel(const char *fileName);
Model LoadModelFromMesh(Mesh mesh);
bool IsModelReady(Model model);
void UnloadModel(Model model);
BoundingBox GetModelBoundingBox(Model model);
void DrawModel(Model model, Vector3 position, float scale, Color tint);
void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);
void DrawModelWires(Model model, Vector3 position, float scale, Color tint);
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint);
void DrawBoundingBox(BoundingBox box, Color color);
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint);
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint);
void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint);
void UploadMesh(Mesh *mesh, bool dynamic);
void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize, int offset);
void UnloadMesh(Mesh mesh);
void DrawMesh(Mesh mesh, Material material, Matrix transform);
void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances);
bool ExportMesh(Mesh mesh, const char *fileName);
BoundingBox GetMeshBoundingBox(Mesh mesh);
void GenMeshTangents(Mesh *mesh);
Mesh GenMeshPoly(int sides, float radius);
Mesh GenMeshPlane(float width, float length, int resX, int resZ);
Mesh GenMeshCube(float width, float height, float length);
Mesh GenMeshSphere(float radius, int rings, int slices);
Mesh GenMeshHemiSphere(float radius, int rings, int slices);
Mesh GenMeshCylinder(float radius, float height, int slices);
Mesh GenMeshCone(float radius, float height, int slices);
Mesh GenMeshTorus(float radius, float size, int radSeg, int sides);
Mesh GenMeshKnot(float radius, float size, int radSeg, int sides);
Mesh GenMeshHeightmap(Image heightmap, Vector3 size);
Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
Material *LoadMaterials(const char *fileName, int *materialCount);
Material LoadMaterialDefault(void);
bool IsMaterialReady(Material material);
void UnloadMaterial(Material material);
void SetMaterialTexture(Material *material, int mapType, Texture2D texture);
void SetModelMeshMaterial(Model *model, int meshId, int materialId);
ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount);
void UpdateModelAnimation(Model model, ModelAnimation anim, int frame);
void UnloadModelAnimation(ModelAnimation anim);
void UnloadModelAnimations(ModelAnimation *animations, int animCount);
bool IsModelAnimationValid(Model model, ModelAnimation anim);
bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2);
bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2);
bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius);
RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius);
RayCollision GetRayCollisionBox(Ray ray, BoundingBox box);
RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform);
RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3);
RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4);
module: raudio
void InitAudioDevice(void);
void CloseAudioDevice(void);
bool IsAudioDeviceReady(void);
void SetMasterVolume(float volume);
float GetMasterVolume(void);
Wave LoadWave(const char *fileName);
Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize);
bool IsWaveReady(Wave wave);
Sound LoadSound(const char *fileName);
Sound LoadSoundFromWave(Wave wave);
Sound LoadSoundAlias(Sound source);
bool IsSoundReady(Sound sound);
void UpdateSound(Sound sound, const void *data, int sampleCount);
void UnloadWave(Wave wave);
void UnloadSound(Sound sound);
void UnloadSoundAlias(Sound alias);
bool ExportWave(Wave wave, const char *fileName);
bool ExportWaveAsCode(Wave wave, const char *fileName);
void PlaySound(Sound sound);
void StopSound(Sound sound);
void PauseSound(Sound sound);
void ResumeSound(Sound sound);
bool IsSoundPlaying(Sound sound);
void SetSoundVolume(Sound sound, float volume);
void SetSoundPitch(Sound sound, float pitch);
void SetSoundPan(Sound sound, float pan);
Wave WaveCopy(Wave wave);
void WaveCrop(Wave *wave, int initSample, int finalSample);
void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels);
float *LoadWaveSamples(Wave wave);
void UnloadWaveSamples(float *samples);
Music LoadMusicStream(const char *fileName);
Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize);
bool IsMusicReady(Music music);
void UnloadMusicStream(Music music);
void PlayMusicStream(Music music);
bool IsMusicStreamPlaying(Music music);
void UpdateMusicStream(Music music);
void StopMusicStream(Music music);
void PauseMusicStream(Music music);
void ResumeMusicStream(Music music);
void SeekMusicStream(Music music, float position);
void SetMusicVolume(Music music, float volume);
void SetMusicPitch(Music music, float pitch);
void SetMusicPan(Music music, float pan);
float GetMusicTimeLength(Music music);
float GetMusicTimePlayed(Music music);
AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels);
bool IsAudioStreamReady(AudioStream stream);
void UnloadAudioStream(AudioStream stream);
void UpdateAudioStream(AudioStream stream, const void *data, int frameCount);
bool IsAudioStreamProcessed(AudioStream stream);
void PlayAudioStream(AudioStream stream);
void PauseAudioStream(AudioStream stream);
void ResumeAudioStream(AudioStream stream);
bool IsAudioStreamPlaying(AudioStream stream);
void StopAudioStream(AudioStream stream);
void SetAudioStreamVolume(AudioStream stream, float volume);
void SetAudioStreamPitch(AudioStream stream, float pitch);
void SetAudioStreamPan(AudioStream stream, float pan);
void SetAudioStreamBufferSizeDefault(int size);
void SetAudioStreamCallback(AudioStream stream, AudioCallback callback);
void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor);
void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor);
void AttachAudioMixedProcessor(AudioCallback processor);
void DetachAudioMixedProcessor(AudioCallback processor);
struct-s
struct Vector2;
struct Vector3;
struct Vector4;
struct Matrix;
struct Color;
struct Rectangle;
struct Image;
struct Texture;
struct RenderTexture;
struct NPatchInfo;
struct GlyphInfo;
struct Font;
struct Camera3D;
struct Camera2D;
struct Mesh;
struct Shader;
struct MaterialMap;
struct Material;
struct Transform;
struct BoneInfo;
struct Model;
struct ModelAnimation;
struct Ray;
struct RayCollision;
struct BoundingBox;
struct Wave;
struct AudioStream;
struct Sound;
struct Music;
struct VrDeviceInfo;
struct VrStereoConfig;
struct FilePathList;
struct AutomationEvent;
struct AutomationEventList;
colors
#define LIGHTGRAY (Color){ 200, 200, 200, 255 }
#define GRAY (Color){ 130, 130, 130, 255 }
#define DARKGRAY (Color){ 80, 80, 80, 255 }
#define YELLOW (Color){ 253, 249, 0, 255 }
#define GOLD (Color){ 255, 203, 0, 255 }
#define ORANGE (Color){ 255, 161, 0, 255 }
#define PINK (Color){ 255, 109, 194, 255 }
#define RED (Color){ 230, 41, 55, 255 }
#define MAROON (Color){ 190, 33, 55, 255 }
#define GREEN (Color){ 0, 228, 48, 255 }
#define LIME (Color){ 0, 158, 47, 255 }
#define DARKGREEN (Color){ 0, 117, 44, 255 }
#define SKYBLUE (Color){ 102, 191, 255, 255 }
#define BLUE (Color){ 0, 121, 241, 255 }
#define DARKBLUE (Color){ 0, 82, 172, 255 }
#define PURPLE (Color){ 200, 122, 255, 255 }
#define VIOLET (Color){ 135, 60, 190, 255 }
#define DARKPURPLE (Color){ 112, 31, 126, 255 }
#define BEIGE (Color){ 211, 176, 131, 255 }
#define BROWN (Color){ 127, 106, 79, 255 }
#define DARKBROWN (Color){ 76, 63, 47, 255 }
#define WHITE (Color){ 255, 255, 255, 255 }
#define BLACK (Color){ 0, 0, 0, 255 }
#define BLANK (Color){ 0, 0, 0, 0 }
#define MAGENTA (Color){ 255, 0, 255, 255 }
#define RAYWHITE (Color){ 245, 245, 245, 255 }
c_and_cpp_code_generators
#define c_and_cpp_code_generators::: \
I===============================================================================================================\
I===============================================================================================================\
I _____ _______ _____ _ _____ _ \
I / __ \ / / __ \ _ _ / __ \ | | | __ \ | | \
I | / \/ / /| / \/| |_ _| |_ | / \/ ___ __| | ___ | | \/ ___ _ __ ___ _ __ __ _| |_ ___ _ __ ___ \
I | | / / | | |_ _|_ _| | | / _ \ / _` |/ _ \ | | __ / _ \ '_ \ / _ \ '__/ _` | __/ _ \| '__/ __| \
I | \__/\/ / | \__/\|_| |_| | \__/\ (_) | (_| | __/ | |_\ \ __/ | | | __/ | | (_| | || (_) | | \__ \ \
I \____/_/ \____/ \____/\___/ \__,_|\___| \____/\___|_| |_|\___|_| \__,_|\__\___/|_| |___/ \
I===============================================================================================================\
I===============================================================================================================I
flex
#define flex:::: \
#define bison:::: \
I-----------------------------------------------\
I ___ _ _____ _ \
I | __| |_____ __ / / _ |_|___ ___ _ _ \
I | _|| / -_| \ / / /| _ \ (_-</ _ \ ' \ \
I |_| |_\___/_\_\/_/ |___/_/__/\___/_||_| \
I \
I-----------------------------------------------I
Flex & Bison by John Levine
# example project
https://github.com/agvxov/farmsay
• flex is a scanner generator
• bison is a parser generator
• flex+bison together are used to create compilers (or interpreters)
• flex/bison generate C/C++ code, ie. they are meta languages integrating with C/C++
• flex descends from lex and is backwards compatible, hence naming containg 'l'/"lex" a lot
• bison descends from yacc and is backwards compatible, hence naming containg 'y'/"yacc" a lot
• YACC -> "Yet Another Compiler Compiler"
• "LEXical analysis" -> lex-(ing|er)
• historical speculation: bison uses the syntax '<typename>' to define / "compile time cast"
the value of a token/rule; i believe this is where the C++ template syntax originates from
• grammatics
• automaton
Uses:
• flex/bison for compilers
• (potentially) only flex for transpilers { Contra }
• flex for simple data file format parsers { .bash_history }
• bison for validating complex command line arguments ( truely works wonders)
Files:
Extentions:
y : bison source file
l : flex file
*yy.* : flex generated * source file
*tab.* : bison generated * source file
Linking:
• only required with wrapping enabled
— lfl
— ly
Programs:
flex [options] [file]+
— o <path> : output file
--header=<path> : generate header file at <path>;
the documented options is "--header-file",
however you are recommended to use this hidden alternative,
because that is also the option bison uses;
it can be safely assumed that it was added for tool consistency
--prefix=<string> : prefix (some) generated function and variable names with [string];
the default prefix is yy hence the new names will follow the
form of: { --prefix=example -> examplelex(); };
the renaming is done with defines, making trying to mix
lexers from the same compilation unit a footgun
bison [options] [file]+
--header=<path> : generated header file
--name-prefix=<string>
Sections:
• both flex/bison has 3 sections
• sections must be present in the exact same order as list-ed
• sections cannot be broken up
• each seactions is separated by "%%"s
{
%%
%%
}
Definitions:
• directives tend to start with '%'
— C code may be directly embeded:
{
%{
%}
}
Rules:
• the meet of the file
• "match cases" followed by corresponding C/C++ code blocks to execute
Code:
• literal code
• copy pasted
• not wrapped or otherwise modified
FLEX:
• flex can be useful without bison
Theory:
• flex scans as a state-automata
• by default it starts from the builtin state INITIAL and starts reading
from its designated input
• as it reads, it will execute the code corresponding to the longest rule that can be matched
• the code corresponding to a rule is called a action
○ matching
• the rule with the longest matching input is selected
• in case of a input length tie, the rule defined first (above) is selected
• if no rule can be matched the lexer "jams" and stops executing
Regex:
<specifier>[repetition]
specifier:
. : any char except '\n'
\n : new line
^ : start of line
$ : end of line
"<literal>"
[(^)<list>] : braced input list
^ : negates
<list>
<literal>
<literal>-<literal>
[[:alnum:]]
[[:alpha:]]
[[:space:]] : whitespace
[ ] : normal space
<<EOF>> : end of file; pseudo; matches the end of the input,
even if the input is a (non-terminated) buffer
repetition:
{<n>} : exactly <n> number of <specifier>s
+ : 1 or more <specifier>s
* : any number of <specifier>s
? : 0 or 1 <specifier>s
User:
<name> <patter>
• the definition section may contain user defined patterns
— user patterns are accessable like:
{<name>}
{
ws [ \t\r\v\f]
%%
{ws} { puts("matched whitespace"); }
%%
}
Definitions:
%option <option>
noyywrap : do not define a (so called wrapper) main()
yylineno : auto increment yylineno whenever a '\n' is encountered
case-insensitive : [a-z] matches [A-Z] and vice versa
nodefault : do not define default rules { . ECHO }
noyymore : explicitly disable yymore()
reject : explicitly enable REJECT
prefix="<string>" : define interface prefix from the code; same as --prefix=<...> from the cli
%top { ... } : place the code ... near the top of the generated file; before the flex definitions
%x [state]+ : defines [state]+ as "eXclusive" states
%s [state]+ : defines [state]+ as "incluSive" states
States:
• INITIAL is the default starting state, defined by flex
• when the scanner is in an exclusive state only rules from that exact state can match
• when the scanner is in an inclusive state, rules defined without a state specified
can also match
Rules:
<when> <what> : when the state and input conditions of <where> is met, <what> is executed
when:
<<state>(,<state>)+><regex> : explicit state and input
<<state>(,<state>)+>{ <regex> } : imply that all regexes inside the brackets belong to <state>
what:
{ code; }
• regular C code
{
<INITIAL>a { foo(); }
<INITIAL>{
a { foo(); }
}
}
{
<FOO,BAR>{
a { foo(); }
}
}
Functions:
int yylex() : start the lexer on the (previsouly assigned) input;
its a coroutine, uppon return-ing (with a token)
and recalling yylex() flexing will continue from the
next char
void yyless(<signed>) : return all matched input from the <signed>th onwards
{
example { yyless(?) }
|
+----------+----------+----------+----------+----------+----------+
| | | | | | |
yyless(0)---------|----------|----------|----------|----------|----------|--------: example
| yyless(1)---------|----------|----------|----------|----------|--------: xample
| | yyless(2)---------|----------|----------|----------|--------: ample
| | | yyless(3)---------|----------|----------|--------: mple
| | | | yyless(4)---------|----------|--------: ple
| | | | | yyless(5)---------|--------: le
| | | | | | yyless(6)-------: e
| | | | | | |
+-> e +-> x +-> a +-> m +-> p +-> l +-> e
}
void yymore() : append the current token to the next in the value of yytext
void yyrestart(<FILE*>) : throw away buffer, override yyin with <FILE*> and
set up the internal state to start scanning from yyin;
does NOT reset the state (to INITIAL)
YY_BUFFER_STATE yy_scan_string(<const char*>) : set the internal buffer to a new one,
which contains a copy of <const char*>
to be scanned (with the next yylex() call);
the programer has the responsability to
free the return value
YY_BUFFER_STATE yy_scan_bytes(<const char*, int>) : like yy_scan_string, but the input does
not have to be NULL terminated and can
contain NULL
YY_BUFFER_STATE yy_scan_buffer(<char*>, <yy_size_t>) : like yy_scan_bytes(), but the passed buffer
must be terminated with 2 NULL-s, and
the buffer will be modified;
however, there is no extra copy involved;
internally yy_scan_string() and yy_scan_bytes
depend on this function
Variables:
char* yytext : matched text
int yyleng : strlen() of yytext
FILE* yyin : input FILE*
FILE* yyout : output FILE*
int yylineno : current line number of the input; dependent on %yylineno
Macros:
#define BEGIN <state>
• change the scanners state into <state>
• does not jump
• conventionally placed as the first statement in an action
#define REJECT
• continue execution with the next best match to the currently matched token
• DOES jump immediately
• comes with a notable performance penalty
#define ECHO fwrite(yytext, yyleng, 1, yyout)
• print mached string
#define YY_INPUT
• used for override-ing how flex accuries the next char of input
• rarely used
• some variables {i} may already be in use in the position
it is copied to, use with catution
#define YY_USER_ACTION
• run every time a rule is matched, after yytext and yyleng is assigned but
before the corresponding action is executed
Naming:
• state names are SCREAMING_SNAKE
• if state names could collide with token names, an "IN_*" prefix is applied;
consistency is still key
{ block { BEGIN IN_BLOCK; return BLOCK; } }
BISON:
• bison is basically useless without flex; even tho yacc preceeds lex, there are far less
many cases where you would want to hand define yylex (as it was done initially),
than using yylex without a parser
Theory:
• bison parses as a stack-automata
• pushing the stack and changing state is called a shift
• popping the stack and changing state is called a reduction
Definitions:
%token <[union-member]> : defines tokens (those which are expected to be returned by flex)
%union<union-body> : defines the data struct yylval uses for storage
%type <<union-member>> <token>+ : defines the type of <token>+
%start <rule> : override-s the default starting token with <rule>
%left <symbol>+ : declare <symbol>+ left associative with precedence
%right <symbol>+ : decalre <symbol>+ right associative with precedence
%nonassoc <symbol>+ : declare <symbol>+ to be not associative
%code [where] { ... } : inject code source into [where]
provides : somewhere in the generated source and header; for export-ing to the header; default
requires : somewhere in the generated source and header; for playing with source internals; "the best place to define types referenced in ‘%union’"
top : near the absolute top of the generated source
%initial-action { ... } : run arbitrary code at the begining of yyparse()
%parse-param {<arg>}+ : define extra arguments to be passed to yyparse();
mostly used with recursion involved
Types:
• only relevant if you intend to use the (conrate) symbols value
{
%union {
char * strval;
int intval;
}
%token <strval> STRING
%token <intval> NUMBER
%type <strval> expression
}
Symbols:
<left context>: <right context>
A A
| |
rule rules/tokens to
produce from
{
myrule: TOKEN_A
| TOKEN_B
;
}
Tokens:
%token [type] <name>+
• caps by convention
• enum-d
• export-ed into the generated headerfile so the scanner may have access to the symbols
• tokens are numbered from 258 and upwards to mitigate collisions with ascii chars (whats 257?!)
• the token value 0 signals the end of the input;
Empty:
• no symbols specified means the rule matches no symbols returned
• historically an comment was usually added
• the significance of empty space was later deemed confusing,
the special symbol %empty was added for explicit-ly specifying validity
Rules:
• lower case by convention
• the first rule is the start symbol; ie. the root of the parse tree
Values:
$<id> : symbol value
$ : value of the left-hand side
<unsigned> : <unsigned>th symbol of the right-hand side
<cast><neg> : <neg>+1 symbol to the left of $1; from 0 to negative N; must be cast;
no compile time guarantees apply, you must have a solid clue what you
are trying to access and how
{
$$ $1 $2
myrule: TOKEN TOKEN
}
• if there is no action specified then $$ := $1
{
kutya_part: HEAD BODY tail
; │ └─────────────────────────────────────────┐
└─────────────────────────────────┐ │
│ │
tail: TAIL TAIL { printf("%s %s %s %s\n", $<strval>-1, $<strval>0, $1, $2); }
; │ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
}
— symbol values can be named and refered to by name
{
exp[result]: exp[left] '+' exp[right] { $result = $left + $right; }
}
• values are transpiled to index the variable yyvsp;
0 is always the right most token;
this is very useful when debugging
@<id> : location value
Precedence:
%left %right %nonassoc
• symbols in the same directive have the same precedence
• the higher the line number of the directive, the higher the precedence
Error_recovery:
%token error : implicitly defined special token that is pushed unto the stack after
the error recovery state is entered
yyerror() : enter the error recovery state
yyerrok : quit the error recovery state
• in the error recovery state, if another error is encountered before successfully reading
3 tokens, no error token is pushed
• bison does NOT pop the errous token
{
%{
#include <stdlib.h>
#include <stdio.h>
#include "error.tab.h"
int yylex() {
static int i = 0;
const int alpha[] = {B, 0};
return alpha[i++];
}
void yyerror() { ; }
%}
%token A B
%%
i: A
| error { yyerrok; puts("We recovered!"); }
;
%%
signed main() {
yyparse();
return 0;
}
%{
#include <stdlib.h>
#include <stdio.h>
#include "error.tab.h"
int yylex() {
static int i = 0;
const int alpha[] = {B, 0};
return alpha[i++];
}
void yyerror() { ; }
%}
%token A B
%%
i: A
| error B { yyerrok; puts("We recovered!"); }
;
%%
signed main() {
yyparse();
return 0;
}
}
Functions:
yyparse() : start parsing; this will internall invoke yylex()
yyrestart(<FILE*>) : parse file <FILE*>
Variables:
yylval : tokens value buffer; will be copied by bison;
must be assigned from flex to give a value to the token
Macros:
#define ECHO fwrite(yytext, yyleng, 1, yyout)
• print mached string
#define YY_ABORT
• return from yyparse() with a non-zero value
#define YY_ACCEPT
• return from yyparse() with a 0
#define YY_ERROR
• call yyerror() and send the parser into error recovery mode
#define yyerrok
• mark the current error recovered
• cause the parser to exit error recovery mode
Notes:
• flex is a hysteric regarding its header; the only way to add it is by
defining yyIN_HEADER, which is borderline undocumented;
which -being a macro- is extraordinary painful;
not only that, the contents of yyIN_HEADER is not pasted into the source file
and unlike bison it is unable to include its own header without having a stroke;
realistically your best bet is adding a purely handwritten header to the project
### Having a std::string (or any arbitrary type) in Bisons yylval ###
• the key is knowing that %code takes an optional location qualifier
• "requires" will place our definition providing headers high enough,
that they are above the yylval union, unlike standard code blocks
and default %code directives
• no, "top" would not work; how did you know?
• this DOES mean that those includes are going in your bison generated header,
whether you want them or not; if it bothers you, good luck macro-juggling
{
%code requires {
#include <iostream>
#include <string>
void yyerror(...) { ; }
}
%union {
std::string * strval;
}
%{
int yylex() {
yylval.strval = new std::string("There are only two hard problems in CS: cache invalidation, naming things, and off-by-one errors.");
return STRING;
}
%}
%token STRING
%%
string: STRING { std::cout << *(yylval.strval) << std::endl; }
%%
signed main() { yyparse(); }
}
• that a string* must be used because, behold: %union creates an union,
meaning we can only have trivial constructors
#
### Scanning a string with Flex ###
There's the stackoverflow solution,
using a conviniently named and easy to discover function:
{
%option noyywrap
%%
%%
signed main() {
const char * input_str = "This is my input";
YY_BUFFER_STATE const b = yy_scan_string(input_str);
yylex();
yy_delete_buffer(b);
}
}
I find this quite ugly to be honest. The reason it
changes buffers is exactly that: it was designed with changing
buffers in mind. However, often times, you would like your scanner
to only work on (specific) strings, in which case the above code
is almost deceptive about what is going on / what we are intending to do.
Another way to accomplish the same effect would be do redefine YY_INPUT,
like so:
{
%{
const char input_str[] = "This is my input";
const int len = sizeof(input_str)-1;
int offset = len;
#define YY_INPUT(buf, result, max_size) { \
int cpi = (offset && offset > max_size) ? max_size : offset; \
memcpy(buf, input_str+(len-offset), cpi); \
result = cpi; \
offset = (cpi > offset) ? 0 : offset - cpi; \
}
%}
%%
%%
}
Now, is the change more than aesthetic? Well, theres one less heap allocation,
but realistically thats not even worth mentioning. There could be a much
stronger argument for performance if we could somehow dodge copying the input,
similarly to yy_scan_buffer(). Speaking of which, reading its source code reviels
that its magic is relatively trivial and in part assignes "b->yy_ch_buf" to the
buffer argument. Which could allow one to hack it into reality, however
section 11, in the description of yy_create_buffer() of the flex info page
states the following:
"The 'YY_BUFFER_STATE' type is a pointer to an opaque 'struct yy_buffer_state'\
structure."
Meaning, while yy_buffer_state is not opaque (from the perpective of the scanner),
its documented as such, making trying to access its members a gamble.
Those are all the relevant facts, choose your own poison now.
#
### Flex on the edge ###
• non this is technically documented behaviour
• flex places all actions into the same function and does not error out on
ruleless actions before the first rule
{
%x HILL
%%
{ puts("Let me help you, Sisyphus!"); goto hill_top; }
<HILL>. { hill_top: puts("There you go!"); exit(0); }
%%
}
• since the first braced code block managed to slip through the parsing,
it will be always executed
• while the HILL should be unclimable as there are no state transitions to work
your way up, because of the shared function scope, goto just werks™
• this "single function state of affairs" seems to be an implementation detail,
however since return statements must be a valid way to yield values from
yylex() (as documented too), there is hardly any way that this could be changed
#
. ###
%option noyywrap
%%
<INITIAL>\/\*([^*]|\*+[^ ]
*/
%option noyywrap
%x COMMENT
%%
<INITIAL>\/\* { BEGIN COMMENT; }
<COMMENT>{
. { ; }
\*\/ { BEGIN INITIAL; }
}
%%
flex -o pattern.yy.c pattern.l
flex -o state.yy.c state.l
gcc -o pattern.out pattern.yy.c -lfl -g
gcc -o state.out state.yy.c -lfl -g
python -c '''print("/*", "".join([ "a" for i in range(0,1000000)]), "*/")''' | valgrind --tool=massif --massif-out-file=massif.out.pattern ./pattern.out
python -c '''print("/*", "".join([ "a" for i in range(0,1000000)]), "*/")''' | valgrind --tool=massif --massif-out-file=massif.out.state ./state.out
ms_print massif.out.pattern
ms_print massif.out.state
MB
1.005^ #
| ::::::::::::::::::::::::::::::::::::::::::::::::::::#
| : #
| : #
| : #
| : #
| : #
| : #
| : #
| : #
| @@@@@@@@@@@@@@@: #
| @ : #
| @ : #
| @ : #
| @ : #
| :::@ : #
| : @ : #
| : @ : #
|:: @ : #
|:: @ : #
0 +----------------------------------------------------------------------->Gi
0 5.398
KB
21.13^ #
|:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
|: #
0 +----------------------------------------------------------------------->Mi
0 89.89
#
SNIPPETS:
ws [ \t\r\v\f]
wsnl [ \t\r\v\f\n]
identifier [$_a-zA-Z][_a-zA-Z0-9]*
#define ECHOS(s) do { \
const char * const ss = s; \
fwrite(ss, strlen(ss), sizeof(char), yyout); \
} while (0)
#define ECHOC(c) fputc(c, yyout)
re
#define re2c::::
Review of this bullshit software called re2c 3.1:
— the comment thing is kinda smart
• it generates very small scanners so having them inline is not insanity
• you can nest them in your source, without breaking your highlighting or making the lls cry
— it can generate state transition graphs, thats kinda cool
— neither the "free-form" or the "function-like" API seems to work;
theres no error or acknoledgement either
— the first example in the documentation is fucking broken
• it uses undocumented cli flags [like some others]
• they feed a string, but only one character is ever evaluated
— '\00' gives a syntax error for no damn reason
— the switches it generates hurt my eye. why the fuck do they need a label and a goto for each case?,
sure there is string/regex matching which cannot fit inside a case,
however what if only those were to jmp?
— the default rule ['*'] is not properly documented
— for whatever reason fallthough is the default behaviour so you have to spam either
continue or goto
— the default default rule is a fallthrough too;
not a jam, but whatever rule the transpiler decided to insert to the top
[spoiler alert: they are not even in the order of declaration]
— what the literal fuck is this syntax?
`re2c:api:style`
1] you dont need the prefix re2c, its utter bloat
2] namespacing for 20 or so options???
3] my bad, *should be 20 so optoins, instead we have shit like this:
re2c:bit-vectors, re2c:flags:bit-vectors, re2c:flags:b
to do the same fucking thing
and just to stress this, they have namespaces, but you can just not use them.
when? option dependent.
— do we have comments inside re2c blocks? dunno. not documented.
— the cli help is too verbose; useless line breaks makes it hard to grep
— while we are at it, why do we need so many fucking options?
$ re2c --help | grep -e '^\W*-' | sort | uniq | wc -l
77
$ flex --help | grep -e '^\W*-' | sort | uniq | wc -l
46
# and this shit is suppose to be smaller
— -d is useless; YYDEBUG is simply not fit to tracing, since it does not tell you
which lexer it is or the line number
— i get duplicate output. now, it very well might be my fault,
however i have no proper means of debugging and im not
wasting more time on this software
cpp
#define cpp \
I---------------------------------------\
I---------------------------------------\
I \
I /$$$$$$ \
I /$$__ $$ /$$ /$$ \
I | $$ \__/ | $$ | $$ \
I | $$ /$$$$$$$$ /$$$$$$$$ \
I | $$ |__ $$__/|__ $$__/ \
I | $$ $$ | $$ | $$ \
I | $$$$$$/ |__/ |__/ \
I \______/ \
I \
I---------------------------------------\
I---------------------------------------I
Literals:
Strings:
— Raw:
R"[delimeter]([...])[delimeter]"
• escape sequences are not processed inside of it
○ prefixes
u8 : unicode
L : wchar_t
u : char16_t
U : char32_t
PREPROCESSOR:
#define __cplusplus : macro defined if the current source file is being processed as C++
CASTING: CASTING:
Dynamic_cast:
dynamic_cast<[class]>([object ptr]) : returns pointer to [object ptr] converted to [class]
• can only be used with pointers and references to classes
• can upcast and down cast
• done at runtime
• returns NULL pointer on fail
• downcast fails if [class1] is not a valid complete object of [class2]
Static_cast:
static_cast<[class]>([object ptr]) : returns pointer to [object ptr]s target converted to [class]
• can be used between pointers to related classes
• can both upcast and down cast
• done at compiletime
Reinterpret_cast:
reinterpret_cast<<typename>>([variable(/obj) ptr]) : returns pointer to bitwise reinterpretation of [variable ptr]s target to [type]
• can converts any pointer type to any other pointer type
• guaranteed ability to convert back
• no safety nets, not recommended
Constant_cast:
const_cast<([const]) [type]>([variable(/obj) ptr]) : returns pointer to [variable(/obj) ptr]s target with specified constantness
• used when a function argument's constantness doesnt match what you want to pass in
• can be used to change constant values; be aware that's undefined behaviour and compilers usually replace mentions of a constant with its
value in compile time
• casting with the same constantness with which it already is, is valid, does jackshit tho (duh)
• see upcasting and downcasting AT "Data groups/Data_classes/Inheritance"
"C\/C++/Conversions"
POINTERS:
Smart_Pointers:
— auto_ptr
— unique_ptr
— shared_ptr
— weak_ptr
"/C++/std/<memory>"
REFERENCES: REFERENCES:
• holds only the memory address of a variable
• behaves very similar to pointers; however no dereferencing is ever needed
• cannot hold NULL, therefor it can be safely assumed that it always holds
a valid memory address
(const) <typename>&(&) [name] : declares a reference
• the const makes it read-only, ie. unreassignable (yes, that goes against the
logic of a read only pointer, but hey, atleast we got wholeness)
• without the extra ampersand its an Lvalue reference,
with it included its an Rvalue reference
see L- and Rvalues AT "/C++/Value types"
Lvalue_refrences:
• cannot be reassigned as it technically doesnt even exist
• its an alias
• can only be assigned to Lvalues, unless its declared constant { const int& a = 10; }
• marked with "&"
Rvalue_refrences:
• can be reassigned
• can only be assigned to Rvalues
• marked with "&&"
Universal_refrences:
• can bind to Lvalue or Rvalue references
• when a deduced type is marked with "&&" its an universal reference
• on initialization its determined whether the resulting variable
is gonna be an L- or Rvalue reference
• most common as parameters to template functions
Refrence_collapsing:
• tho expressions that would result in reference-to-reference are illegal,
it could come up when deducing types
• for that reason, in such a cases the compiler wont throw an error,
but rather decide whether the resulting type shall be an L- or Rvalue reference
• an Rvalue reference to an Rvalue reference becomes an Rvalue reference,
the other 3 combinations yield Lvalue references
OPERATORS:
<=> : spaceship operator; (?!); (c++20)
LOOPS: LOOPS:
Foreach:
for (<var> : <iteratable>) { <...> }
• "range based for loop"
• exactly what is commonly referred to as a for-each loop (in other languages)
• <var> will always take up the value of the upcoming member of <iterateable>
• <iterateable> must be an iterateable object
• arrays and all std containers are iteratable;
you can define your own itertable class-es
DATA_GROUPS_AND_OBJECTS: DATA_GROUPS_AND_OBJECTS:
• redesigned to feel like (or have the ability to feel like) base C types
and support OOP
— C++ supports the following groups:
union - C union with small additions
struct - C struct with member function support
class - class in the OOP sense
• classes and structs can have static members
Static:
static <typename> <name>;
• the variable is entirely independent of the data group, only its visibility is affected
— if not const a definition will be needed outside of the class:
// @BAKE g++ -o $*.out $@
struct A {
static int s; // not const; declared, but not defined!
};
signed main(void) {
// we have to reference it,
// or the compiler pretends our
// variable doesnt exist at all
return A::s;
}
// Out: <LINKER ERROR>
// However, if we add the following line, it works correctly:
int A::s = 0;
• the existence of any instances is not required for the variable to be usable
• you can refer to a static member as usual ([instance].[member]) or by:
<class>::<member>
Member_Functions:
Const:
<function head> const <function body>
• signals the compiler that this function doesnt modify any members
• makes all members behave like const-s inside the function
— const objects can call const member functions:
// ### Source 1 ###
struct A {
int i = 0;
int return_inc() {
return i + 1;
}
};
signed main(){
const A a;
a.return_inc();
}
g++ output
error: passing ‘const A’ as ‘this’ argument discards qualifiers [-fpermissive]
a.return_inc();
// NOTE: now even tho we don't attempt to modify any member variables
// the compiler has no clue whether that's true or not
### Source 2 ###
struct A {
int i = 0;
int return_inc() const { // <-- added const keyword
return i + 1;
}
};
signed main(){
const A a;
a.return_inc();
}
the ABOVE compiles and runs without a problem
Static:
• independent of the instance,
therefor cannot access non static members and cannot use the "this" keyword
• used for logically packing what is essentially a free-function with a group
Special:
• all groups can contain special functions
Constructor:
[group] [name]{ [name](){} }; : declares constructor
[name]() = delete : forbids the default constructor to ever be called
• runs whenever an object is created
Destructor:
[group] ~[name]{ [name](){} }; : declares constructor
• runs whenever an object is deleted
Operators:
[return type] operator[op]([args]) { [...] } : overloads operator [op]
-------------------------------------------------------------------
| Overloadable operators |
-------------------------------------------------------------------
| + - * / = < > += -= *= /= << >> |
| <<= >>= == != <= >= ++ -- % & ^ ! | |
| ~ &= ^= |= && || %= [] () , ->* -> new |
| delete new[] delete[] |
-------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
| Expression | Operator | Member function | Non-member function |
------------------------------------------------------------------------------------------------------------
| [op]a | + - * & ! ~ ++ -- | A::operator[op]() | operator[op](A) |
| a[op] | ++ -- | A::operator[op](int) | operator[op](A,int) |
| a[op]b | + - * / % ^ & | < > == != <= >= << >> && || , | A::operator[op](B) | operator[op](A,B) |
| a[op]b | = += -= *= /= %= ^= &= |= <<= >>= [] | A::operator[op](B) | N/A |
| a(b,c...) | () | A::operator()(B,C...) | N/A |
| a->b | -> | A::operator->() | N/A |
| (TYPE) a | TYPE | A::operator TYPE() | N/A |
------------------------------------------------------------------------------------------------------------
Access:
<access-specifier>: [...] : marks [...] with <access-specifier>;
valid until the next specifier marker
or the end of the group
○ access specifiers:
public : accessible from anywhere where
the object is visible
private : accessible only by other members
of the same class (or by their "friends")
protected : accessible as ABOVE and by their children
○ friendship
friend [func prototype] : mark [func] as a friend; use INSIDE a class
friend class [name] : mark [name] class as a friend; use INSIDE a class
• friend functions and classes can access private/protected members of a group
• friendship is not mutual
• friendship is not inherited
○ this
• the "this" keyword is a pointer to the current object
• mostly unnecessary to explicitly write dont,
however some consider it good practice to always do so
struct A{
int x;
A(int x) {
this->x = x;
}
};
Bitfields:
• can only exist inside data groups
○ declaration:
<typename> [name] : <int>;
• similar to bool vectors/bitsets
• behaviour is very compiler dependent
• with g++ casting a bitfield with a value in the first halve of its max value gives the exact value, no surprises;
however casting a bitfiled with a value in the second halve of its max value will result in:
([casted types max value] - ([bitfileds max value] - [bitfields current value]))
{ char a : 4; a = 8 [...] (unsigned int)a -> 4294967288}
Data_stuctures:
[s_name] [name](([args])) : creates object of [s_name] struct named [name]
[([args])] is only needed if the constructor require arguments
• all members are public unless specified otherwise
Data_classes:
class [s_name]{ [...] } [name]; : declares class; notice the ';'; [name] creates objects
[...] can contain variables and functions;
[s_name] [name](([args])] : creates object of [s_name] class named [name];
[([args])] is only needed if the constructor require arguments
• all members are private unless specified otherwise
Iheritance:
class [name]: [access] [class](, [...]){ [...] };
• with inheritance a class can have direct access to members of other classes
• [class] is the name of a class that [name] shall inherit from
[access]:
• overload meaning
• affects the access type of the inherited members in the derived class
— the different keywords will result in the following;
(most dominant access specifier being [access] used;
left-hand-side being the access type of the member in the base class;
right-hand-side being the access type of the member in the derived class)
public:
public -> public
protected -> protected
(private !! not inherited)
protected:
public -> protected
protected -> protected
(private !! not inherited)
private:
public -> private
protected -> private
(private !! not inherited)
Upcast:
• converting from pointer-to-derived to pointer-to-base
• safe and common
• accomplished by offsetting on an assembly level;
resulting in the upcast being technically equal to
the ("original") instance, but they are considered equal
{
class A { int a_ };
class B : public A { int b_ };
signed main(void) {
B * b = new A();
A * a = b;
if (a == b) {
std::cout << "Equal.";
}
}
}
Downcast:
• convert from pointer-to-base to pointer-to-derived
• not best practice, probably indicates design flaws
Virtual_member_functions_and_Overwriting:
• to override a function in a child,
the function should be marked "virtual" in the parent
• non-virtual members can also be redefined in derived classes,
but non-virtual members of derived classes cannot be
accessed through a reference of the base class
• in the child it should be marked with "override",
so that the compiler can throw an error
when no such function exist in the parent
class A {
virtual int ret_int() { return 0; }
};
class B : public A {
int ret_int() override { return 1; }
};
— pure virtual function:
• must be overriden to be called
• used when every derived class will have one, but none will use the default
• initialized as a variable assigned to 0
virtual draw() = 0;
Multiple_inheritnce:
• inheriting from multiple classes is perfectly valid
— however when a class inherits from two classes that inherit
from the same class the following situation will arise:
class Top { public: int t; };
class Left : public Top { public: int l; };
class Right : public Top { public: int r; };
class Bottom : public Left, public Right { public: int b; };
/*
* Top Top
* | |
* | |
* Left Right
* \ /
* \ /
* V
* Bottom
*/
// now, our Bottom has two Tops therefor:
Bottom b;
b.t = 10;
// is ambiguous and will not compile.
// to access the "grandparents" members, :: must be used
Bottom b;
b::Left.t = 10;
— if the above shape is not desirable, virtual inheritence can be used:
class Top { public: int t; };
class Left : virtual public Top { public: int l; };
class Right : virtual public Top { public: int r; };
class Bottom : public Left, public Right { public: int b; };
/*
* Top
* A
* / \
* / \
* Left Right
* \ /
* \ /
* V
* Bottom
*/
// this pseudo shape is accomplished with a virtual offset table
// it adds overhead
// now, Top's default constructor will get invoked,
// unless the compiler is explicitly told otherwise
FUNCTIONS:
([[ [attribute] ]]) ([specifier]) [return typename] [name]([[arg][, [...]]]) [exception specifier] { [...] } : declares function
constexpr int return_one() noexcept {
return 1;
}
[[ noreturn ]] void quit(){
deinit();
exit(0);
}
[attribute]:
• see more on attributes AT "?!"
[[ noreturn ]] : specifies that the function shall
not return under any circumstances;
not enforced, returning from a noreturn
function is undefined behaviour
[[ nodiscard ]] : specifies that the return value shall be saved (ie. assigned);
in case it is not the compiler will warn the user
[specifier]:
constexpr : states to the compiler that this function will return a constant,
causing the compiler to resolve it at compile time and
replace all mentions with a constant value;
its body can only hold a single return statement ("using"s are allowed)
[exception specifier]:
http://www.gotw.ca/publications/mill22.htm
"The compiler just guarantees to beat them senseless if they [throw]...\
oh, and to beat your program senseless too, most of the time."
• not just optional, but also deprecated (obviously, backward compatibility
will be available until the heat death of the universe)
• probably a bad idea to use it
• runtime enforced
throw([exception]) : specifies what exceptions the functions can throw;
if it throws something else regardless,
that exception cannot be caught
noexcept : specifies that this function shall not trow anything;
alias for "throw()"; see ABOVE;
this keyword has another use (see AT "../Misc keywords")
Overloading:
• declares the same [name], but different arguments to a function so its(/they are) more flexible to call
• see more AT "../Templates"
LAMBDAS: LAMBDAS:
• produces function behaviour inside a single expression
[[c]] () [ms] ([es]())( -> [type]) { [body] } : declares lambda
[[c]] : Capture clause
= : captures everything in current scope by value
& : captures everything in current scope by reference
=[variable] : captures [variable] by value
&[variable] : captures [variable] by reference
this : captures current object
• one or more may be specified, separated with a ','
[ms] : Mutable specification
[es] : Exception specification
— > [type] : Trailing-return-type
FUNCTORS: FUNCTORS:
• "function object"
• an object that behaves as a function
• they have their operator() override-n
• as they are objects, they can have inner states
• as they are objects, they can be easily passed into other functions
• viable for creating co-routines
• modern alternative to C functions with static variables
(which have an inherent problem with thread-safety,
strtok(3) is a good example)
TEMPLATES: TEMPLATES:
• "glorified macros"
• the typename and class keywords are interchangeable
in the context of template declarations declarations
• templates can also have defaulted parameters;
these are signalled by using a concrete type instead of class or typename;
template arguments with default parameters are optional to pass
// @BAKE g++ -o $* $@
#include <iostream>
template<typename T = int>
class MyClass {
T i = 0;
public:
void print() {
std::cout << i << std::endl;
}
};
signed main(void) {
MyClass a;
MyClass<double> b;
}
Variables:
# template var definition
VARIABLE-TEMPLATE := template < TYPENAME > NAME ( = VALUE);
• NAME<TYPENAME> behaves as a completely independent variable
• template specialization is impossible
• initializing one with a constructor is impossible,
as it makes the compiler think its a function template or
an undefined function prototype (depending on how you try)
• the closest you can get is the part that's visible
on the right-hand-side of the declaration and enclosed in parentheses,
but do to the lack of possible parameters it can only
be initialized with a const value;
resulting in compiler errors if a version that cannot be assigned
to that const value is attempted to be referred to (obviously)
• works fine with datagroups as long as an operator= is defined
• feels more like a bug than a feature to be honest
template<class T> T var;
var<int> = 10;
var<float> = 2.65;
var<bool> = true;
cout << var<int> << endl; // Out: 10
cout << var<float> << endl; // Out: 2.65
cout << var<bool> << endl; // Out: 1
Function:
# template function definition
FUNCTION-TEMPLATE := template < PARAMETERS > NAME FUNCTION
PARAMETERS := PARAMETER (, PARAMETER)*
PARAMETER := typename NAME
NAME := "name of the template parameter"
FUNCTION := "regular function definition,\
but the given NAME-s can be used to refer to types"
• forward declare it normally, by cutting off the body
• NAME must be used inside the scope of FUNCTION or type deduction fails
• declare variables inside FUNCTION as type NAME to make them have whatever type passed in
• templated functions called without "<[type]>" will use the type the compiler determines;
it is generally not recommended (the exceptions would be <algorithm> and tuples)
Variadic_template_functions:
template<typename [name1](, [...]), typename ... [name2]>
[type] [name3]([name1] [name4](, [...]), [name2] ... [name5]) { [...] [func](args ...) }
• if a template function can take an arbitrary number of arguments its called a variadic template function
• such an effect is accomplished by recursion ([func] symbolizes this function)
Classes:
# template class definition
CLASS-TEMPLATE := template < PARAMETERS > CLASS
PARAMETERS := PARAMETER (, PARAMETER)*
PARAMETER := typename NAME
NAME := "name of the template parameter"
CLASS := "regular class definition,\
but the given NAME-s can be used to refer to types"
# template class usage
CLASS-TEMPLATE-INTACE := TEMPLATE-CLASS-NAME < PARAMETERS > NAME CONSTRUCTOR-CALL
• a class template is like a regular class, but with some members having a generic type
• the textbook usage is for containers {a list holding an arbitrary type}
specialization:
• a parameter is changed to a concrete type
• creates a specialized implementation of the template
for a specific parameter (combination)
• essentially an overload for templates
VALUE_TYPES: VALUE_TYPES:
• the (original) naming comes from assignment operations
Lvalue:
• "Left side VALUE"
• a value that has a defined location in memory
○ includes:
[type] [name]
[type]* [name]
[type]& [name]
[type]&& [name]
[Lvalue].[name]
Rvalue:
• "Right side VALUE"
• not an Lvalue
PRvalue:
○ includes:
[literal value]
Xvalue:
• "eXpiring VALUE"
○ includes:
[operation]
[function]()
&[Rvalue]
[Rvalue].[name]
static_cast<[type]>([name])
Offical_graph_for_visualization:
Lvalue Xvalue Prvalue
x x x
x x x x
x x x x
x x x x
x x x x
x x x x
x x x x
x x x x
x x
Gvalue Rvalue
Gvalue:
• Generalised value
• a context where an Lvalue and an Xvalue behaves the same
TYPE_DEDUCTION:
• happens on template parameters and when using auto
• in most cases the deduced type is the same as the passed one
EXCEPTION_HANDLING: EXCEPTION_HANDLING:
throw <data>
try{ [...1] }catch(<typename> <name>){ [...2] }
• classical exception pattern
• when throw is invoked from within a try block, the corresponding catch block is executed
• no finally block (like in other languages)
• any datatype can be thrown
• the catch could specify "..." to catch everything
// @BAKE g++ -o $*.out $@
#include <iostream>
signed main(void) {
try {
throw 1;
std::cout << "try" << std::endl;
} catch (...) {
std::cout << "catch" << std::endl;
}
}
NAMESPACES: NAMESPACES:
• a way to categorize
namespace [name] { [...] } : defines namespace
[name]::[member] : accesses namespace element
using namespace [name] : introduces namespace to the current scope
namespace <name-1> = <name-2> : creates an alias for <name-1> called <name-2>
MOVE_SCHEMANTICS:
Rule_of_3:
○ subject at hand
• destructors ( ~T() )
• copy-constructors ( T(const T& other) )
• copy-assignments ( T& operator=(const T& other) )
• these are always defined by the compiler if no implementation is provided
• when managing heap memory all 3 should be defined explicitly (or delete/hidden)
• not doing so is very bug prone
Rule_of_5:
○ subjects at hand
• destructors ( ~T() )
• copy-constructors ( T(const T& other) )
• copy-assignments ( T& operator=(const T& other) )
• move-constructors ( T(T&& other) noexcept )
• move-assignments ( T& operator=(T&& other) noexcept )
• extension of rule of 3
• missing move-* is a missed oppurtunity to optimize
Rule_of_0:
• just use smart pointers and everything will work out fine
MISC_KEYWORDS: MISC_KEYWORDS:
new [typename(<int>)] : returns a pointer to <typename> constructed on the heap;
use <int> to create array;
every new should have a corresponding delete
delete <pointer> : call the destructor of <pointer>
delete[] <array> : call the destructor of every element of <array>;
new[] requires a corresponding delete[]
enum : enumerate
enum {[alias1], [...]}; : assigns increasing value ints (0 based) to [alias]es; these numbers are constant;
every mention of an alias will get replaces compile time
enum [name] {[alias1], [...]}; : same as ABOVE, but an object of [name] can only be assigned to [alias]es;
(you can static_cast into [name] tho)
enum class [name] {[alias1], [...]}; : same as ABOVE, but aliases are now only accessible by the "namespace" of [name] ([name]::[alias1]) and
[aliases] must be casted to be used as other types
nullptr : null pointer; ≈NULL
decltype([value]) : expands to typename of [value] { decltype(myInt) mySecondInt; }
noexcept([expression]) : returns true if [expression] is declared to not trow (see AT "C++/Functions/Exception specifiers")
explicit ([constructor] || : forbids the compiler to make implicit conversation
[conversion operator]) { class a{
int i;
public:
(explicit) a(int i_) : i(i_){}
};
void func(a your_a){
std::cout << your_a;
}
[...]
func(42);
}
(left for describing:
alignas; alignof; atomic_cancel; atomic_commit (TM TS); atomic_noexcept; concept; volatile; mutable;
reflexpr;
static_assert; synchronized; thread_local; typeid; typename;
)
cpp_stl
#define cpp_stl
c
#define c++_stl::: \
I=========================================================\
I=========================================================\
I _____ _____ _____ _ \
I / __ \ _ _ / ___|_ _| | \
I | / \/| |_ _| |_ \ `--. | | | | \
I | | |_ _|_ _| `--. \ | | | | \
I | \__/\|_| |_| /\__/ / | | | |____ \
I \____/ \____/ \_/ \_____/ (C++ Standard Library || C++ std)\
I=========================================================\
I========================================================I
Left:{
numeric; regex; stdexcept; system_error; typeindex; typeinfo; type_traits;
}
=====================================================
C LIBRARIES
=====================================================
• every C library is available as in C
• every C library is also available with a 'c' prefix and no extension;
this places them in the std namespace
• some C libraries have slightly changed affects
#include <cassert>
#include <ccomplex>
• includes <complex>
#include <cctype>
#include <cerrno>
#include <cfenv>
#include <cfloat>
#include <cinttypes>
#include <ciso646>
• C++ added all macro operator aliases as keywords,
meaning this header is affectless when imported
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstdbool>
• standard in C++, making the header only contain a macro, always expanding to 1:
__bool_true_false_are_defined
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctgmath>
• includes <cmath> and <complex>
#include <ctime>
#include <cuchar>
#include <cwchar>
#include <cwtype>
cpp_io_libs
#define cpp_io_libs:::
=====================================================
I/O LIBRARIES
=====================================================
Hierarchy_of_the_Cpp_input_and_output_libraries:
+---------------+ +---------------+ +------------+ +---------------+ +-------------------+
| <ios> | | <ostream> | | <iostream> | | <fstream> | | <sstream> |
+---------------+ +---------------+ +------------+ +---------------+ +-------------------+
| | | | | | | | | |
| ------------ | | ----------- | | -------- | | ------------ | | ----------------- |
| | ios_base | | #=========>| ostream |=========#=======>| cout | | #============>| ifstream | | #============>| istringstream | |
| ------------ | ‖ | ----------- | ‖ | -------- | ‖ | ------------ | ‖ | ----------------- |
| ‖ | ‖ | ‖ | ‖ | | ‖ | | ‖ | |
| V | ‖ +------‖--------+ ‖ | -------- | ‖ | ----------- | ‖ | ---------------- |
| ------- | ‖ #=========# #=======>| cerr | | ‖ #=========>| fstream | | ‖ #=========>| stringstream | |
| | ios |==============# ‖ ‖ | -------- | ‖ ‖ | ----------- | ‖ ‖ | ---------------- |
| ------- | ‖ ‖ ‖ | | ‖ ‖ | | ‖ ‖ | |
| | ‖ ‖ +---------------+ ‖ | -------- | ‖ ‖ | ------------ | ‖ ‖ | ----------------- |
+---------------+ ‖ ‖ | <istream> | #=======>| clog | | ‖ ‖ #======>| ofstream | | ‖ ‖ #======>| ostringstream | |
‖ ‖ +---------------| ‖ | -------- | ‖ ‖ ‖ | ------------ | ‖ ‖ ‖ | ----------------- |
‖ ‖ | | ‖ | | ‖ ‖ ‖ | | ‖ ‖ ‖ | |
‖ ‖ | ----------- | ‖ | ------- | ‖ ‖ ‖ | ----------- | ‖ ‖ ‖ | ----------------- |
#=========>| istream |=============#===>| cin | | ‖ ‖ ‖ #===>| filebuf | | ‖ ‖ ‖ #===>| istringstream | |
‖ | ----------- | ‖ ‖ | ------- | ‖ ‖ ‖ ‖ | ----------- | ‖ ‖ ‖ ‖ | ----------------- |
‖ | ‖ | ‖ ‖ | | ‖ ‖ ‖ ‖ | | ‖ ‖ ‖ ‖ | |
‖ | V | ‖ ‖ +------------+ ‖ ‖ ‖ ‖ +---------------+ ‖ ‖ ‖ ‖ +-------------------+
‖ | ------------ | ‖ #==================#==‖==‖==‖=====================# ‖ ‖ ‖
#===>| iostream |==================================#==‖==‖========================# ‖ ‖
| ------------ | #============================#==‖===========================# ‖
| | ‖ ‖
+---------------+ ‖ ‖
‖ ‖
‖ ‖
‖ ‖
+---------------+ ‖ ‖
| <streambuf> | ‖ ‖
+---------------+ ‖ ‖
| | ‖ ‖
| ------------- | ‖ ‖
| | streambuf |=======================================#==============================#
| ------------- |
| |
+---------------+
####################################################################################################################################################
-----------
ios: ios:
-----------
#include <ios>
Classes:
ios_base:
• base class for the entire standard c++ i/o library
• has no public constructors; ie. no objects can be declared
Private member variables:
• fmtflags variable
• floating-point precision field variable
• field width variable
• extensible, general purpose long array
Member_classes:
Init [name] : declares Init object named [name]
Private member variables:
init_cnt || _S_refcount : static int; instance count; name is implementation dependent
_S_synced_with_stdio : static bool; whether C and C++ default streams are synchronized
• the constructor adds one to init_cnt
• if init_cnt is changed from 0, the standard iostream objects get initialized
• the destructor subtracts one from init_cnt
• if init_cnts value falls back to 0 again, the standard iostream objects are flushed (not deleted)
failure:
• inherits from system_error (see AT <system_error>)
Member_typedefs:
event_callback : void(*)([event], [ios_base&], <int>)
fmtflags : bitmask type; see UNDER "Masks:/fmtflag flags"; BELOW
iostate : bitmask type; see UNDER "Masks:/iostate flags"; BELOW
openmode : bitmask type; see UNDER "Masks:/openmode flags"; BELOW
Member_functions:
flags() : returns private fmtflags variable
flags([fmtflags]) : sets private fmtflags variable to [fmtflags] and returns the old one
setf([fmtflags]) : ors the private fmtflags variable [with] [fmtflags]
setf([fmtflags1], [fmtflags2]) : ors the private fmtflags variable [with] [fmtflags1] and ands the result with not[fmtflags2]
unsetf([fmtflags]) : clears the bits of private fmtflags variable corresponding to true bits in [fmtflags]
precision() : returns private floating-point precision field variable
precision([streamsize]) : sets private floating-point precision field variable to [streamsize] and returns the old one
width() : returns private field width variable
width([streamsize]) : sets private field width field variable to [streamsize] and returns the old one
imbue([locale]) : sets [locale] to be used
getloc() : returns current locale used
xalloc() : returns unique value to be used as an argument for iword() or pword()
iword(<int>) : returns a long& to the <int>th element from the private, extensible, general purpose long array
pword(<int>) : returns a void*& to the <int>th element from the private, extensible, general purpose long array
register_callback( : sets up [event_callback] to be called whenever [event] occurs with passing in <int> as an argument;
[event_callback], <int>) if multiple functions are set they will execute in FILO (First In Last Out) order
sync_with_stdio([bool] = true) : sets whether the default streams of C and C++ are synchronized;
(ie. whether you can use them interchangeably (not as in {stdout.flags}))
Enums:
event:
• used with ios_base::register_callback() (see ABOVE)
copy_fmt_event : on a ios::copyfmt() call; between the format flag and exception mask copy
erase_event : on a stream destruction
imbue_event : on a ios_base::imbue() call; before the return
seekdir:
beg : beginning of sequence
cur : current position within sequence
end : end of sequence
Masks:
+---------------+------------------------------------------------------------------------------+
| fmtflag flags | effect |
+---------------+------------------------------------------------------------------------------+
| boolalpha | read/write alphabetic bools ("true" and "false") |
| showbase | write numeric base prefixes |
| showpoint | write decimal points to floating points under all circumstances |
| showpos | always write sign |
| skipws | skip leading whitespaces |
| unitbuf | flush output after every insertion operation |
| uppercase | use uppercase letters in certain output operations |
| dec | read/write in decimal base |
| oct | read/write in octal base |
| hex | read/write in hexadecimal base |
| fixed | write floating points like ints |
| scientific | write floating points in scientific notation |
| internal | pad to reach $[field width] with [fill] chars at a specific internal point ?!|
| left | pad to reach $[field width] with [fill] chars at the end |
| right | pad to reach $[field width] with [fill] chars at the beginning |
| adjust field | left or right or internal |
| basefield | dec or oct or hex |
| floatfield | scientific or fixed |
+---------------+------------------------------------------------------------------------------+
+---------------+---------------------------------------------+
| iostate flags | meaning |
+---------------+---------------------------------------------+
| eofbit | whether end of file is reached |
| failbit | whether the last operation has failed |
| badbit | whether stream buffer i/o error encountered |
| goodbit | whether all other bits are false |
+---------------+---------------------------------------------+
+---------------+------------------------------------------------------------+
| openmode flag | effect |
+---------------+------------------------------------------------------------+
| in | file opened for reading; (always set for ifstream) |
| out | file opened for writing; (always set for ofstream) |
| binary | operations are performed in binary mode rather than text |
| ate | AT End; the output position starts at the end of the file |
| app | append instead of overwriting |
| trunc | truncate; overwrite the file (default) |
+---------------+------------------------------------------------------------+
Class_templates:
basic_ios<[char_type], [char_traits] = char_traits<charT>>
Inherits from:
• ios_base
Member typesdefs:
char_type : alias of template parameter [char_type]
traits_type : alias of template parameter [char_traits]
int_type : traits_type::int_type
pos_type : traits_type::pos_type
off_type : traits_type::off_type
Protected member functions:
init([basic_streambuf<[char_type, traits_type]>*]) : ?!
Member_functions:
Functions:
Typedefs:
streamoff : signed integer type
streamsize : signed integer type
streampos : integer type
Enums:
----------------
iostream: iostream:
----------------
#include <iostream>
cout : print out pretty much everything you give it (c out);
cin :
• beolvas
• (c in)
~az első space-ig megy
— cin.getline([char variable], [array size])
• only works with char-s
— getline(std::cin, [variable])
• ha {
string text
int number;
cin >> number;
getline(std::cin, text)
}
szerencsétlen nem olvassa be text-et. skipeli.
------------
megoldás {
string text
int number;
cin >> number;
cin.ignore()
getline(std::cin, text)
}
endl : print end line; = "\n"
fixed : print all numbers as floats
scientific : print all numbets as scientific numbers
hexfloat : print all numbers as hexadecimal
defaultfloat : restore print state to normal
---------------
fstream: fstream:
---------------
#include <fstream>
• it keeps the data in a buffer
• "extracting" chars from this buffer they will get removed
• when working with files, always check for errors!
ifstream:
class ifstream : istream : ios : ios_base
Member_functions:
open([file]) : associates [obj] with [file]; if the stream is already associated with a file, this fails
open([file], [openmode]) : same as above, but with changed [openmode]; (see BELOW)
is_open() : returns whether [obj] has a file opened
eof() : returns whether you have reached the End Of File
swap([ifstream]) : swaps associated files with [ifstream]
close() : should always be called
get([char*]) : extracts char into [char*]
get([char[]], <int>) : extracts <int>-1 chars into [char[]]; IT OVERFLOWS!
get([char[]], <int>, [char]): extracts <int>-1 chars or until delimiter [char] is reached into [char[]]; IT OVERFLOWS!
getline([char[]], <int>) : extracts <int>-1 chars or until \n is reached into [char[]]; IT OVERFLOWS!
ignore(<int>) : extracts <int> chars and discards them
peek() : returns the next character in the input sequence, without extracting it
read([char[]], <int>) : extracts <int> chars, stores them in [char[]]
readsome([char[]], <int>) : mostly same as above; i do not understand the difference
putback([char]) : inserts [char] to the start of the buffer
gcount() : returns the number of chars inputted from the last of the following functions called:
get; getline; ignore; peek; read; readsome; putback and unget;
ofstream:
class ofstream : ostream : ios : ios_base
public member functions:
open([file]) : associates [obj] with [file]; if the stream is already associated with a file, this fails
open([file], [openmode]) : same as above, but with changed [openmode]; (see AT <ios>/Classes/ios_base/Masks/openmode)
is_open() : returns whether [obj] has a file opened
swap([ofstream]) : swaps associated files with [ofstream]
close() : should always be called
-----------------
streambuf: streambuf:
-----------------
#include <streambuf>
Class_templates:
template class basic_streambuf<[char_type], [traits] = char_traits<[char_type]>>
• the "internal stream position indicator" stands for the current element operated on; i call it that cause it
lines up with the logic of naming of C FILE-s
Member_typedefs:
char_type : alias of template parameter [char_type]
traits_type : alias of template parameter [char_traits]
int_type : traits_type::int_type
pos_type : traits_type::pos_type
off_type : traits_type::off_type
Member_functions:
pubimbue([locale]) : calls protected virtual member function imbue()
getloc() : returns current [locale] set
pubsetbuf([char_type*], [streamsize]) : calls protected virtual member function setbuf() with the same arguments as passed in
pubseekoff([off_type], [ios_base::seekdir], : calls protected virtual member function seekoff() with the same arguments as passed in
[ios_base::openmode] =
ios_base::in | ios_base::out)
pubseekpos([pos_type], [ios_base::openmode],: calls protected virtual member function seekpos() with the same arguments as passed in
[ios_base::openmode] =
ios_base::in | ios_base::out)
pubsync() : calls protected virtual member function sync()
in_avil() : returns the number of chars left available to read
snextc() : advances the internal stream position indicator by one and returns the char pointed by it
sbumpc() : returns the char pointed by the internal stream position indicator and advances it by one
sgetc() : returns the char pointed by the internal stream position indicator
sgetn([char_type*], [streamsize]) : calls protected virtual member function xsgetn() with the same arguments as passed in
sputbackc([char_type]) : moves the internal stream position indicator back one and returns the char there
if it [char_type], calls pbackfail() otherwise
sungetc([char_type]) : moves the internal stream position indicator back one and returns the char there
sputc([char_type]) : stores char at the location pointed by the internal stream position
indicator and its advanced by one
sputn([char_type*], [streamsize]) : calls protected virtual member function xsputn()
swap([basic_streambuf]) : exchanges states with [basic_streambuf]
Protected member functions:
eback() : returns a char_type* to the first element to the internal buffer array
gptr() : returns a char_type* to the first element to the internal stream position indicator
egptr() : returns gptr() + 1
gbump(<int>) : advances the internal stream position indicator
setg([char_type1*], [char_type2*], : sets eback to [char_type1*], gptr to [char_type2*] and egptr to [char_type3*]
[char_type3*])
imbue([locale]) : sets [locale] to be used
setbuf([char_type*], [streamsize]) : does nothing
pubseekoff([off_type], [ios_base::seekdir], : does nothing
[ios_base::openmode] =
ios_base::in | ios_base::out)
pubseekpos([pos_type], [ios_base::openmode],: does nothing
[ios_base::openmode] =
ios_base::in | ios_base::out)
sync() : does nothing
showmanyc() : returns 0
xsgetn([char_type*], [streamsize]) : returns and copies [streamsize] chars from the internal stream position
indicator to [char_type*]
xsputn([char_type*], [streamsize]) : strores [streamsize] chars from [char_type*] at the location pointed
by the internal stream indicator
pbackfail([int_type]) : ?!
underflow() : ?!
uflow() : ?!
Typedefs:
streambuf : basic_streambuf<char>
wstreambuf : basic_streambuf<wchar_t>
cpp_containers
#define cpp_containers\
#define cpp_container_libs
==================================================
CONTAINERS
==================================================
-----------------
Iterators: Iterators:
-----------------
#include <iterator>
• an iterator is an object that points to an element of a container
• cannot go out of range
template class [container_type]<<typename>>::iterator
Functions:
advance([it], <int>) : advances the [it] by <int> element positions; <int> can be negative
next([it]) : returns iterator equal to advance([it], 1), but [it] stays unchanged
prev([it]) : returns iterator equal to advance([it], -1), but [it] stays unchanged
distance([it1], [it2]) : returns the number of elements between [it1] and [it2]; if [it1] and [it2] are unrelated the function never returns
Operators:
*[it] : access value of what [it] is pointing to . . . . . .\ . \. . . . . . \
++[it] : pre-increase [it] \ \ \
[it]++ : post-increase [it] } all \ \
[it1] == [it2] : returns whether [it1] and [it2] point to the same element / } bidirection allowed | random access
[it1] != [it2] : returns whether [it1] and [it2] dont point to the same element./ / | allowed
--[it] : pre-decrease [it] / /
[it]-- : post-decrease [it] . . . . . . . . . . . . / /
[it] [ARTIMETRIC OPERATION] <int> : operate on [it] . . . . . . . . . . . . . . . . . . . /
------------------------
initializer_list: initializer_list:
------------------------
#include <initializer_list>
Classes:
initializer_list : initializer list; silently created when ever initializer list is used
• copying an initializer_list object produces another object referring to the same underlying elements, not to new copies of them
Member_functions:
size() : returns length of initializer list
begin() : returns iterator to the first element
end() : returns iterator to past-the-end element
-------------
array: array:
-------------
#include <array>
template class array<<typename>, <int>>
• NOT C arrays, instead a class called "array"
• fixed size
• elements accessible with corresponding index
Member_functions:
begin() : returns iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
front() : returns reference to first element
back() : returns reference to last element
at(int i) : returns reference to element <int>
data() : returns pointer to first element
fill([val]) : sets all elements to [val]
size() : returns size; unsigned
empty() : returns whether empty
swap([array]) : exchanges the values of this array with [array]; [array] must be have the same <typename> and size as this array
x[] : access element
----------------
valarray: valarray:
----------------
#include <valarray>
template class valarray<<typename>>
• implements a compound design pattern
• operations on the container apply to each element
Constructors:
default
(<size_t-capacity>)
(<int-val>, <int-repeat>)
(<init-array>, <size_t-n>)
Member_functions:
size_t size()
typename min()
typename max()
typename sum()
this apply(<func>)
valarray<typename> cshift() : left "Circular SHIFTed" copy
operator-s : the operation is applied to each element
--------------
bitset: bitset:
--------------
#include <bitset>
template class bitset<[size]>
• a bool array of whichs elements are not separated by padding
• saves plenty of memory
• using it over other data types can shorten algorithm computation time
• fixed size
Constructor:
defult : all bit are initialized as 0s
(<int>) : bitmap will have the same binary representation as <int>
(<string>) : initializes bitmap with <string> containing 0s and 1s;
the last char from left to right will represent [bitset object][0] (and vice versa)
Member_functions:
count() : returns the number of ones in the bitset
size() : returns container size/length
test(<int>) : returns whether the bit at position <int> is set to 1
any() : returns whether any of the bits is set to 1
none() : returns whether none of the bits are to 1
all() : returns whether all of the bits are set to 1
set() : sets all bits to 1
set(<int>, [bool]) : sets the bit at position <int> to [bool]
reset() : sets all bits to 0
flip() : sets all 1 bits to 0 and all 0 bits to 1
flip(<int>) : sets the bit at <int> to 1 if its 0 or to 0 if its 1
reset(<int>) : sets the bit at position <int> to 0
to_string() : returns string representing bitset; no, it doesnt convert to chars {01101010110};
the last char from left to right will represent [bitset object][0] (and vice versa)
to_ulong() : returns unsigned long with the same binary representation as the bitset
to_ullong() : returns unsigned long long with the same binary representation as the bitset
operator[<value>] : access element with <value> directly with the [] operator
--------------
string: string:
--------------
#include <string>
Classes:
class string [name]
• elements (chars) accessible with corresponding index
• way safer than C-strings
Member_functions:
length() || size() : hány charból áll
append(<string>) : hozzá ad szöveget
insert(<int>, <string>) : inserts <string> at <int>; DOEST OVERWRITE SHIT, YOU MORON!
erase([hanyadik hely utánra], [hány char-t]) : kivon szöveget
popback() : removes last the char of the string
replace([honnan kezdve], [hányat], "[mivel]") : replaces (duh)
size_t find(<string>) : returns position of first occurrence of <string>
or string::npos; {pl.: asd.replace(asd.find("fuck"), 4, "****")}
size_t find(<string>, <int>) : returns position of first occurrence of <string>
or string::npos, starting from position <int>
rfind(<string>) : returns position of last occurrence of <string> or string::npos
rfind(<string>, <int>) : returns position of last occurrence of <string> or string::npos, starting from position <int>
substr([int-1] = 0, : substring; returns a string constructed from *this partal text;
[int-2] = string::npos) [int-1] is the starting position; [int-2] is the amount of chars to take
find_firts_of("[mit]") : megtalálja az első CHAR-t 'mit'-ből; returns position
compare("[mivel]") : össze hasonlítja őket (hogy egyenlőek-e);
c_str() : returns a pointer to a C-string representing the current value
Struct_templates:
template class char_traits<[char_type]>
Specializations:
<>char_traits<char>
<>char_traits<wchar_t>
<>char_traits<char16_t>
<>char_traits<char32_t>
Member_typesdefs:
char_type : alias of template parameter [char_type]
int_type : integer type that can represent [char_type] and eof()
off_type : a type that behaves like streamoff (see AT "<ios>/Typedefs")
pos_type : a type that behaves like streampos (see AT "<ios>/Typedefs")
state_type : multibyte transformation type such as mbstate_t (see At "<wchar.h>/Structs")
Member_functions:
• "char_type" marks the template parameter supplied
• "int_type" marks the member typedef
eq([char_type1], [char_type2]) : returns whether the two arguments are equal
eq_int_type([int_type1], [int_type2]) : returns whether the two arguments are considered equal
lt([char_type1], [char_type2]) : not eq() (see ABOVE)
length([char_type*]) : returns length of null terminated string at [char_type*]
assign([char_type1], [char_type]) : assigns [char2] to [char1] ([char1] = [char2])
assign([char_type*], [size_t], [char_type]) : assigns [char_type] to the first [size_t] chars of string pointed by [char_type*]
move([char_type1*], [char_type2*], [size_t]) : copies [size_t] char_types from [char_type2*] to [char_type1*]
copy([char_type1*], [char_type2*], [size_t]) : same as ABOVE
eof() : returns an int_type representing an end of file value
not_eof([int_type]) : retutns [int_type] if its not an end of file value, otherwise returns an
implementation dependent value
comapre([char_type1*], [char_type2*], [size_t]) : compares the first [size_t] two string parameters; returns:
0 : all chars are equal
<0 : from the first chars that do not equal [char_type1*]s has a SMALLER value
• 0 : from the first chars that do not equal [char_type1*]s has a LARGER value
find([char_type*], [size_t], [char_type]) : returns a char_type* to the first occurrence of [char_type] in the first [size_t] chars
of [char_type*] or null
to_char_type([int_type]) : returns the char_type equivalent of [int_type]
to_int_type([char_type]) : returns the int_type equivalent of [char_type]
Class_templates:
template class basic_string<[type], [char_traits] = char_traits<[type]>, [allocator] = allocator<[type]>>
• [type] is the underlying type of the characters; could be any base type
Specializations:
<>basic_string<char>
<>basic_string<wchar_t>
<>basic_string<char16_t>
<>basic_string<char32_t>
Member_types:
traits_type : alias of template parameter [char_traits]
allocator_type : alias of template parameter [allocator]
value_type : trairs_type::char_type
reference : value_type&
const_refrence : const value_type&
pointer : ?!
Functions:
stoi(<string>) : converts string to int
stol(<string>) : converts string to long
stoul(<string>) : converts string to unsigned long
stoll(<string>) : converts string to long long
stoull(<string>) : converts string to unsigned long long
stod(<string>) : converts string to double
stof(<string>) : converts string to float
to_string([num]) : converts [num] to string
to_wstring([num]) : converts [num] to wide string
getline([ifstream], <string>);
---------------
vectors: vectors:
---------------
#include <vector>
template class vector<<typename>> [name] : declares vector
• elements accessible with corresponding index
• fast appending and removing elements at the end
• slow insertion in the middle or at the beginning
Member_functions:
begin() : returns iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
front() : returns reference to first element
back() : returns reference to last element
insert([it], [value]) : inserts [value] at [it]
push_back([val]) : adds an element to the end
pop_back() : delete last element
emplace([it], [args]) : inserts an element at [it] which is constructed in place, passing [args] to its constructor
emplace_back([args]) : adds an element to the end which is constructed in place, passing [args] to its constructor
size() : returns size; unsigned
empty() : returns whether empty
erase([it]) : removes element at [it] from vector
erase([it1], [itt2]) : removes every element from [it1] till [it2]
clear() : removes all elements from vector
operator[] : access element
Multidimensional vectors || vector of vectors:
vector<vector<typename>> [name];
x. : x-el foglalkozik
x[unsigned int]. : x valamelyik elementjével foglalkozik
x[unsigned int][unsigned int] : x valamelyik elemének elemével foglalkozik
create a temporary vector to push back into the outer vector!
{ vector<vector<char> >example;
for (int i = 0; i < rows; i++) {
vector<char> temp;
for (int j = 0; j < cols; j++) {
temp.push_back('a');
}
example.push_back(temp);
}
}
-------------
queue: queue:
-------------
#include <queue>
template class queue<<typename>, [container] = deque>
• First In First Out (FIFO) container
• [container] is the underlining container type to be used;
it shall have atleast the following member functions:
• empty()
• size()
• front()
• back()
• push_back()
• pop_front()
from the STL deque and list support them
Member_functions:
front() : returns reference to first element
back() : returns reference to last element
template class priority_queue<typename, [container] = deque, [ordering] = less>
• the first element is always the greatest, judged by [ordering]
Member_functions:
top() : returns reference to first element
Shared_functions:
empty() : returns whether empty
size() : returns size; unsigned
push(<typename>) : places <typename> to the end of the queue, making it the new last element
emplace([args]) : constructs <typename> with [args] and places to the end of the queue, making it the new last element
pop() : removes the first (front) element
swap([queue]) : swaps contents with [queue]
-------------
deque: deque:
-------------
#include <deque>
template class deque<<typename>>
• "Double Ended QUEue"
• "deck"
• elements accessible with corresponding index
• fast inserting of elements at the end and beginning
• slow insertion at the middle
• not guaranteed to store all its elements in contiguous storage locations:
accessing elements in a deque by offsetting a pointer to another element causes undefined behavior
Member_functions:
begin() : returns iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
front() : returns reference to first element
back() : returns reference to last element
insert([it], [value]) : inserts [value] at [it]
push_back([val]) : adds element to the end
push_front([val]) : adds element to the beginning
pop_back() : removes last element
pop_front() : removes first element
emplace([it], [args]) : inserts an element at [it] which is constructed in place, passing [args] to its constructor
emplace_back([agrs]) : adds element to the end which is constructed in place, passing [args] to its constructor
emplace_front([agrs]) : adds element to the beginning which is constructed in place, passing [args] to its constructor
size() : returns size; unsigned
empty() : returns whether empty
erase([it]) : removes [it] element from deque
erase([it1], [itt2]) : removes every element from [it1] till [it2]
clear() : removes all elements from deque
operator[] : access element
------------
list: list:
------------
#include <list>
template class list<<typename>>
"/Data structures/Linked lists/?!"
• no element indexes
Member_functions:
reverse() : reverse the order of elements
begin() : returns iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
front() : returns reference to first element
back() : returns reference to last element
insert([it], [value]) : inserts [value] at [it]
slice([it], [list]) : transfer all elements from [list] into this list at [it]
slice([it], [list], [it2]) : transfer element [it2] from [list] into this list at [it]
slice([it], [list], [it2], [it3]) : transfer elements [it2]-[it3] from list into this list at [it]
push_back([val]) : adds element to the end
push_front([val]) : adds element to beginning
pop_back() : removes last element
pop_front() : removes first element
emplace([it], [args]) : inserts an element at [it] which is constructed in place, passing [args] to its constructor
emplace_back([agrs]) : adds element to the end which is constructed in place, passing [args] to its constructor
emplace_front([agrs]) : adds element to the beginning which is constructed in place, passing [args] to its constructor
size() : returns size; unsigned
empty() : returns whether empty
erase([it]) : removes [it] element from deque
erase([it1], [itt2]) : removes every element from [it1] till [it2]
remove([val]) : removes all elements which equal [val]
clear() : removes all elements from list
swap([list]) : exchanges the values of this set with [list]
--------------------
forward_list: forward_list:
--------------------
#include <forward_list>
forward_list<<typename>> [name] : declares forward list
"/Data structures/Linked lists/Forward linked"
• no element indexes
• no size()
• no pushback()
Member_functions:
reverse() : reverse the order of elements
begin() : returns iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
front() : returns reference to first element
insert_after([it], [val]) : inserts [val] after [it]
push_front([val]) : inserts element at beginning
pop_front() : removes first element
emplace_front([agrs]) : adds element to the beginning which is constructed in place, passing [args] to its constructor
emplace_after([[it], [args]]) : inserts an element after [it] which is constructed in place, passing [args] to its constructor
empty() : returns whether empty
erase_after([it]) : removes the element AFTER [it]
erase_after([it], [it2]) : removes elements from [it]+1 till [it2]
clear() : removes all elements from list
------------
sets: sets:
------------
#include <set>
• values of the elements in a set cannot be modified
• no element indexes
SETS:
set<<typename>> [name] : declares set
• cannot hold duplicates
Member_functions:
• SHARED FUNCTIONS (see BELOW)
find([val]) : returns iterator to element equal to [val]; if not found returns end()
count([val]) : returns the number of elements equal to [val]; since set elements are unique, can only return 0 || 1
erase([val]) : removes element with [val]
MULTISETS:
multiset<<typename>> [name] : initializes multiset
• can hold duplicets
Member_functions:
• SHARED FUNCTIONS (see BELOW)
find() : returns iterator to first element equal to [val]; if not found returns end()
count([val]) : returns the number of elements equal to [val]
erase([val]) : removes an element with [val]
Shared_functions:
begin() : returns iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
size() : returns size; unsigned
empty() : returns whether empty
insert([value]) : inserts [value]
erase([it]) : removes element at [it]
erase([it], [it2]) : removes elements from [it] to [it2]
emplace([args]) : inserts an element which is constructed in place, passing [args] to its constructor
clear() : removes all elements from set
swap(<set>) : exchanges the values of this set with <set>
----------------------
unordered_sets: unordered_sets:
----------------------
#include <unordered_set>
• faster to access elements by their value then ordered sets, also constant
• uses hash tables to store data
• makes no guarantees on which specific element is considered which, but the range that goes from its begin to its end covers all the elements
• guarantees that deleting elements does not cause a rehashing
• values of the elements in a set cannot be modified
UNORDERED_SET:
template class unordered_set<[dataset]>
• cannot hold duplicates
Member_functions:
find([val]) : returns iterator to element equal to [val]; if not found returns end()
count([val]) : returns the number of elements equal to [val]; since set elements are unique, can only return 0 || 1
erase([val]) : removes element with [val]
UNORDERED_MULTISET:
template class unordered_multiset<[dataset]>
• can hold duplicates
Member_functions:
find() : returns iterator to first element equal to [val]; if not found returns end()
count([val]) : returns the number of elements equal to [val]
erase([val]) : removes all elements with [val]
Shared_functions:
begin() : returns iterator to "first" element
end() : returns iterator to past-the-"end" element
cbegin() : returns const_iterator to "first" element
cend() : returns const_iterator to past-the-"end" element
size() : returns size; unsigned
empty() : returns whether empty
insert([value]) : inserts [value]
insert([it1], [it2]) : inserts range
erase([it]) : removes element at [it]
erase([it], [it2]) : removes elements from [it] to [it2]
erase([val]) : removes element with [val]
emplace([args]) : inserts an element which is constructed in place, passing [args] to its constructor
clear() : removes all elements from set
swap([unordered_set]) : exchanges the values of this set with [unordered_set]
------------
Pair: Pair:
------------
#include <utility>
template struct pair<[type1], [type2]>
(or { auto mypair = make_pair(10, 10); })
• a struct to pair together two values of different kinds
• a pair has 2 variables, named "first" && "second";
they are also called Key and Value
Assigning:
pair [name]([value1], [value2])
( or { mypair.first = 10; mypair.second = 10; })
Member_functions:
swap(<pair>) : exchanges the values of this pair and <pair>
Functions:
make_pair([value1], [value2]) : returns a pair
-----------
map: map:
-----------
#include <map>
• implemented as binary trees
MAPS:
template class map<[type1], [type2]>
• cannot hold duplicates
• elements accessible with corresponding index
• a "list" of pairs
• accessing an element will insert it
Member_functions:
• SHARED FUNCTIONS
erase([val]) : removes element with key equal to [val]
find([key]) : returns iterator to [key] element; returns .end() if not found
insert(<pair>) : inserts <pair>; returns a pair, containing an iterator to the pair inserted (or the one with an identical key)
and a bool value set to true if a new element was inserted and false if it already existed
cound([key]) : returns the number of elements with keys equal to [key]; since map elements are unique, can only return 0 || 1
swap([map]) : exchange the values of this map with [map]
MULTIMAPS:
multimap<[type1], [type2]> [name] : declares multimap
• can hold duplicets
• elements accessible with corresponding index
• a "list" of pairs
Member_functions:
• SHARED FUNCTIONS
erase([val]) : removes all elements with key equal to [val]
find() : returns iterator to first element equal to [val]; if not found returns end()
insert(<pair>) : inserts <pair>; returns an iterator to the newly inserted element
count([key]) : returns the number of elements with keys equal to [key]
swap([multimap]) : exchange the values of this multimap with [multimap]
Shared_functions:
begin() : return iterator to first element
end() : returns iterator to past-the-end element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
insert([it], <pair>) : inserts <pair> at [it]
erase([it]) : removes element at [it]
erase([it], [it2]) : removes all elements from [it] till [it2]
empty() : returns true if empty, false otherwise
size() : returns container size/length
clear() : clear contents
----------------------
unordered_maps: unordered_maps:
----------------------
#include <unordered_map>
• uses hash tables to store data
• guarantees that deleting elements does not cause a rehashing
• members are faster to access by their key, then in (regular) maps
• a "list" of pairs
• faster to access elements by their key value then ordered maps, also constant
• less efficient for range iteration through a subset of their elements than maps
• makes no guarantees on which specific element is considered which, but the range that goes from its begin to its end covers all the elements
UNORDERED_MAPS:
unordered_map<[type1], [type2]> [name] : declares unordered map
• cannot hold duplicates
• elements directly accessible by value
Member_functions:
• SHARED FUNCTIONS
erase([val]) : removes element with key equal to [val]
find([key]) : returns iterator to [key] element; returns .end() if not found
count([key]) : returns the number of elements with keys equal to [key]; since unordered map elements are unique, can only return 0 || 1
swap([unordered_map]) : exchange the values of this map with [unordered_map]
[[value]] : access element with [value] directly with the [] operator
UNORDERED_MULTIMAPS:
unordered_multimap<[type1], [type2]> [name] : declares unordered multimap
• can hold duplicates
Member_functions:
• SHARED FUNCTIONS
erase([val]) : removes all elements with key equal to [val]
find() : returns iterator to first element equal to [val]; if not found returns end()
count([key]) : returns the number of elements with keys equal to [key]
swap([unordered_multimap]) : exchange the values of this multimap with [unordered_multimap]
Shared_functions:
begin() : return iterator to first element
end() : returns iterator to past-the-"end" element
cbegin() : returns const_iterator to first element
cend() : returns const_iterator to last element
insert(<pair>) : inserts <pair>
erase([it]) : removes element at [it]
erase([it], [it2]) : removes all elements from [it] till [it2]
emplace([args]) : inserts an element which is constructed in place, passing [args] to its constructor
empty() : returns true if empty, false otherwise
size() : returns container size/length
clear() : clear contents
-------------
tuple: tuple:
-------------
#include <tuple>
Classes:
tuple:
• can hold different types
• similar to pythons tuple
Member_functions:
swap([tuple]) : exchanges members with [tuple]; [tuple] must be the same type
tuple_size:
tuple_size<decltype([tuple])>::value : ?!; returns [tuple object]s length for some reason
tuple_element:
tuple_element<[index],decltype([tuple])>::type : ?!; expands(?) to type of [tuple object] element at [index]
Objects:
ignore : ignores any value assigned to it
Functions:
make_tuple([vals]) : returns tuple filled with passed in [vals]
make_tuple([vals]) : returns reference to temporary tuple
tie([vals]) : temporary makes [vals] to behave like a tuple (so that a tuple can be assigned to them)
tuple_cat([tuples]) : returns a tuple with all elements of [tuples] concatenated after eachother
get<[index]>([tuple]) : returns [tuple]s element at [index]
-------------
stack: stack:
-------------
#include <stack>
Classes_templates:
stack:
• FILO (first in last out) container
template class stack<<typename>, [container] = deque>
— [container] shall have atleast the following member functions:
• empty()
• size()
• back()
• push_back()
• pop_back()
— containers from the std that qualify to be [container]:
• vector
• deque
• list
Member_functions:
empty() : whether the container is empty
size() : returns size
top() : access top element
push(<typename>) : insert element
emplace([args]) : constructs <typename> with [args] and places to the end of the queue, making it the new last element
pop() : removes top element
swap([stack]) : swaps the contents with [stack]
Member_typedes:
value_type : alias of template parameter <typename>
container_type : alias of template parameter [container]
reference : container_type::reference (most likely: value_type&)
const_refrence : container_type::const_refrence (most likely: const value_type@)
size_type : an unsigned number (most likely: size_t)
cpp_thread_libs
#define cpp_thread_libs:::
===============================================
THREADS
===============================================
---------------
threads: threads:
---------------
#include <thread>
class thread
joinable if NOT:
• default-constructed
• moved from either constructing another thread object, or assigning to it
• either of its members join or detach has been called
Member function:
joinable() : returns whether joinable
get_id() : returns thread id
swap([thread]) : swaps states with [thread]
join() : this function returns when the thread execution has completed
detach() : makes execution independent of object
always CALL join() OR detach() BEFORE DESTRUCTING A thread OBJECT:
"remaining detached threads executing in the background are not waited upon,\
instead their execution is suspended and their thread-local objects destructed;\
crucially, this means that the stack of those threads is not unwound and\
thus some destructors are not executed; depending on the actions\
those destructors were supposed to undertake, this might be as bad a situation\
as if the program had crashed or had been killed.\
hopefully the OS will release the locks on files, etc...\
but you could have corrupted shared memory, half-written files, and the like"
--------------
atomic:
--------------
#include <atomic>
--------------------------
condition_variable:
--------------------------
#include <condition_variable>
--------------
future:
--------------
#include <future>
-------------
mutex:
-------------
#include <mutex>
cpp_other_libs
#define cpp_other_libs:::
=============================================
OTHER
=============================================
-----------------
algorithm: algorithm:
-----------------
#include <algorithm>
• its the programmer's responsibility to make sure [it[X]]:[it[X+1]] range is valid; ([X] is odd)
• when you call algorithms for multiple ranges, make sure that the second and additional ranges have at least as many elements as the first range
• [func] can mark either an actual function or a functor
• values "judged" equal by a function if the function returns true when the said values were passed in
Bool:
all_of([it1], [it2], [func]) : returns whether ALL elements in range [it1]:[it2]-1 return TRUE to [func]
none_of([it1], [it2], [func]) : returns whether ALL elements in range [it1]:[it2]-1 return FALSE to [func]
any_of([it1], [it2], [func]) : returns whether ANY elements in range [it1]:[it2]-1 return TRUE to [func]
equal([it1], [it2], [it3]) : returns whether range [it1]:[it2]-1 is equal to range [it3]:[it3]+(it2-it1)
equal([it1], [it2], [it3], [func]) : returns whether [func]([it1]+i, [it3]+i) return true to all elements
is_permutation([it1], [it2], [it3]) : returns whether range [it1]:[it2]-1 and range [it3]:[it3]+(it2-it1) contain the equal
elemets in whatever order
is_permutation([it1], [it2], [it3], [func]) : returns whether range [it1]:[it2]-1 and range [it3]:[it3]+(it2-it1) contain the equal
elemets judged by [func] in whatever order
is_partitioned([it1], [it2], [func]) : returns whether all elemets that return true to [func] precede those that return false
is_sorted([it1], [it2]) : returns whether range [it1]:[it2]-1 is sorted
is_sorted([it1], [it2], [func]) : returns whether range [it1]:[it2]-1 is sorted by [func]
includes([it1], [it2], [it3], [it4]) : returns whether range [it1]:[it2]-1 contains all elements from range [it3]:[it4]
includes([it1], [it2], [it3], [it4], [func]): returns whether range [it1]:[it2]-1 contains all elements judged by [func] from range [it3]:[it4]
is_heap([it1], [it2]) : returns whether range [it1]:[it2]-1 is a heap; (not that heap; see BELOW)
is_heap([it1], [it2], [func]) : returns whether range [it1]:[it2]-1 is a heap organized by [func]; (not that heap; see BELOW)
lexicographical_compare([it1], [it2], : returns whether range [it1]:[it2]-1 is lexigraphically (alphabetically) less then range [it1]:[it2]
[it3], [it4])
lexicographical_compare([it1], [it2], : returns whether range [it1]:[it2]-1 is judged by [func] to be less then range [it1]:[it2]
[it3], [it4], [func])
Searching:
• they return [it2] if not found
find([it1], [it2], [val]) : returns iterator to FIRST element with an equal value to [val] in range [it1]:[it2]
find_if([it1], [it2], [func]) : returns iterator to FIRST element for which [func] returns TRUE
find_if_not([it1], [it2], [func]) : returns iterator to FIRST element for which [func] returns FALSE
find_first_of([it1], [it2], : returns iterator to FIRST element in range [it1]:[it2]-1 that is found in range [it3]:[it4]
[it3], [it4])
find_first_of([it1], [it2], : returns iterator to FIRST element in range [it1]:[it2]-1 that returns true to [func]([it1]+i, [it3]+i)
[it3], [it4],[func])
find_end([it1], [it2], : returns iterator to LAST element in range [it1]:[it2]-1 that is found in range [it3]:[it4]
[it3], [it4])
find_end([it1], [it2], : returns iterator to LAST element in range [it1]:[it2]-1 that returns true to [func]([it1]+i, [it3]+i)
[it3], [it4], [func])
adjacent_find([it1], [it2]) : returns iterator to FIRST element that is equal to the element after it
adjecent_find([it1], [it2], [func]) : returns iterator to FIRST element that returns true when it and the element after it are fed to [func]
mismatch([it1], [it2], [it3]) : returns a pair of iterators to [it1]+i and [it3]+i; i being where they first dont match
mismatch([it1], [it2], [it3], [func]) : returns a pair of iterators to [it1]+i and [it3]+i; i being where they first return FALSE to [func]
min([...]) : returns the smallest value, or if all arguments are equal -> [1]
min([...], [func]) : returns the smallest value, or if all arguments are equal -> [1]; compares using [func]
max([...]) : returns the highest value, or if all arguments are equal -> [1]
max([...], [func]) : returns the highest value, or if all arguments are equal -> [1]; compares using [func]
minmax([...]) : returns a pair, containing the smallest value as its first and the highest as its second
minmax([...], [func]) : returns a pair, containing the smallest value as its first and the highest as its second;
compares using [func]
min_element([it1], [it2]) : returns iterator to the element with the smallest value in range [it1]:[it2]
min_element([it1], [it2], [func]) : returns iterator to the element with the smallest value judged by [func] in range [it1]:[it2]
max_element([it1], [it2]) : returns iterator to the element with the largest value in range [it1]:[it2]
max_element([it1], [it2], [func]) : returns iterator to the element with the largest value judged by [func] in range [it1]:[it2]
minmax([it1], [it2]) : returns a pair, containing the smallest value as its first and the highest as its second in range [it1]:[it2];
minmax([it1], [it2], [func]) : returns a pair, containing the smallest value as its first and the highest as its second in range [it1]:[it2];
compares using [func]
search([it1], [it2], [it3], [it4]) : returns iterator to FIRST element in the range [it1]:[it2]-1 where theres a subsequence equal to [it3]:[it4]
search([it1], [it2], [it3], [it4]) : returns iterator to FIRST element in the range [it1]:[it2]-1 where theres a subsequence equal to [it3]:[it4]
judged by [func]
search_n([it1], [it2], [num], [val]) : returns iterator to the first position in range [it1]:[it2]-1 that has [num] equal elements to [val] in a row
search_n([it1], [it2], [num], : returns iterator to the first position in range [it1]:[it2]-1 that has [num] elements that are judged to be
[val], [func]) equal to [val] by [func] in a row
partition_point([it1], [it2], [func]) : returns an iterator to first element of partition two of range [it1]:[it2];
range shall be already partitioned; (use it cause its optimezed)
is_sorted_until([it1], [it2]) : returns iterator to the first element in range [it1]:[it2]-1 that is not in a sorted position
is_sorted_until([it1], [it2], [func]) : returns iterator to the first element in range [it1]:[it2]-1 that is not sorted by [func]
lower_bound([it1], [it2], [val]) : returns iterator to the first element in range [it1]:[it2]-1 that is not LESS then [val];
optimized for random-access iterators
lower_bound([it1], [it2], [val], [func]): returns iterator to the first element in range [it1]:[it2]-1 that is not LESS then [val] judged by [func];
optimized for random-access iterators
upper_bound([it1], [it2], [val]) : returns iterator to the first element in range [it1]:[it2]-1 that is not GREATER then [val];
optimized for random-access iterators
upper_bound([it1], [it2], [val], [func]): returns iterator to the first element in range [it1]:[it2]-1 that is not GREATER then [val] judged by [func];
optimized for random-access iterators
equal_range([it1], [it2], [val]) : returns a pair of iterators, the first element pointing to the first element in range [it1]:[it2]
equal to [val], the second element pointing after the last element that is adjasent and equal first;
optimized for random-access iterators
equal_range([it1], [it2], [val], [func]): returns a pair of iterators, the first element pointing to the first element in range [it1]:[it2]
judged by [func] to be equal to [val], the second element pointing after the last element that is
adjacent and equal first; optimized for random-access iterators
binary_search([it1], [it2], [val]) : returns true if any elements in the range [it1]:[it2]-1 is equal to [val];
optimized for random-access iterators
binary_search([it1], [it2], : returns true if any elements in the range [it1]:[it2]-1 is judged to be equal to [val] by [func];
[val], [func]) optimized for random-access iterators
is_heap_until([it1], [it2]) : returns an iterator to the first element in range [it1]:[it2]-1 which is not part of a heap;
(not that heap; see BELOW)
is_heap_until([it1], [it2], [func]) : returns an iterator to the first element in range [it1]:[it2]-1 which is not part of a heap
organized by [func]; (not that heap; see BELOW)
Transformation:
for_each([it1], [it2], [func]) : applies [func] to each elements in range [it1]:[it2]
transform([it1], [it2], [it3], [func]) : as ABOVE, but keeps them unchanged and stores the results at [it3]
copy([it1], [it2], [it3]) : copies range [it1]:[it2]-1 to range [it3]:[it3]+(it2-it1)
copy_n([it1], [num], [it2]) : copies range [it1]:[it1]+[num] to range [it2]:[it2]+[num]
copy_if([it1], [it2], [it3], [func]) : copies elemets from range [it1]:[it2]-1 to range [it3]:[it3]+(it2-it1) if they return true to [func]
copy_backward([it1], [it2], [it3]) : same as copy but it starts from the end; no, it does not reverse the order
move([it1], [it2], [it3]) : moves [it1]:[it2] to range [it3]:[it3]+(it2-it1); parsely for noncopyable types; ?!
move([container]) : moves [container] to what its assigned to (with '='); parsely for noncopyable types; ?!
swap([container1], [container2]) : swaps the contents of the two containers
swap([it1], [it2], [it3]) : swaps the contents of the two ranges
iter_swap([it1], [it2]) : swaps the elemets pointed by the two iterators
fill([it1], [it2], [val]) : replace all elements in range [it1]:[it2]-1 with [val]
fill_n([it], [num], [val]) : replace all elements in range [it1]:[it1]+[num] with [val]
generate([it1], [it2], [func]) : replace all elements in range [it1]:[it2]-1 with values returned by [func] on successive calls;
[func] shall take no argument
generate_n([it], [num], [func]) : replace all elements in range [it1]:[it1]+[num] with values returned by [func] on successive calls;
[func] shall take no argument
random_shuffle([it1], [it2]) : randomly rearanges elements in range [it1]:[it2]-1
random_shuffle([it1], [it2], [func]) : randomly rearanges elements in range [it1]:[it2]-1 by random number generator [func]
shuffle([it1], [it2], [func]) : as ABOVE, but [func] shall be an uniform random number generator (take no arguments)
merge([it1], [it2], [it3], [it4], [it5]) : copies range [it1]:[it2]-1 and [it3]:[it4] to [it5] in a sorted order
merge([it1], [it2], [it3], [it4], : copies range [it1]:[it2]-1 and [it3]:[it4] to [it5], sorted by [func]
[it5], [func])
inplace_merge([it1], [it2], [it3]) : sorts two adjesent, separately sorted ranges ([it1]:[it2]; [it2]:[it3]); efficient
inplace_merge([it1], [it2], [it3], [func]) : sorts two adjesent, separately sorted ranges ([it1]:[it2]; [it2]:[it3]) by [func]; efficient
set_union([it1], [it2], [it3], [it3], [it5]): copies unique elements from sorted ranges [it1]:[it2]-1 and [it3]:[it4]-1 to [it5]
set_union([it1], [it2], [it3], : copies elements judged by [func] to be unique from sorted ranges [it1]:[it2]-1 and [it3]:[it4]-1 to [it5]
[it3], [it5], [func])
set_intersection([it1], [it2], [it3], : copies elements that are present in both ranges [it1]:[it2]-1 and [it3]:[it4]-1 to [it5]
[it3], [it5])
set_intersection([it1], [it2], [it3], : copies elements that are present in both ranges [it1]:[it2]-1 and [it3]:[it4]-1 to [it5];
[it3], [it5], [func]) [func] judges what values are considered equal
set_difference([it1], [it2], [it3], : copies elements that are present only in range [it1]:[it2]-1 , but not and [it3]:[it4]-1 to [it5]
[it3], [it5])
set_difference([it1], [it2], [it3], : copies elements that are present only in range [it1]:[it2]-1 , but not and [it3]:[it4]-1 to [it5]
[it3], [it5], [func]) [func] judges what values are considered equal
set_symmetric_difference([it1], [it2], : copies elements that are present only in one of the ranges [it1]:[it2]-1 and [it3]:[it4]-1 to [it5]
[it3], [it4], [it5])
set_symmetric_difference([it1], [it2], : copies elements that are present only in one of the ranges [it1]:[it2]-1 and [it3]:[it4]-1 to [it5];
[it3], [it4], [it5], [func]) [func] judges what values are considered equal
Sorting:
• transformation with logic
sort([it1], [it2]) : sorts the elements in range [it1]:[it2]-1 into ascending order
sort([it1], [it2], [func]) : sorts the elements in range [it1]:[it2]-1 by [func];
[func] must return bool, which signals whether the first argument is considered to go before the second
stable_sort([it1], [it2]) : same as ABOVE, but equal elements keep their relative order
stable_sort([it1], [it2], [func]) : same as ABOVE, but equal elements keep their relative order
partial_sort([it1], [it2], [it3]) : rearanges the elements in range [it1]:[it3]-1 in such a way that range [it1]:[it2]-1 will be sorted
into ascending order, but elements in range [it2]:[it3] will be left in no order
partial_sort([it1], [it2], : rearanges the elements in range [it1]:[it3]-1 in such a way that range [it1]:[it2]-1 will be sorted
[it3], [func]) by [func], but elements in range [it2]:[it3] will be left in no order; [func] must return bool
partial_sort_copy([it1], [it2], : same as ABOVE, but the original container is untouched and the results of the operation are stored at [it4]
[it3], [it4])
partial_sort_copy([it1], [it2], : same as ABOVE, but the original container is untouched and the results of the operation are stored at [it4]
[it3], [it4], [func])
replace([it1], [it2], : replaces all elements in range [it1]:[it2]-1 with [val2] that are equal to [val1]
[val1], [val2])
replace_if([it1], [it2], : replaces all elements in range [it1]:[it2]-1 with [val] that return true to [func]
[func], [val])
replace_copy([it1], [it2], [it3], : copies range [it1]:[it2]-1 to range [it3]:[it3]+(it2-it1) but all elements equal to [val1] in the SOURCE
[val1], [val2]) range are replaces with [val2] in the DESTINATION
replace_copy_if([it1], [it2], : copies range [it1]:[it2]-1 to range [it3]:[it3]+(it2-it1) but all elements that return true to [func]
[it3], [func], [val]) in the SOURCE range are replaces with [val] in the DESTINATION
remove([it1], [it2], [val]) : packs the values equal to [val] to the start of the range, overwriting any elements do not equal to [val];
it does not resize the container, but returns an iterator to the last element that should be considered
part of the container
remove_if([it1], [it2], [func]) : packs the values that return true to [func] the start of the range, overwriting any elements
do not return true to [func]; it does not resize the container, but returns an iterator to
the last element that should be considered part of the container
remove_copy([it1], [it2], : same as copy, but leaving out any elements equaling [val]
[it3], [val])
remove_copy_if([it1], [it2], : same as copy, but leaving out any elements that does not return true to [func]
[it3], [func])
unique([it1], [it2]) : packs the unique values to the start of the range, overwriting any non-unique elements in the way,
it does not resize the container, but returns an iterator to the last element that should be considered
part of the container
unique([it1], [it2], [func]) : ?!
unique_copy([it1], [it2], [it3]) : copies unique elements from range [it1]:[it2]-1 to range [it3]:[it3]+x
reverse([it1], [it2]) : reverses the order of elemennts in range [it1]:[it2]
reverse_copy([it1], [it2], [it3]) : copy range [it1]:[it2]-1 to range [it3]:[it3]+(it2-it1) in reverse order
rotate([it1], [it2], [it3]) : rotares around the elements in souch a way that [it2] becomes the new [it1], and elements wrap around
rotate([it1], [it2], [it3], [it4]) : as ABOVE, but range [it1]:[it2]-1 will remain the same and range [it3]:[it3]+(it2-it1) will contain the results
partition([it1], [it2], [func]) : rearranges range [it1]:[it2]-1 in such a way that elemets that return true to [func] will be
packed to the front, and elements that return false will be packed to the back
stable_partition([it1], [it2], : same as ABOVE, but the relative order of elements are preserved
[func])
partition_copy([it1], [it2], : copies elemets [it1]:[it2]-1 from that return true to [func] to [it3] and elements that
[it3], [it4] [func]) return false to [it4]
nth_elementh([it1], [it2], [it3]) : sorts only [it2] element of range [it1]:[it3]; meaning [it2] will be the element that it would be if the whole
container were sorted; all other elements in an unspecified position, but no element preceding [it2] is greater
and no element after is less than it
Heap:
• not that heap
• a way to organize elements
• the first element is always the one with the highest value
make_heap([it1], [it2]) : makes heap out of range [it1]:[it2]
make_heap([it1], [it2], [func]) : makes heap out of range [it1]:[it2], deciding which element has the highest using [func]
push_heap([it1], [it2]) : adds element *[it2]-1 to heap
push_heap([it1], [it2], [func]) : adds element *[it2]-1 to heap organized by [func]
pop_heap([it1], [it2]) : srinks the heap by one, placing the highest value to [it2]-1
pop_heap([it1], [it2], [func]) : srinks the heap by one, placing the highest value judged by [func] to [it2]-1
Misc:
count([it1], [it2], [val]) : returns the number of elements in that are equal to val
count_if([it1], [it2], [val]) : returns the number of elements that return true to [func]
--------------
chrono: chrono:
--------------
#include <chrono>
• uses its own sub-namespace of std; ( std::chrono::[...] )
Duration:
template<<typename>, [ratio]> class duration
• 64 bit values by default
○ default typedef of instantiations
• hours
• minutes
• seconds
• milliseconds
• microseconds
• nanoseconds
— Member_functions:
count() : returns value in int
Clocks:
○ default typedef of instantiations
• system_clock
• steady_clock
• high_resolution_clock
functions inside the above namespaces:
now() : returns timestamp to current time
/------+--------------------\
| Epoch | UTC 1970 January 1. |
\------+--------------------/
Timepoints:
template<[clock], [duration]> class time_point
• point in time relative to a clock's epoch
Member_functions:
time_since_epoch() : returns duration since epoch
Functions:
duration_cast<[duration1]>([duration2]) : return
---------------
codecvt: codecvt:
---------------
#include <codecvt>
Enum:
codecvt_mode:
• bitmask type
1 - little_endian
2 - generate_header
4 - consume_header
Class_templates:
codecvt_utf8<
[w_char_type],
[] = 0x10ffffUL,
[codecvt_mode]
•
---------------
complex: complex:
---------------
#include <complex>
Classes:
complex:
complex<[num]> : declares complex
• holds complex number
• a complex number looks like this:
x + i*y
where x ∈ R, representing the "real" part of the number;
where i = √1 (i² = -1);
where y ∈ R, representing the amount if 'i'-s;
Member_functions:
real() : returns x
imag() : returns y
Functions:
real([complex]) : returns x of [complex]
imag([complex]) : returns y of [complex]
abs([complex]) : returns the absolute value of [complex]; ie. the distance between (0, 0) and (x, y) ( √(x²+y²) )
-----------------
exception: exception:
-----------------
#include <stdexcept>
Functions:
unexpected() : whenever a function throws an exception that is not listed on its exception specifier this function
is automatically called; calls the current unexpected handler (see BELOW)
get_unexpected() : if set_unexpected() was called previously, it returns the current unexpected handler,
otherwise returns an unspecified value
set_unexpected([func]) : sets the current unexpected handler to [func] (see ABOVE)
terminate() : default unexpected handler; calls the current terminate handler (which is abort() by default)
get_terminate() : if set_terminate() was called previously, it returns the current terminate handler,
otherwise returns an unspecified value
set_terminate([func]) : sets the current terminate handler to [func] (see ABOVE)
uncaught_exception() : returns true if an exception was throw, but not yet handled
current_exception() : returns an exception_ptr that points to the currently handled exception or to a copy of it
rethrow_exception( : throws exception *[exception_ptr]
[exception_ptr])
make_exception_prt([...]) : returns an exception_ptr created from [...]
throw_with_nested([...]) : throws a nested_exception combining the currently handled except and [...]
rethrow_if_nested([...]) : throws the exception nested in [...] if [...] is derived from nested_exception
Classes:
exception: base class for standard exceptions; all objects thrown by components of the standard library are derived from this class;
therefore, all standard exceptions can be caught by catching this type by reference;
Derived Classes: (bad_cast, bad_exception, bad_function_call, bad_typeid, bad_weak_ptr, ios_base::failure,
logic_error, runtime_error, domain_error, future_error, invalid_argument, length_error, out_of_range,
overflow_error, range_error, system_error, underflow_error, bad_array_new_length)
• most are defined in other headers
Member_functions:
virtual what() : returns a null terminated character sequence that may be used to identify the exception
bad_exception: derived from exception (see ABOVE); if a function throws an exception that wasnt listed in its exception specifier
and unexpected() throws something that was also not listed, this exception is automatically thrown
nested_exception: holds 2 exception, one as nested
Member_functions:
rethrow_nested() : throws the nested exception
nested_ptr() : returns exception_ptr to nested exception
Typedefs:
exception_prt : smartpointer that can refer to an exception object
terminate_handler : void function pointer with no arguments
unexpected_handler : void function pointer with no arguments
------------------
functional: functional:
------------------
#include <functional>
Functions:
bind([function], [args/placeholders]) : returns a function object which, when called calls [function] with [args/placeholders]
{
int divide(int x, int y){ return x/y; }
[...]
auto d = std::bind(divide, 10, 2); d();
auto d2 = std::bind(divide, std::placeholders::_1, 2); d2(100);
std::cout << std::bind(divide, 9, 3);
}
ref([...]) : returns reference_wrapper to [...]
cref([const ...]) : returns reference_wrapper to [const ...]
mem_fun([member func]) : returns member function pointer to "function" pointer;
which can be called with an object pointer as its first
argument and a custom one to call the member function with;
ie. incompatible with member functions that take more then 1 argument
{
struct meaning_of_life{ int answer(){ return 42; } my_meaning;
auto give_answer = std::memfun(&meaning_of_life::answer);
std::cout << give_answer(&my_meaning);
}
mem_fn([member func]) : replacement for mem_fun() (see ABOVE); can take arbitrary number of arguments;
can be called with object
not_fn([func]) : return functor that returns the opposite value of [func] (0 || 1)
Class_templates:
template class reference_wrapper<[...]>
Member_functions:
• no default constructor
get() : access reference wrapped element
function<[...]> : callable element wrapper
• used for passing unknown type of functions (or functors) as arguments
Member_functions:
assign() : ?!
operator bool : ??!!??!!
target_type : ?!
Target type_info: ?!
target : ?!
swap : ?!
Operator classes (function classes):
----------------------------------------------
| Expresion | Effect |
----------------------------------------------
| negate<[type]>() | - param |
| plus<[type]>() | param1 + param2 |
| minus<[type]>() | param1 - param2 |
| multiplies<[type]>() | param1 * param2 |
| divides<[type]>() | param1 / param2 |
| modulus<[type]>() | param1 % param2 |
| equal_to<[type]>() | param1 == param2 |
| not_equal_to<[type]>() | param1 != param2 |
| less<[type]>() | param1 < param2 |
| greater<[type]>() | param1 > param2 |
| less_equal<[type]>() | param1 <= param2 |
| greater_equal<[type]>() | param1 >= param2 |
| logical_not<[type]>() | ! param |
| logical_and<[type]>() | param1 && param2 |
| logical_or<[type]>() | param1 || param2 |
| bit_and<[type]>() | param1 & param2 |
| bit_or<[type]>() | param1 | param2 |
| bit_xor<[type]>() | param1 ^ param2 |
----------------------------------------------
Namespaces:
placeholders : contains unspecified amount of "placeholders" (_1, _2, [...] _N), which when used in std::bind(),
when calling the returned object the appropriate argument passed in will take its place (see AT bind())
--------------
limits: limits:
--------------
#include <limits>
Functions_templates:
template class numeric_limits<[num]>
Members:
• static consexpr-s
• most correspond to C <limits.h> or <float.h> macros
is_specialized : true if [num] a type that numeric_limits<> is specialized for { int, double...}
min() : minimum finite value
max() : maximum finite value
lowest() : for ints same as min(); for floating-points negative of max()
digits : for ints, the number of non sign bits; for floats the mantissa bits
digits10 : number of decimal digits that can be rounded into a [class] floating-point type and back without loss of precision
is_signed : whether signed
is_integer : whether int
is_exact : whether uses exact representation
radix : base of representation
epsilon() : difference between 1 and the next representable value
round_error() : measure of maximum rounding error
mix_exponent : minimum value for the exponent that generates a normalized [class] floating-point type
mix_exponent10 : minimum value for the exponent of base 10 that generates a normalized [class] floating-point type
max_exponent : maximum value for the exponent that generates a normalized [class] floating-point type
max_exponent10 : maximum value for the exponent of base 10 that generates a normalized [class] floating-point type
has_infinity : whether can represent infinity
has_quiet_NaN : whether can represent quiet NAN
has_signaling_NaN : whether can represent signaling NAN
infinity() : representation of infinity
quiet_NaN() : representation of quiet NAN
signaling_NaN() : representation of signaling NAN
has_denorm : appropriate float_denorm_style (see BELOW)
has_denorm_loss : whether loss of accuracy is detected as a denormalization loss
denorm_min() : minimum positive denormalized value
is_iec559 : whether IEC-559 or IEEE-754 standard
is_bounded : whether finite
is_modulo : whether adding two positive numbers to have the result wrap around and result in a smaller number
traps : whether trapping is implemented for [class]
tinyness_before : whether tinyness is detected before rounding
round_syte : appropriate float_round_style (see BELOW)
{std::numeric_limits<int>::max();}
Enums:
float_round_style:
round_indeterminate : -1; rounding style cannot be determined at compile time
round_toward_zero : 0; rounding style toward zero
round_to_nearest : 1; rounding style to the nearest representable value
round_toward_infinity : 2; rounding style toward infinity
round_toward_neg_infinity : 3; rounding style toward negative infinity
float_denorm_style
denorm_indeterminate : -1; denormalization style for the type cannot be determined at compile time
denorm_absent : 0; [class] type does not allow denormalized values
denorm_present : 1; [class] allows denormalized values
--------------
memory: memory:
--------------
#include <memory>
Class_templates:
Managed_pointers:
Auto_pointer:
template class auto_ptr<[...]>
• automatically manages life span of the pointed object; call the destructor
whenever the pointer is destroyed (goes out of scope); deprecated, use unique_ptr instead (see BELOW)
template class auto_ptr_ref<[auto_ptr]>
• auto_ptr reference wrapper
Unique_pointer:
template class unique_ptr<[class]>
• automatically manages life span of the pointed object; call the destructor
whenever the pointer is destroyed (goes out of scope); it should be the only managed pointer owning the object;
minimal to no overhead
Member_functions:
get() : returns pointer to the pointed object; does NOT release ownership
get_deleter() : returns callable object that is used for deleting the pointed object
release() : returns pointer to the pointed object, releases owner ship and sets itself to NULL
reset() : destroys the pointed object and sets itself to NULL
swap([unique_ptr]) : swaps contents with [unique_ptr]
Shared_pointer:
template class shared_ptr<[class]>
• automatically manages life span of the pointed object; whenever the last shared_ptr to the pointed object
is deleted, the destructor of the pointed object is called; uses reference counting;
assign only to make_shared() please (see BELOW)
Member_functions:
get() : returns pointer to the pointed object; does NOT release ownership
reset() : destroys the pointed object and sets itself to NULL
swap([shared_ptr]) : swaps contents with [unique_ptr]
use_count() : returns the number of shared_pointers pointing to the pointed object
unique() : returns whether this is the only shared_ptr pointing to the pointed object
owner_before([shared_ptr]) : returns whether this shared_pointer precedes [shared_ptr]; implementation defined;
used to make shared and weak pointers usable as keys in associative containers
Weak_pointer:
template class weak_ptr<[class]>
• kinda a shared_ptr that doesnt increase the reference count
reset() : destroys the pointed object and sets itself to NULL
swap([weak_ptr]) : swaps contents with [weak_ptr]
use_count() : returns the number of shared_pointers pointing to the pointed object
owner_before([weak_ptr]) : returns whether this weak_pointer precedes [weak_ptr]; implementation defined;
used to make shared and weak pointers usable as keys in associative containers
expired() : returns whether use_count() == 0, but in a (possibly) more efficient way
lock() : returns shared_ptr to the pointed object (or a default constructed shared_ptr if there's none),
and prevents the owner to realise as long as the returned object doesnt do so
Allocation_related:
Class_templates:
Allocator:
template class allocator<<typename>>
• default allocator
Member_typedefs:
value_type : alias of template parameter <typename>
pointer : <typename>*
const_pointer : const <typename>*
reference : <typename>&
const_refrence : const <typename>&
size_type : size_t
difference_type : ptrdiff_t
Member_struct_templates:
rebind<[typename2]>
Member_typedefs:
other : allocator<[typename2]>
Member_functions:
address([&object]) : returns address of [&object]
allocate([size_type], [const void*] = 0) : allocates memory for [size_type] [value_type]s; returns a pointer to the first element;
[const void*] shall be a value obtained from a previous call, which hasn't been freed yet;
[const void*] will not be overwritten, but rather the adjacent memory will get tested
for suitableness, which if is suitable is a performance improvement
deallocate([pointer], [size_type]) : releases [size_type] [value_type] memory
max_size() : returns the number of elements that could be potentially allocated by allocate()
construct([pointer], [args]) : constructs a value_type at [pointer] with [args]
destroy([pointer]) : destructs object at [pointer]
Structs:
allocator_arg_t : empty struct-s used for differentiating overloads
Objects:
allocator_arg : object of allocator_arg_t (see ABOVE)
Struct_templates:
Allocator_traits:
template class allocator_traits<[allocator]>
Member_typedefs:
allocator_type : alias of template parameter [allocator]
value_type : allocator_type::value_type
pointer : allocator_type::pointer
const_pointer : allocator_type::const_pointer
void_pointer : ?!
Functors:
template class default_delete<[class]>
• deletes whatever the passed in pointer points to
Function_templates:
template class make_shared<[class]>([args])
• constructs shared pointer to an object of [class] constructed with [args];
faster then calling the shared_ptr's constructor
template class make_shared<[class]>([args])
• constructs unique pointer to an object of [class] constructed with [args]
--------------
random: random:
--------------
#include <random>
Generators:
• random number engines
Class_templates:
linear_congruential_engine
mersenne_twister_engine
subtract_with_carry_engine
discard_block_engine
independent_bits_engine
shuffle_order_engine
Classes:
default_random_engine
minstd_rand
minstd_rand0
mt19937
mt19937_64
ranlux24_base
ranlux48_base
ranlux24
ranlux48
knuth_b
random_device
Distributions:
• functor that takes a generator as an argument and uses it to create distributions of it
uniform_int_distribution
uniform_real_distribution
bernoulli_distribution
binomial_distribution
geometric_distribution
negative_binomial_distribution
poisson_distribution
exponential_distribution
gamma_distribution
weibull_distribution
extreme_value_distribution
normal_distribution
lognormal_distribution
chi_squared_distribution
cauchy_distribution
fisher_f_distribution
student_t_distribution
discrete_distribution
piecewise_constant_distribution
piecewise_linear_distribution
Mics:
seed_seq
generate_canonical
{
ranlux48 randy;
bernoulli_distribution bnard(0.5);
auto dice = bind(bnard, randy);
}
-------------
ratio: ratio:
-------------
#include <ratio>
Class_templates:
• meant to be typedefed rather then actually create instances of
template class ratio<[num1], [num2] = 1>
• { typedef ratio<1, 2> half; cout << half::num << '/' << half::den << endl; }
• the denominator cant be 0
• will always simplify { 4/8 -> 1/2 }
— Members:
num(erator)
den(ominator)
arthimetric:
• all have members "num" and "den"
template class ratio_add<[ratio class1], [ratio class2]> : holds the value of the sum of [ratio class1] and [ratio class2]
template class ratio_subtract<[ratio class1], [ratio class2]> : holds the value of the difference of [ratio class1] and [ratio class2]
template class ratio_multiply<[ratio class1], [ratio class2]> : holds the value of the multiplication of [ratio class1] and [ratio class2]
template class ratio_divide<[ratio class1], [ratio class2]> : holds the value of the dividition of [ratio class1] with [ratio class2]
comperason:
• all have a member "value"
template class ratio_equal<[ratio class1], [ratio class2]> : whether [ratio class1] and [ratio class2] are equal
template class ratio_not_equal<[ratio class1], [ratio class2]> : whether [ratio class1] and [ratio class2] are NOT equal
template class ratio_less<[ratio class1], [ratio class2]> : whether [ratio class1] is less then [ratio class2]
template class ratio_less_equal<[ratio class1], [ratio class2]> : whether [ratio class1] is less then or equal to [ratio class2]
template class ratio_greater<[ratio class1], [ratio class2]> : whether [ratio class1] is greater then [ratio class2]
template class ratio_greater_equal<[ratio class1], [ratio class2]> : whether [ratio class1] is greater then or equal to [ratio class2]
-------------
regex: regex:
-------------
#include <regex>
Namespaces:
regex_constants:
Bitmasks:
— used as [flags] parameter of basic_regex.assign():
icase : case insensitive
nosubs : no subexpressions
optimize : optimize for matching rather than object construction
collate : local sensitive
— syntax:
• one and only one shall be specified
ECMAScript : ECMAScript; default
basic : basic POSIX
extended : extended POSIX
awk : Awk POSIX
grep : grep POSIX
egrep : egrep POSIX
— used as [?!] parameter of regex_match(), regex_search(), regex_replace,
regex_iterator constructor or regex_token_iterator constructor
match_default : default
○ match_not_[e,b]
• match the literal, humanly logical [*] and not the corresponding char
macth_not_bol : not Beginning-Of-Line; { '^' }
match_not_eol : not End-Of-Line; nor '\n' { '$' }
match_not_bow : not Beginning-Of-Word; { '\b' }
match_not_eow : not End-Of-Word; { '\b' }
match_any : any match is acceptable if multiple matches are possible
match_not_null : do not match empty sequences
match_continuous
match_prev_avail
format_default
format_sed
format_no_copy : non-matching sequences are not copied when replacing
format_first_only : replace first occurrence only
—
error_collate
error_ctype
error_escape
error_backref
error_brack
error_paren
error_brace
error_badbrac
error_range
error_space
error_badrepeat
error_complexity
error_stack
Class_templates:
regex_traits:
regex_traits<<typename>> [name] : declares regex_traits
• <typename> is the char_type to be used
Member_typedefs:
char_type : alias of template parameter <typename>
string_type : basic_string<[char_type]>
locale_type : the standard locale type
char_class_type : a bitmask type; ?!
Member_functions:
length([char_type*]) : returns size of C-style string [char_type*]
translate([char_type*]) : returns [char_type*]; meant to be overridden
translate_nocase([char_type*]) : returns case insensitive version of [char_type*]; by default uses cctype/tolower()
transform([forward_iterator1], : returns string_type created from [forward_iterator1, forward_iterator2]
[forward_iterator2])
transform_primary([forward_iteratorr1], : ?!
[forward_iteratorr2])
basic_regex:
regex<<typename>, [traits] = regex_traits<typename>> [name] : declares regex
Member_typedefs:
value_type : <typename>
traits_type : [traits]
string_type : [traits]::string_type
flag_type : regex_constants::syntax_option_type
locale_type : [traits]::locale_type
Member_functions:
assign(<string>, [flags])
Typedefs:
regex : basic_regex<char>
Exceptions:
regex_error : thrown when ?!
---------------------------
<stdexcept>
---------------------------
#include <stdexcept>
--------
------------------------------
<system_errno>
------------------------------
#include <system_errno>
--------
---------------------------
<typeindex>
---------------------------
#include <typeindex>
--------
--------------------------
<typeinfo>
--------------------------
#include <typeinfo>
--------
-----------------------------
<type_traits>
-----------------------------
#include <type_traits>
--------
-------------------------
<utility>
-------------------------
#include <utility>
#define 3th_party_cpp_libs
#define 3th_party_c++_libs:::
--------
--------------
utfcpp: utfcpp:
--------------
#include <utf8.h>
using namespace utf8;
Functions:
string utf8to16(<string>)
string utf8to32(<string>)
string utf16to8(<string>)
string utf16to32(<string>)
string utf32to8(<string>)
string utf32to16(<string>)
Function_templates:
typename find_valid(<typename>, <typename>)
IN_PRACTICE:
Hello_world:
{
#include <iostream.h>
#include <fstream>
#include <vector>
#include <utf8.h>
using namespace std;
signed main(int argc, char* argv[]){
ifstream f("my_utf8_file.txt");
vector<string> vstr;
string str;
while(getline(f, str)){
if(utf8::is_valid(str)){
vstr.push_back(str);
}
}
vector<u32string> vws;
for(auto i : vs){
vws.push_back(utf8::utf8to32(i));
}
for(auto i : vws){
wcout << i << endl;
}
return 0;
}
}
boost
#define boost:::: \
I---------------------------------------------------\
I ______ _____ _____ _____ _____ \
I | ___ \| _ || _ |/ ___||_ _| \
I | |_/ /| | | || | | |\ `--. | | \
I | ___ \| | | || | | | `--. \ | | \
I | |_/ /\ \_/ /\ \_/ //\__/ / | | \
I \____/ \___/ \___/ \____/ \_/ \
I---------------------------------------------------I
-----------------
random_hpp: random_hpp:
-----------------
#include <boost/random.hpp>
using namespace boost;
https://www.boost.org/doc/libs/1_66_0/doc/html/boost_random/reference.html
engines:
— reference has a nice list
— fastest: mt11213b
— bestest: ranlux64_4
base:
[random number generator engine] [object name];
[object name]() : gives random number;
[object name].seed(): takes int, changes seed, just like srand();
uniform_int<> [object name]([int min], [int max]) : min-max value variable
variate_generator< [random number generator engine], [uniform_int or ???] > [object name]( [engine object name], [uniform_int object name]);
---------------------
ios_state_hpp: ios_state_hpp:
---------------------
#include <boost/io/ios_state.hpp>
boost::io::ios_flags_saver [name]([cout]); : this object saves the state of [cout] and restores it when ever its deconstructed
----------------------
filesystem.hpp:
----------------------
#include <boost/filesystem.hpp>
• enclosed in the "boost::filesystem" namespace
Functions:
• these functions all follow the logic of POSIX stat
current_path() : returns [path] representing ${PWD} (the current working directory)
exists([path]) : whether [path] exists
is_directory([path]) : whether [path] is a directory
is_regular_file([path]) : whether [path] is a normal file
is_symlink() : whether [path] is a symlink
is_other() : whether [path] is neither a directory, a normal file or a symlink
is_empty() : whether [path] is a empty file
file_size([path]) : returns size of [path]
create_directory([path]) : creates directory named [path]
status([path]) : returns filestatus object constructed from [path]; symlinks are NOT followed
symlink_status([path]) : returns filestatus object constructed from [path]; symlinks are followed
Classes:
file_status : stores file status information
member_functions:
• these functions correspond to global funtions (see ABOVE)
exists([path]) : whether [path] exists
is_directory([path]) : whether [path] is a directory
is_regular_file([path]) : whether [path] is a normal file
is_symlink() : whether [path] is a symlink
is_other() : whether [path] is neither a directory, a normal file or a symlink
is_empty() : whether [path] is a empty file
Class_templates:
path<<string>, [traits]> : represents a file path
• fluidly constructed from C-string/std::string;
therefor when a path must be passed and a string will also do
• can include reference to current and parent directory ("."; "..")
Member_typedefs:
typedef basic_path<String, Traits> path_type
typedef String string_type
typedef typename String::value_type value_type
typedef Traits traits_type
typedef typename Traits::external_string_type external_string_type
Member_functions:
clear() :
swap([path]) : swaps contents with [path]
remove_filename() : if has_parent_path() is true, remove the last filename and trailing '/'s, else do nothing
replace_extention(<string> = "") : replaces file extension with <string>
string() : returns stored path as string_type
empty() : returns string().empty() (see ABOVE)
file_string() : returns stored path formatted in a operating system native format file name format
(which is the same as string() in Linux and Windows)
directory_string() : returns stored path formated in a operating system native format directory name format
(which is the same as string() in Linux and Windows)
filename() : returns filename only (like basename; see AT "/Linux/File System/basename")
operators:
/ : appends path with child
{ path base("mydir");
path file("myfile");
path full( base / file );
}
directory_iterator<[path]> : type for easy iterating over of files in a directory
Member_functions:
path() : returns path currently pointed at
Operators:
++ : steps the next file, hence modifying path()s value
basic_directory_entry<[path]> :
members:
basic_path m_path :
file_status m_status :
file_status m_symlink_status :
the file_status object cache values
---------------------------------
integer_common_factor_hpp: integer_common_factor_hpp:
---------------------------------
#include <boost/integer/common_factor.hpp>
gcd([num], [num]) : returns the "Greatest Common Divisor" of the 2 arguments
lcm([num], [num]) : returns the "Least Common Multiple" of the 2 arguments
qt
#define qt:::: \
I--------------------\
I _____ _ \
I | _ | | \
I | | | | |_ \
I | | | | __| \
I \ \/' / |_ \
I \_/\_\\__| \
I--------------------I
• robust GUI framework
• recommended
• has its own dialect of C++ with slots and signals,
which transpiles to standard C++
• reliable
• pretty
• easy to get started
• cross-platform
• large
• confusing at points
• convoluted dependency chain (but not quite bad enough to be called a dependency hell)
Programs:
qmake : Qt build tool
qt-designer : standalone GUI builder
(similar to how you can create WPF UIs
with drag-n-drop and attribute editing)
qt-creator : Qt IDE; contains an editor with an LSP,
a debugger, build-system and integrates qt-designer;
friendly towards files being edited from outside
(meaning, using its quality of life features does
not force its editor on you)
--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------
----------------
RapidCSV: RapidCSV:
----------------
using namespace rapidcsv;
• header only
Classes:
Document:
class Document(<path>(, <LabelParams>))
Member_functions:
template auto GetColumn<typename>(<id>) -> vector<typename>
template auto GetRow<typename>(<id>) -> vector<typename>
template auto GetCell<typename>(<id-1>, <id-2>) -> vector<typename>
Label_params:
class LabelParams(<int-1>, <int-2>)
int-1 : row header
int-2 : column header
0 - header exists
— 1 - header doesnt exists
SeparatorParams:
class SeparatorParams(<char>)
-------------------
TurboVision: TurboVision:
-------------------
#include <tvision/tv.h>
• TUI library
• looks great
• object oriented
• from the 90s
• the guy porting it did a very nice job, seriously
• supports all kinds of colors seemlessly
• the ported version supports unicode
• the naming is all funny
• it seems that nothing can be added to the deskTop until TApplication::run()
has been called, but since that creates an event oriented context,
it also means that nothing can be displayed without user interaction
(not without hacking anyways)
swig
#define swig:: \
I---------------------------\
I ___ _ \
I / __|_ __ _(_)__ _ \
I \__ \ V V / / _` | \
I |___/\_/\_/|_\__, | \
I |___/ \
I---------------------------I
• C/C++ binding generator
• primarily focused on extending scripting languages
— the type of binding Swig automates
┌────────────────────┐
│ Scripting Language │
└────────────────────┘
| |
| |
\ /
\ /
\ /
┌─────────────────────────────────────┐
│ │
│ Collection of C/C++ functions │
│ │
└─────────────────────────────────────┘
Programs:
swig <backend> [options]* <file>+ : generate bindings based on <file> for <backend>
<backends>
— csharp
— d
— go
— guile
— java
— javascript
— lua
— octave
— perl5
— php7
— python
— r
— ruby
— scilab
— tcl8
— xml
[options]
— c++ : generate C++ bindings { use new instead of malloc() }
— module <name> : override module naming
— D<symbol>[=<value>]
— o <file>
Extensions:
.i : interface file
.swg : explicit swig interface file
Interfaces:
• swig generates code based on interface files
• the swig output from interface files are valid C/C++ meant to be further processed
with conventional compilers
{
<directive|declaration>+
}
• often C/C++ source files are technically adequate interface files only requiring
a few cli options, however this is generally discurraged
Directives:
%module <name> : names the "module"; this information is usually passed to the backend
%{ %} : literal codeblock to be inserted into the generated code
without further processing;
yacc style
Declaration:
• ANSI C or C++ declaration
• every declartion will be wrapped
• marks symbols as public for the backend
footguns
#define footguns:::: \
I=====================================================\
I=====================================================\
I \
I ______ _ \
I | ___| | | \
I | |_ ___ ___ | |_ __ _ _ _ _ __ ___ \
I | _/ _ \ / _ \| __/ _` | | | | '_ \/ __| \
I | || (_) | (_) | || (_| | |_| | | | \__ \ \
I \_| \___/ \___/ \__\__, |\__,_|_| |_|___/ \
I __/ | \
I |___/ \
I=====================================================\
I=====================================================I
Errno:
function ‘int* __errno_location()’ is initialized like a variable
Cause:
• if errno is defined as a macro,
it cannot be used as name in another scope nor declared extern
— according to the standard it has to be a macro, yet the man says (2025):
"The <errno.h> header file defines the integer variable errno [...]"
Fix:
• do not use the name "errno"
• include <errno.h>
Clang:
• as we know undefined behaviour is useful for optimizations
• clang has a tendency to take them to an extreme
• the example below has been fixed in clang++19,
but the general take away is that GCC is slightly more reliable
// @BAKE clang++-18 -o $* $@ -O1 -Wall
#include <iostream>
int main() {
while (1)
;
}
void unreachable() {
std::cout << "Hello world!" << std::endl;
}
/*
clang version 18.1.5
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm/18/bin
Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang.cfg
$ a.out
Hello world!
*/
conversions
#define conversions:::: \
I=================================================================================\
I=================================================================================\
I _____ _ _ _ _ \
I / __ \ (_) | | | |_ | | \
I | / \/ ___ _ ____ _____ _ __ ___ _ ___ _ __ | |_| (_)__| |_ __ \
I | | / _ \| '_ \ \ / / _ \ '__/ __| |/ _ \| '_ \ | __| | / _` | '__| \
I | \__/\ (_) | | | \ V / __/ | \__ \ | (_) | | | | | |_| || (_| | | \
I \____/\___/|_| |_|\_/ \___|_| |___/_|\___/|_| |_| \__|_( )__,_|_| \
I |/ \
I=================================================================================\
I=================================================================================I
Ints <-> Ints:
• no explicit conversion is needed, values are auto truncated/padded
Floats <-> Floats:
• no explicit conversion is needed, values are auto truncated/padded
Floats <-> Ints:
• no explicit conversion is needed, values are auto truncated/padded
char <-> Ints:
• as char is already a num type just representing an ASCII code a simple addition/subtraction will suffice
• the const difference between 0 and '0' is 48 (or 060/0x30/0b00110000), which is -not accidently- also '0'
{
char user_input;
int user_choise = user_input - '0';
int my_int = 7;
putchar(7 + 48)
}
char -> wchar_t:
wchar_t btowc([char])
wchar_t -> char:
char wctob([wchar_t])
• returns EOF if inpossible
char* -> typename:
• use scanf if possible
{
int d;
sscanf("5", "%d", d);
}
typename -> char*:
• its the simplest to use printf() for all purposes alike
• GNU asprintf() and vasprintf() makes life oh so better
{
char* output;
asprintf(&output, "%.1lf", 13.4);
}
Nums -> string:
{
#include <string>
std::to_string(myNumber);
}
string -> const char*:
<string>.c_str()
bool -> string:
boolalpha([bool]) : converts bool to string 'true' or 'false'
snippets
#define snippets::: \
I========================================================\
I========================================================\
I _____ _ _ \
I / ___| (_) | | \
I \ `--. _ __ _ _ __ _ __ ___| |_ ___ \
I `--. \ '_ \| | '_ \| '_ \ / _ \ __/ __| \
I /\__/ / | | | | |_) | |_) | __/ |_\__ \ \
I \____/|_| |_|_| .__/| .__/ \___|\__|___/ \
I | | | | \
I |_| |_| \
I========================================================\
I========================================================I
FILE* to C string:
https://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html
#include <stdio.h>
// ...
FILE* f = fopen("file.txt", "rw");
if(!f){ /*ERROR HANDLING*/; }
fseek(f, 0, SEEK_END);
int flen = ftell(f);
rewind(f);
char fstr[flen+1];
fstr[flen] = '\00';
fread(fstr, flen, sizeof(char), f);
fclose(f);
#define READ_ENTIRE_FILE(filehandle, buffername) \
fseek(filehandle, 0, SEEK_END); \
int filehandle ## len = ftell(filehandle); \
rewind(filehandle); \
char buffername[filehandle ## len+1]; \
buffername[filehandle ## len] = '\00'; \
fread(buffername, filehandle ## len, sizeof(char), filehandle); \
fclose(filehandle);
Guard_C_definitions:
#ifdef __cplusplus
extern "C" {
#endif
// C definitions
#ifdef __cplusplus
}
#endif
Strtok: Strtok:
#include <string.h>
// ...
const char* delim = ";";
char* data = strtok(line, delim);
i = 0;
do{
/* do stuff with data */
++i;
}while((data = strtok(NULL, delim), data));
Nested_strtok_with_strtok_r: Nested_strtok_with_strtok_r:
• the variable names {line_delim, col_delim} in the example specialize on parsing csv
#include <string.h>
// ...
const char* line_delim = "\n";
const char* col_delim = ";";
char* line_save;
char* line = strtok_r(fstr, line_delim, &line_save);
int i = 0;
int h;
do{
h = 0;
char* col = strtok(line, col_delim);
do{
/* do stuff with col */
++h;
}while((col = strtok(NULL, col_delim), col));
++i;
}while((line = strtok_r(NULL, line_delim, &line_save), line));
### Getting the TTY size in C without ncurses ###
• *NIX only
• it is baffling how everyone only ever says "uh oh use ncurses or something"
// @BAKE gcc -o $*.out $@
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
int get_tty_size(int * width_out, int * height_out) {
struct winsize ws;
int fd = open("/dev/tty", O_WRONLY);
if (fd == -1) { return 1; }
ioctl(fd, TIOCGWINSZ, &ws);
close(fd);
*width_out = ws.ws_col;
*height_out = ws.ws_row;
return 0;
}
#include <stdio.h>
signed main(void) {
int width, height;
get_tty_size(&width, &height);
printf("Your terminal size is %dx%d\n", width, height);
return 0;
}
#
Auto_pass_vararg_count:
// @BAKE gcc $@ -o $*
#include <stdio.h>
#include <stdarg.h>
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_128TH_ARG(__VA_ARGS__)
#define PP_128TH_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,_64,_65,_66,_67,_68,_69,_70, \
_71,_72,_73,_74,_75,_76,_77,_78,_79,_80, \
_81,_82,_83,_84,_85,_86,_87,_88,_89,_90, \
_91,_92,_93,_94,_95,_96,_97,_98,_99,_100, \
_101,_102,_103,_104,_105,_106,_107,_108,_109,_110, \
_111,_112,_113,_114,_115,_116,_117,_118,_119,_120, \
_121,_122,_123,_124,_125,_126,_127,N,...) N
#define PP_RSEQ_N() \
127,126,125,124,123,122,121,120, \
119,118,117,116,115,114,113,112,111,110, \
109,108,107,106,105,104,103,102,101,100, \
99,98,97,96,95,94,93,92,91,90, \
89,88,87,86,85,84,83,82,81,80, \
79,78,77,76,75,74,73,72,71,70, \
69,68,67,66,65,64,63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
void _variad(size_t argc, ...);
#define variad(...) _variad(PP_NARG(__VA_ARGS__), __VA_ARGS__)
void _variad(size_t argc, ...) {
va_list ap;
va_start(ap, argc);
for (int i = 0; i < argc; i++) {
printf("%d ", va_arg(ap, int));
}
printf("\n");
va_end(ap);
}
signed main() {
variad(7, 2, 3, 5);
}
arduino
#define arduino:: \
I------------------------------------------------------------------------\
I------------------------------------------------------------------------\
I \
I /$$$$$$ /$$ /$$ \
I /$$__ $$ | $$ |__/ \
I | $$ \ $$ /$$$$$$ /$$$$$$$ /$$ /$$ /$$ /$$$$$$$ /$$$$$$ \
I | $$$$$$$$ /$$__ $$ /$$__ $$| $$ | $$| $$| $$__ $$ /$$__ $$ \
I | $$__ $$| $$ \__/| $$ | $$| $$ | $$| $$| $$ \ $$| $$ \ $$ \
I | $$ | $$| $$ | $$ | $$| $$ | $$| $$| $$ | $$| $$ | $$ \
I | $$ | $$| $$ | $$$$$$$| $$$$$$/| $$| $$ | $$| $$$$$$/ \
I |__/ |__/|__/ \_______/ \______/ |__/|__/ |__/ \______/ \
I \
I------------------------------------------------------------------------\
I------------------------------------------------------------------------I
• "Ardurino Sketch"/"Ardurino Lang"
• C/C++ dialect
• supports many C++ features, but kept more minimalistic
• supports neither the C or C++ standard libraries
FILES: FILES:
ino : Ardurino Sketch file
Arduino: Arduino:
• preassembled micro controllers to computers
r3:
• USB-B
— ATmega328P micro-controller:
• 32 * 8 general purpose working register
• 16MHz
• 2KB SRAM
• 32KB FLASH
• 1KB EEPROM
Sketches: Sketches:
<sketch>/
├── <sketch>.ino
└── <...>
• ardurino programs/projects are called sketches
• their control abstraction is what justifies this convention
• each Arduino program must contain exactly one .ino file
with setup() and loop() definitions
• for sketches, function declarations are created for every
function definition directly at the top;
this means typedef return types and arguments are
getting nuked without warning or reason
• structure is otherwise retained (you may place .c files in your
sketch folder; the IDE will even recognize and compile them)
Variables: Variables:
C_Builtin_and_standard_types_available:
void
bool
(unsigned) char
short
(unsigned) int
(unsigned) long
size_t
float
double
• due to the memory and register constrains,
concrete type sizes are the minimum allowed by
the C standard { sizeof(int) == 2 };
they also seem not to expand to higher storage
when doing artimetrics(?!)
{ unsigned long i = 60 * 1000; }
New:
boolean : type alias for bool
byte : what you would expect
word : processor word; guaranteed to be >= 16 bits
String : char string class
Member_functions:
charAt(<int>)
compareTo(<String>)
concat(<constructor>)
c_str()
equals(<String>)
equalsIgnoreCase(<String>)
indexOf(<char|String>)
indexOf(<char|String>, <int>)
getBytes(<byte*>)remove(<int>) : delete from <int> to the end
remove(<int-from>, <int-n>) : remove <int-n> chars starting from <int-from>
replace(<String-what>, <String-with>) : replace all occurrences of <String-what> with <String-with>
reserve(<int>) : preemptively grow the internal buffer
substring(<int>)
substring(<int>, <int>)
toDouble()
toInt()
toFloat()
toLowerCase()
toDouble()
Constructors:
String()
String(<char*>)
String(<int>)
String(<int>, <base>)
Functions: Functions:
Setup:
void setup(void);
• run once on power up or reset
Loop:
void loop(void);
• there is no main; this is its "equivalent"
• never exits, its run continuously in a loop
Interupts: Interupts:
— interupt execution suspends the hardware clock,
affecting for example the following functions
• delay()
• millis()
• micros()
void cli(void) : "CLear Interupts"; suspend interupt detection
void sei(void) : "SEt Interupts"; restart interupt detection
void ISR(<override-r>) : "Interupt Service Routine"; interupt handler;
the desired handler is selected based on overloading
Overloader_macros:
PCI0_vect
PCI1_vect
PCI2_vect
Standard_libary: Standard_libary:
void tone(<pin>, <int-frequency>) : output square ware on <pin> of <int-frequency> until a corresponding call to noTone()
void tone(<pin>, <int-frequency>, <int-duration>) : output square ware on <pin> of <int-frequency> for <int-duration> milliseconds
void noTone(pin) : cancel squarewave initiated by tone() on <pin>
void delay(<int-miliseconds>)
int random(max_bound)
int random(min, max_bound)
unsigned long millis(void) : number of milliseconds since start; overflows after ~50 days
unsigned long micros(void) : number of microseconds since start; overflows after ~70 mins
int map(<int-input>, <int-fromLow>, <int-fromHigh>, <int-toLow>, <int-toHigh>)
class HardwareSerial
Member_functions:
being(<int data_rate_bps>) : initializes the interface
print(<...>)
println(<...>)
Builtin_Instances:
Serial
-----------------
LiquidCrystal.h
-----------------
class LiquidCrystal : represents an LCD display
○ state
— cursor
• position
• visibility
• text (WO)
• scroll direction
Constructors:
LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
Member_functions:
void begin(int cols, int rows) : required initialization finisher
void begin(int cols, int rows, CHARSIZE) : same as ABOVE, but with explicit CHARSIZE (see BELOW)
void setCursor(int col, int row) : move the cursor
void home() : == setCursor(0, 0)
void clear() : erase and home()
int write(?!)
int print(<...>)
int print(int, BASE)
void cursor() : show cursor
void noCursor() : hide cursor
void blink() : blink the cursor
void noDisplay() : turn of the screen; preserves state {cursor; text}
void display() : retore screen after noDisplay()
void scrollDisplayLeft() : scroll the diplayed text to the left by one
void scrollDisplayRight() : scroll the diplayed text to the left by one
void autoscroll() : turn on scrolling; each write shall push the
previous output to the scroll direction
void noAutoscroll() : turn off scrolling (see ABOVE)
void leftToRight() : set the scolling direction left-to-right
void rightToLeft() : set the scolling direction right-to-left
void createChar([0..7], byte*) : create custom character from <byte*>
with the ID [0..7],
which can be passed to write() for display;
<byte*> must be an array,
where each bit is interpreted as a bool;
the size of <byte*> is assumed from the CHARSIZE
passed to begin();
some displays may not support it at all
Enum:
CHARSIZE:
LCD_5x8DOTS
LCD_5x10DOTS
BASE:
BIN
DEC
OCT
HEX
holy_c
#define holy_c:: \
I----------------------------------------------------------\
I----------------------------------------------------------\
I \
I /$$ /$$ /$$ /$$$$$$ \
I | $$ | $$ | $$ /$$__ $$ \
I | $$ | $$ /$$$$$$ | $$ /$$ /$$ | $$ \__/ \
I | $$$$$$$$ /$$__ $$| $$| $$ | $$ | $$ \
I | $$__ $$| $$ \ $$| $$| $$ | $$ | $$ \
I | $$ | $$| $$ | $$| $$| $$ | $$ | $$ $$ \
I | $$ | $$| $$$$$$/| $$| $$$$$$$ | $$$$$$/ \
I |__/ |__/ \______/ |__/ \____ $$ \______/ \
I /$$ | $$ \
I | $$$$$$/ \
I \______/ \
I----------------------------------------------------------\
I----------------------------------------------------------I
• created by Saint Terrence Andrew Davis (Terry for short),
the developer behind God's 3th temple, TempleOS
• i tried documenting as close to the King's original as it made sense for cdd
• C89 features unmentioned are to be presumed to be untouched
Programs: Programs:
On_TempleOS:
• has a JIT capable compiler
hcc <file>+ : cross-platform Holy C compiler
https://github.com/Jamesbarford/holyc-lang
Types: Types:
• no typedef (use class)
• union-s do not require the union keyword
• no type checking (similar to B)
V0 : void, but ZERO size!
I8 : char
U8 : unsigned char
I16 : short
U16 : unsigned short
I32 : int
U32 : unsigned int
I64 : long
U64 : unsigned long
F64 : double
no F32 float.
Bit_access:
Literals:
'<char>+' : multi-char literal;
compiles to the char values being strongly packed
and without a NULL termination
{ 'ABC' -> 0x434241 }
Classes:
• single inheritance only
lastclass : ?!
Metadata:
format
data
Preprocessor: Preprocessor:
• no macro functions
• cant use <> with #include (use "")
#exe {} : ?!
Functions: Functions:
<flag> <returns> <name>(<args>) { <...> } : function definition
• functions with no args, or just default args can be called
without parentheses
{
Dir("*");
Dir();
Dir;
}
• function names do not decay to their addresses,
the address of operator (&) has to be used explicit-ly
Default_arguments:
• C++ style declarations
• dont have to be at the end
• an empty spot between commas will result in the default being used
{
U0 Test(I64 i=4, I64 j, I64 k=5) {
Print("%x %x %x\n", i, j, k);
}
Test(,3);
}
Builtin_wiring:
'<char>'; : sent to PutChars()
'' <char*> : sent to PutChars()
"<fmt>" <args>; : sent to Print()
"" <fmt*> <args> : sent to Print()
{
void DemoC(char drv, char * fmt, char * name, int age) {
printf("Hello World\n");
printf("%s age %d\n", name, age);
printf(fmt, name, age);
putchar(dry);
putchar('*');
}
V0 DemoHolyC(U8 drv, U8 * fmt, U8 * name, I64 age) {
"Hello World\n";
"%s age %d\n", name, age;
"" fmt, name, age;
'' dry;
'*';
}
}
Variadic_functions:
— variable arg count functions (...) can access their args with built-in
variables similar to 'this' in C++
I64 argc
I64 argv
Flags:
interupt : ?!
haserrcode : ?!
public : ?!
argpop : ?!
noargpop : ?!
Main:
• there is no main() function
• any code outside of functions gets executed upon start-up, in order
{
V0 Main() {
"Heyo World\n"
}
Main;
}
Operators: Operators:
• no ternary operator (operator?)
<base>`<power> : power operator
offset <member> : returns the offset of a member of a class;
designed after sizeof
Precedence:
` >> <<
* / %
&
^
|
+ -
< > <= =>
== !=
&&
^^
||
= <<= >>= *= /= &= |= ^= += -=
Logic: Logic:
• multiple logical statements can be combined into one