Skip to content
Snippets Groups Projects
Commit 01aeacfd authored by Recolic's avatar Recolic :house_with_garden:
Browse files

.

parent ba28abb4
No related branches found
No related tags found
No related merge requests found
Pipeline #1042 failed with stage
in 8 seconds
# Warning: This IS NOT single-file rlib header
This directory contains useful standalone headers, for various c/cpp debugging.
They **are not** part of rlib, and they are intended for situations while not practical to include a complete rlib.
> DO NOT expect too much for these low-quality toys.
|Header|Note|
|------|----|
|rdebug.h|Minimal C helper to print debug output|
|c-with-class.h|Old fashioned trick used in some C homeworks|
|rlib.min.hpp|Minimal io/string helper for solving OJ questions, or writing POC program|
File moved
/*
Usage: Put this in /usr/bin/stdio.h
#if __has_include("/home/recolic/sh/rdebug.h")
#include "/home/recolic/sh/rdebug.h"
#endif
DO NOT modify this file directly. Please commit any change to ~/sh/rdebug.h
version: 1.0.3
changelog: 1.0.3: add print_time for c
*/
#ifndef RDB__H
#define RDB__H
#include <execinfo.h>
#include <stdio.h>
#include <stddef.h>
#define RDEBUG(fmt, ...) fprintf(stderr, "RDEBUG: %s:%d(%s), " #fmt "\n" , __FILE__, __LINE__, __func__ __VA_OPT__(,) __VA_ARGS__ );
#ifdef __cplusplus
#include <ostream>
#include <iomanip>
#include <cstdint>
[[maybe_unused]] inline
#else
__attribute__((unused)) static
#endif
void printbt() {
void *array[32];
int size;
// get void*'s for all entries on the stack
size = backtrace(array, 32);
// print out all the frames to stderr
backtrace_symbols_fd(array, size, 2);
}
#ifdef __cplusplus
template <typename CharT>
[[maybe_unused]] inline void print_buf(std::ostream& out, const char *title, const CharT *data, size_t dataLen) {
out << title << std::endl;
out << std::setfill('0');
for(size_t i = 0; i < dataLen; ++i) {
out << std::hex << std::setw(2) << (0x000000ff & (int32_t)(((const char *)data)[i]));
// format
out << (((i + 1) % 16 == 0) ? "\n" : " ");
}
out << std::endl;
}
inline void print_buf(std::ostream& out, const char *title, const std::string &data) {
return print_buf(out, title, data.data(), data.size());
}
#else
__attribute__((unused)) static void print_buf(FILE *stream, const char *title, const unsigned char *buf, size_t buf_len)
{
size_t i = 0;
fprintf(stream, "%s\n", title);
for(i = 0; i < buf_len; ++i)
fprintf(stream, "%02X%s", buf[i],
( i + 1 ) % 16 == 0 ? "\r\n" : " " );
fprintf(stream, "\n");
}
#include <time.h>
__attribute__((unused)) static void print_time(FILE *stream) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
// struct tm *my_tm = localtime(&ts.tv_sec);
fprintf(stream, "%lu.%lu\n", ts.tv_sec, ts.tv_nsec);
}
#endif
#endif
/*
*
* string.hpp: string process utility.
* Recolic Keghart <root@recolic.net>
* MIT License
*
* Minified version: works on C++11.
*
*/
#ifndef R_STRING_HPP
#define R_STRING_HPP
#include <vector>
#include <string>
#include <stdexcept>
namespace rlib {
class string : public std::string {
public:
using std::string::string;
string() : std::string() {}
string(const std::string &s) : std::string(s) {}
string(std::string &&s) : std::string(std::forward<std::string>(s)) {}
private:
template <typename T> struct as_helper {};
template <typename T>
T as(as_helper<T>) const {
if(empty()) return T();
return T(*this);
}
const char *as(as_helper<const char *>) const {
return this->c_str();
}
std::string as(as_helper<std::string>) const {
return std::move(*this);
}
rlib::string as(as_helper<rlib::string>) const {
return std::move(*this);
}
char as(as_helper<char>) const {
if(size() > 1)
throw std::invalid_argument("Can not convert rlib::string to char: size() > 1.");
return size() == 0 ? '\0' : *cbegin();
}
// unsigned-char conflicts with uint8_t. I'll regard it as uint8_t. ("8".as<unsigned char> == 8)
//unsigned char as(as_helper<unsigned char>) const {
// return static_cast<unsigned char>(as<char>());
//}
bool as(as_helper<bool>) const {
if(*this == "true") {
return true;
}
else if(*this == "false") {
return false;
}
// Nothing is slower than throw(); Just test more cases...
else if(*this == "1" || *this == "True" || *this == "TRUE") {
return true;
}
else if(*this == "0" || *this == "False" || *this == "FALSE") {
return false;
}
throw std::invalid_argument("Can not convert rlib::string to bool. Not matching any template.");
}
#define RLIB_IMPL_GEN_AS_NUMERIC(type, std_conv) \
type as(as_helper<type>) const { \
if(empty()) return 0; \
return std::std_conv(*this); \
}
RLIB_IMPL_GEN_AS_NUMERIC(int, stoi)
RLIB_IMPL_GEN_AS_NUMERIC(long, stol)
RLIB_IMPL_GEN_AS_NUMERIC(unsigned long, stoul)
RLIB_IMPL_GEN_AS_NUMERIC(unsigned long long, stoull)
RLIB_IMPL_GEN_AS_NUMERIC(long long, stoll)
RLIB_IMPL_GEN_AS_NUMERIC(float, stof)
RLIB_IMPL_GEN_AS_NUMERIC(double, stod)
RLIB_IMPL_GEN_AS_NUMERIC(long double, stold)
#define RLIB_IMPL_GEN_AS_ALIAS(new_type, old_type) \
new_type as(as_helper<new_type>) const { \
return static_cast<new_type>(as<old_type>()); \
}
RLIB_IMPL_GEN_AS_ALIAS(unsigned int, unsigned long)
RLIB_IMPL_GEN_AS_ALIAS(unsigned short, unsigned long)
RLIB_IMPL_GEN_AS_ALIAS(uint8_t, unsigned long)
RLIB_IMPL_GEN_AS_ALIAS(short, int)
RLIB_IMPL_GEN_AS_ALIAS(int8_t, int)
public:
template <typename T>
T as() const {
return std::forward<T>(as(as_helper<T>()));
}
template <typename T>
std::vector<T> split_as(const char &divider = ' ') const {
const string &toSplit = *this;
std::vector<T> buf;
size_t curr = 0, prev = 0;
while((curr = toSplit.find(divider, curr)) != std::string::npos) {
buf.push_back(string(toSplit.substr(prev, curr - prev)).as<T>());
++curr; // skip divider
prev = curr;
}
buf.push_back(string(toSplit.substr(prev)).as<T>());
return std::move(buf);
}
template <typename T>
std::vector<T> split_as(const std::string &divider) const {
const string &toSplit = *this;
std::vector<T> buf;
size_t curr = 0, prev = 0;
while((curr = toSplit.find(divider, curr)) != std::string::npos) {
buf.push_back(string(toSplit.substr(prev, curr - prev)).as<T>());
curr += divider.size(); // skip divider
prev = curr;
}
buf.push_back(string(toSplit.substr(prev)).as<T>());
return std::move(buf);
}
template <class ForwardIterable>
string &join(const ForwardIterable &buffer) {
join(buffer.cbegin(), buffer.cend());
return *this;
}
template <class ForwardIterator>
string &join(ForwardIterator begin, ForwardIterator end) {
const string &toJoin = *this;
std::string result;
for(ForwardIterator iter = begin; iter != end; ++iter) {
if(iter != begin)
result += toJoin;
result += *iter;
}
return operator=(std::move(result));
}
string &strip() {
strip(" \t\r\n");
return *this;
}
template <typename CharOrStringOrView>
string &strip(const CharOrStringOrView &stripped) {
size_t len = size();
size_t begin = find_first_not_of(stripped);
if(begin == std::string::npos) {
clear();
return *this;
}
size_t end = find_last_not_of(stripped);
erase(end + 1, len - end - 1);
erase(0, begin);
return *this;
}
string &replace(const std::string &from, const std::string &to) {
size_t _;
replace(from, to, _);
return *this;
}
string &replace(const std::string &from, const std::string &to, size_t &out_times) {
if(from.empty())
return *this;
size_t start_pos = 0;
size_t times = 0;
while((start_pos = find(from, start_pos)) != std::string::npos)
{
++times;
this->std::string::replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
out_times = times;
return *this;
}
string &replace_once(const std::string &from, const std::string &to) {
bool _;
replace_once(from, to, _);
return *this;
}
string &replace_once(const std::string &from, const std::string &to, bool &out_replaced) {
size_t start_pos = find(from);
if(start_pos == std::string::npos) {
out_replaced = false;
}
else {
this->std::string::replace(start_pos, from.length(), to);
out_replaced = true;
}
return *this;
}
};
}
#endif
#include <iostream>
#include <string>
namespace rlib {
// This is my own hand-written library. I'm making it easy to use it directly.
inline rlib::string scanln(std::istream &is = std::cin, char delimiter = '\n') noexcept {
std::string line;
std::getline(is, line, delimiter);
return (line); // RVO
}
template <typename PrintFinalT>
void print(PrintFinalT reqArg)
{
std::cout << reqArg;
}
template <typename Required, typename... Optional>
void print(Required reqArgs, Optional... optiArgs)
{
std::cout << reqArgs << ' ';
print(optiArgs ...);
}
template <typename... Optional>
void println(Optional... optiArgs)
{
print(optiArgs ...);
println();
}
template <>
inline void println()
{
//std::cout << rlib::endl;
std::cout << std::endl;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment