start ...

This commit is contained in:
2026-06-17 01:45:40 +03:00
commit 60a261f18c
9 changed files with 393 additions and 0 deletions

75
.gitignore vendored Normal file
View File

@@ -0,0 +1,75 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
CMakeLists.txt.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
build/

24
CMakeLists.txt Normal file
View File

@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.10.0)
project(snipplib VERSION 0.1.0 LANGUAGES CXX)
option(BUILD_EXAMPLES "Build examples" ON)
set(LIB_HEADERS include/snipplib/concepts/snplib_concepts.h
include/snipplib/utils/snplib_hash.h
include/snipplib/utils/snplib_utils.h
include/snipplib/hmap/snplib_hmap.h)
add_library(${PROJECT_NAME} INTERFACE ${LIB_HEADERS})
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_23)
target_include_directories(
${PROJECT_NAME}
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:include/${PROJECT_NAME}>"
)
set(EXAM_STRING str_exam)
add_executable(${EXAM_STRING} examples/str_exam.cpp)
target_link_libraries(${EXAM_STRING} ${PROJECT_NAME})

29
examples/str_exam.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <print>
// #include "../utils/snplib_string.h"
// #include "../include/snipplib/snplib_string.h"
#include <snipplib/utils/snplib_string.h>
using namespace snplib;
int main()
{
std::string si = " dewf wek e lwekjflkj ";
auto s = snplib_trim_spaces(si);
std::println("s = '{}'", s);
auto sv = snplib_trim_spaces_as_view(si, TrimType::TRIM_LEFT);
std::println("sv(TrimType::TRIM_LEFT) = '{}'", sv);
sv = snplib_trim_spaces_as_view(si, TrimType::TRIM_RIGHT);
std::println("sv(TrimType::TRIM_RIGHT) = '{}'", sv);
sv = snplib_trim_spaces_as_view(si, TrimType::TRIM_BOTH);
std::println("sv(TrimType::TRIM_BOTH) = '{}'", sv);
return 0;
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include <concepts>
#include <ranges>
namespace snplib {
// type T is hashable
template <typename T>
concept snplib_hashable_c = requires(T t) {
{ std::hash<T>(t) } -> std::convertible_to<size_t>;
};
template <typename T, typename CharT = char>
concept snplib_char_range_c = std::ranges::range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
template <typename T, typename CharT = char>
concept snplib_input_char_range_c = std::ranges::input_range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
template <typename T, typename CharT = char>
concept snplib_output_char_range_c = std::ranges::output_range<T, CharT>;
template <typename T, typename CharT = char>
concept snplib_char_view_c = std::ranges::view<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
} // end of snplib namespace

View File

@@ -0,0 +1,67 @@
#pragma once
#include "../concepts/snplib_concepts.h"
#include "../utils/snplib_hash.h"
namespace snplib {
template<snplib_hashable_c KeyT>
class HeterogenMap {
protected:
// actuall map key type
typedef std::pair<const HeterogenMap*, KeyT> key_t;
struct KeyHash {
static size_t operator()(key_t key) {
size_t hash = 0;
snplib_hash_combine(hash, key.first, , key.second);
return hash;
}
}
template <typename VT>
inline static std::unordered_map<key_t, VT, KeyHash> _umap{};
std::vector<std::function<void()>> _clearFunc{};
public:
enum Error : {ERROR_OK, ERROR_NO_ELEM};
HeterogenMap() = default;
~HeterogenMap() {
for (auto &func: _clearFunc) {
func();
}
}
template<typename VT>
size_t push(KeyT const& key, VT&& value) {
auto it = _umap<std::decay_t<VT>>.emplace(std::make_pair(this, key), std::forward<VT>(value));
if (it.second){
_clearFunc.empace_back([it=it.first]() { _umap<std::decay_t<VT>>.erase(it); });
} // here the element already exists (just update its value)
return _clearFunc.size();
}
template<typename VT, typename ...CtorArgTs>
size_t emplace(KeyT const&, CtorArgTs&& ...args) {
return push(key, VT(std::forward<CtorArgTs>(args)...));
}
template<typename VT>
std::expected<VT, Error> get(KeyT const& key) const {
if (auto it = _umap<VT>.find(std::make_pair(this, key)); it != _umap<VT>.end()) {
return it->second;
}
return std::unexpected(Error::ERROR_NO_ELEM);
}
};
} // end of namespace snplib

View File

@@ -0,0 +1,86 @@
#pragma once
#include "../concepts/snplib_concepts.h"
#include <iterator>
namespace snplib {
template <snplib_input_char_range_c R>
static constexpr size_t FNV1aHash(const R& r)
{
static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "ONLY FOR 32 or 64-bit size_t!!!");
size_t hash = 0, prime = 0;
if constexpr (sizeof(size_t) == 8) { // 64-bit
prime = 1099511628211UL;
hash = 14695981039346656037UL;
} else if constexpr (sizeof(size_t) == 4) { // 32-bit
prime = 16777619;
hash = 2166136261;
}
for (const char& ch : r) {
hash ^= ch;
hash *= prime;
}
return hash;
}
static constexpr size_t FNV1aHash(std::forward_iterator auto begin, std::sentinel_for<decltype(begin)> auto end)
requires std::same_as<std::remove_cv_t<std::iter_value_t<decltype(begin)>>, char>
{
static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "ONLY FOR 32 or 64-bit size_t!!!");
size_t hash = 0, prime = 0;
if constexpr (sizeof(size_t) == 8) { // 64-bit
prime = 1099511628211UL;
hash = 14695981039346656037UL;
} else if constexpr (sizeof(size_t) == 4) { // 32-bit
prime = 16777619;
hash = 2166136261;
}
for (auto it = begin; it != end; ++it) {
hash ^= *it;
hash *= prime;
}
return hash;
}
// Boost implementation of hash combining
template <snplib_hashable_c T, snplib_hashable_c ...Ts>
static constexpr void snplib_hash_combine(std::size_t& seed, const T& v, Ts&& ... vs) {
static constexpr auto digits = std::numeric_limits<std::size_t>::digits;
static_assert(digits == 64 || digits == 32, "Unsupported 'size_t' type size!");
if constexpr (digits == 64) {
std::size_t x = seed + 0x9e3779b9 + std::hash<T>()(v);
const std::size_t m = 0xe9846af9b1a615d;
x ^= x >> 32;
x *= m;
x ^= x >> 32;
x *= m;
x ^= x >> 28;
seed = x;
}
else { // 32-bits
std::size_t x = seed + 0x9e3779b9 + std::hash<T>()(v);
const std::size_t m1 = 0x21f0aaad;
const std::size_t m2 = 0x735a2d97;
x ^= x >> 16;
x *= m1;
x ^= x >> 15;
x *= m2;
x ^= x >> 15;
seed = x;
}
if constexpr (sizeof...(Ts)) {
snplib_hash_combine(seed, std::forward<Ts>(vs)...);
}
}
} // end of snplib namespace

