My C++ sensible prelude.
at main 3.6 kB view raw
1/* ======================================================================== 2 * 3 * Filename: prelude.hpp 4 * Description: C++ sensible prelude - Declarations 5 * Author: Diego A. Estrada Rivera 6 * Version: 0.0.4 7 * 8 * ======================================================================== */ 9#pragma once 10 11/* === Numeric Types === */ 12#include <cstdint> 13#include <limits.h> 14using Size = std::size_t; 15 16/* Floating Point */ 17// brain floating point 18// see https://en.wikipedia.org/wiki/Bfloat16_floating-point_format 19typedef __bf16 BF16; 20typedef _Float16 F16; 21typedef float F32; 22static_assert(sizeof(F32) * CHAR_BIT == 32); // 23typedef double F64; 24static_assert(sizeof(F64) * CHAR_BIT == 64); 25#if __float80_max < __float128_max 26 typedef __float80 F80; // sometimes is the same as F128 27#endif 28typedef __float128 F128; 29 30// decimal floating points 31// see decimal32/64/128 in https://en.wikipedia.org/wiki/IEEE_754 32//typedef float __attribute__((mode(SD))) D32; 33//typedef float __attribute__((mode(DD))) D64; 34//typedef float __attribute__((mode(TD))) D128; 35 36/* Integer */ 37typedef uint8_t U8; 38typedef uint16_t U16; 39typedef uint32_t U32; 40typedef uint64_t U64; 41typedef __uint128_t U128; 42 43typedef int8_t I8; 44typedef int16_t I16; 45typedef int32_t I32; 46typedef int64_t I64; 47typedef __int128_t I128; 48 49// generic Integer type 50typedef int_fast32_t Int; 51 52/* === Other Types === */ 53typedef bool Bool; 54typedef char Char; 55typedef const char * CString; 56 57#include <vector> 58template <typename T> using Vector = std::vector<T>; 59 60#include <string> 61using String = std::string; 62using namespace std::string_literals; 63 64// Unit type 65enum class Unit { unit }; 66 67// Void type 68enum class Void {}; 69 70// Pointer types 71template <typename T> using Ref = T&; 72 73template <typename T> using Handle = T*; 74 75/* === Keywords === */ 76template <class T> 77concept Auto = true; 78#define let auto const 79#define var auto 80 81#define fn [[nodiscard, gnu::const]] auto 82#define proc [[nodiscard]] auto 83 84/* This is included as a static member variable of <tuple>. 85 * However, there is no way to bring the std::ignore namespace static variable 86 * into the current scope. This is a way to do that. 87 * https://en.cppreference.com/w/cpp/utility/tuple/ignore 88 */ 89namespace detail { 90struct ignore_t { 91 template <typename T> 92 constexpr // required since C++14 93 void 94 operator = (T&&) const noexcept {} 95}; 96} // namespace detail 97inline constinit const detail::ignore_t ignore; // changed to constinit 98 99// manage tuples better 100#define fst std::get<0> 101#define snd std::get<1> 102#define thr std::get<2> 103 104/* === Miscellaneous Functions */ 105#include <concepts> 106#include <type_traits> 107#include <unordered_map> 108 109// key_hash comes from this stack overflow: https://stackoverflow.com/questions/20834838/using-tuple-in-unordered-map 110// this is necessary so we can index the hashmap using tuples 111template <class... Types> struct n_tuple_key_hash { 112 fn operator()(std::tuple<Types...> const& args) const noexcept -> size_t 113 { 114 return std::apply([](var... t) { return (t ^ ...); }, args); 115 } 116}; 117 118template <class... Types> fn memoize(let&& op) noexcept 119{ 120 static var mp = 121 std::unordered_map<std::tuple<Types...>, 122 std::invoke_result_t<decltype(op), Types...>, 123 n_tuple_key_hash<Types...>>(); 124 125 return [&](Types... types) noexcept { 126 let& t = std::make_tuple(types...); 127 return mp.contains(t) ? mp.at(t) : mp[t] = op(types...); 128 }; 129} 130 131/* Sensible IO */ 132#include <iostream> 133proc getLine() noexcept -> String; 134 135proc getChar() noexcept -> Char; 136 137proc print(const std::string_view& f) noexcept -> Unit; 138 139proc println(const std::string_view& f) noexcept -> Unit;