View File

@@ -0,0 +1,77 @@
#pragma once
#include <algorithm>
#include <string>
#include "../concepts/snplib_concepts.h"
namespace snplib {
constexpr static bool snplib_is_space(char in) noexcept
{
static constexpr auto ws = {' ', '\t', '\n', '\v', '\r', '\f'};
return std::ranges::any_of(ws, [in](auto p) { return p == in; });
};
enum class TrimType { TRIM_LEFT, TRIM_RIGHT, TRIM_BOTH };
template <snplib_output_char_range_c OR, snplib_input_char_range_c R, typename IsSpaceFuncT = decltype(snplib_is_space)>
constexpr static OR snplib_trim_spaces(R&& r, TrimType type = TrimType::TRIM_BOTH, IsSpaceFuncT&& is_space_func = snplib_is_space)
{
if (type == TrimType::TRIM_LEFT) {
auto res = r | std::views::drop_while(is_space_func);
return OR{res.begin(), res.end()};
} else if (type == TrimType::TRIM_RIGHT) {
auto res = r | std::views::reverse | std::views::drop_while(is_space_func) |
std::views::reverse;
return OR{res.begin(), res.end()};
} else if (type == TrimType::TRIM_BOTH) {
auto res = r | std::views::drop_while(is_space_func) | std::views::reverse | std::views::drop_while(is_space_func) |
std::views::reverse;
return OR{res.begin(), res.end()};
}
return OR{};
}
template <snplib_input_char_range_c R, typename IsSpaceFuncT = decltype(snplib_is_space)>
constexpr static std::string snplib_trim_spaces(R&& r, TrimType type = TrimType::TRIM_BOTH, IsSpaceFuncT&& is_space_func = snplib_is_space)
{
return snplib_trim_spaces<std::string>(std::forward<R>(r), type, std::forward<IsSpaceFuncT>(is_space_func));
}
template <snplib_input_char_range_c R, typename IsSpaceFuncT = decltype(snplib_is_space)>
constexpr static std::string_view snplib_trim_spaces_as_view(R&& r, TrimType type = TrimType::TRIM_BOTH, IsSpaceFuncT&& is_space_func = snplib_is_space)
requires std::ranges::contiguous_range<R>
{
auto end = std::forward<R>(r).end();
auto f1 = std::forward<R>(r).begin();
if (type != TrimType::TRIM_RIGHT) {
// look for the first non-space symbol
f1 = std::ranges::find_if_not(std::forward<R>(r), std::forward<IsSpaceFuncT>(is_space_func));
if (f1 == end) { // all are spaces!
return std::string_view();
}
}
auto f2 = end;
if (type != TrimType::TRIM_LEFT) {
auto f3 = f1;
do {
f2 = std::ranges::find_if(++f3, end, std::forward<IsSpaceFuncT>(is_space_func));
if (f2 == end)
break;
f3 = std::ranges::find_if_not(f2 + 1, end, std::forward<IsSpaceFuncT>(is_space_func));
} while (f3 != end);
}
return std::string_view(f1, f2);
}
} // end of snplib namespace

View File

@@ -0,0 +1,2 @@
#pragma once

5
snipplib.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include <iostream>
void say_hello(){
std::cout << "Hello, from snipplib!\n";
}