parent
6e741638a9
commit
fc2dc6cac1
@ -0,0 +1,31 @@ |
|||||||
|
# ---> Vim |
||||||
|
# Swap |
||||||
|
[._]*.s[a-v][a-z] |
||||||
|
!*.svg # comment out if you don't need vector files |
||||||
|
[._]*.sw[a-p] |
||||||
|
[._]s[a-rt-v][a-z] |
||||||
|
[._]ss[a-gi-z] |
||||||
|
[._]sw[a-p] |
||||||
|
|
||||||
|
# Session |
||||||
|
Session.vim |
||||||
|
Sessionx.vim |
||||||
|
|
||||||
|
# Temporary |
||||||
|
.netrwhist |
||||||
|
*~ |
||||||
|
# Auto-generated tag files |
||||||
|
tags |
||||||
|
# Persistent undo |
||||||
|
[._]*.un~ |
||||||
|
|
||||||
|
subprojects |
||||||
|
builddir |
||||||
|
ttassets |
||||||
|
backup |
||||||
|
*.exe |
||||||
|
*.dll |
||||||
|
*.world |
||||||
|
coverage |
||||||
|
coverage/* |
||||||
|
.venv |
||||||
@ -0,0 +1 @@ |
|||||||
|
set makeprg=meson\ compile\ -C\ . |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
all: build test |
||||||
|
|
||||||
|
reset: |
||||||
|
ifeq '$(OS)' 'Windows_NT' |
||||||
|
powershell -executionpolicy bypass .\scripts\reset_build.ps1
|
||||||
|
else |
||||||
|
sh -x ./scripts/reset_build.sh
|
||||||
|
endif |
||||||
|
|
||||||
|
build: |
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
release_build: |
||||||
|
meson --wipe builddir -Db_ndebug=true --buildtype release
|
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
debug_build: |
||||||
|
meson setup --wipe builddir -Db_ndebug=true --buildtype debugoptimized
|
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
test: build |
||||||
|
./builddir/fuc2it
|
||||||
|
|
||||||
|
run: build test |
||||||
|
ifeq '$(OS)' 'Windows_NT' |
||||||
|
powershell "cp ./builddir/fuc2it.exe ."
|
||||||
|
./fuc2it
|
||||||
|
else |
||||||
|
./builddir/fuc2it
|
||||||
|
endif |
||||||
|
|
||||||
|
debug: build |
||||||
|
gdb --nx -x .gdbinit --ex run --args builddir/fuc2it
|
||||||
|
|
||||||
|
debug_run: build |
||||||
|
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/fuc2it
|
||||||
|
|
||||||
|
clean: |
||||||
|
meson compile --clean -C builddir
|
||||||
|
|
||||||
|
debug_test: build |
||||||
|
gdb --nx -x .gdbinit --ex run --args builddir/fuc2it -e
|
||||||
@ -0,0 +1,57 @@ |
|||||||
|
#pragma once |
||||||
|
#include <source_location> |
||||||
|
#include <string> |
||||||
|
#include <stdexcept> |
||||||
|
#include <iostream> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <functional> |
||||||
|
|
||||||
|
namespace fuc2 { |
||||||
|
using Func = std::function<void()>; |
||||||
|
using Case = std::pair<std::string, Func>; |
||||||
|
|
||||||
|
struct Options { |
||||||
|
bool fail_fast; |
||||||
|
}; |
||||||
|
|
||||||
|
struct Set { |
||||||
|
std::string name; |
||||||
|
Options options; |
||||||
|
std::vector<Case> tests; |
||||||
|
std::source_location location = std::source_location::current(); |
||||||
|
}; |
||||||
|
|
||||||
|
std::string craft_error( |
||||||
|
const std::string& type, |
||||||
|
const std::string& test, |
||||||
|
const std::string &message, |
||||||
|
const std::source_location location, |
||||||
|
const std::source_location test_sig = |
||||||
|
std::source_location::current()); |
||||||
|
|
||||||
|
void CHECK(bool test, const std::string &message="", |
||||||
|
const std::source_location location = std::source_location::current()); |
||||||
|
|
||||||
|
void EQUAL(auto v1, auto v2, const std::string &message="", |
||||||
|
const std::source_location location = std::source_location::current()) |
||||||
|
{ |
||||||
|
if(v1 != v2) { |
||||||
|
auto test_value = fmt::format("{} != {}", v1, v2); |
||||||
|
throw std::runtime_error(craft_error("EQUAL", test_value, message, location)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void NOT_EQUAL(auto v1, auto v2, const std::string &message="", |
||||||
|
const std::source_location location = std::source_location::current()) |
||||||
|
{ |
||||||
|
if(v1 == v2) { |
||||||
|
auto test_value = fmt::format("{} == {}", v1, v2); |
||||||
|
throw std::runtime_error(craft_error("NOT_EQUAL", test_value, message, location)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void BLOWS_UP(std::function<void()> cb, const std::string &message, |
||||||
|
const std::source_location location = std::source_location::current()); |
||||||
|
|
||||||
|
int run(const Set& test_set); |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
project('fuc2', 'cpp', |
||||||
|
version: '0.1.0', |
||||||
|
default_options: [ |
||||||
|
'cpp_std=c++23', |
||||||
|
'cpp_args=-D_GLIBCXX_DEBUG=1 -D_GLIBCXX_DEBUG_PEDANTIC=1', |
||||||
|
]) |
||||||
|
|
||||||
|
# use this for common options only for our executables |
||||||
|
cpp_args=[ |
||||||
|
'-Wno-unused-parameter', |
||||||
|
'-Wno-unused-function', |
||||||
|
'-Wno-unused-variable', |
||||||
|
'-Wno-unused-but-set-variable', |
||||||
|
'-Wno-deprecated-declarations', |
||||||
|
] |
||||||
|
link_args=[] |
||||||
|
# these are passed as override_defaults |
||||||
|
exe_defaults = [ 'warning_level=2', 'werror=false'] |
||||||
|
|
||||||
|
fmt = subproject('fmt').get_variable('fmt_dep') |
||||||
|
|
||||||
|
dependencies = [fmt] |
||||||
|
|
||||||
|
sources = [ |
||||||
|
'src/fuc2.cpp', |
||||||
|
] |
||||||
|
|
||||||
|
fuc2_includes = include_directories('include') |
||||||
|
|
||||||
|
fuc2_lib = static_library('fuc2', |
||||||
|
sources, |
||||||
|
pic: true, |
||||||
|
cpp_args: cpp_args, |
||||||
|
include_directories: fuc2_includes, |
||||||
|
override_options: exe_defaults, |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
fuc2_dep = declare_dependency( |
||||||
|
link_with: fuc2_lib, |
||||||
|
include_directories: fuc2_includes) |
||||||
|
|
||||||
|
executable('fuc2it', [ |
||||||
|
'tests/sample1.cpp', |
||||||
|
], |
||||||
|
cpp_args: cpp_args, |
||||||
|
link_args: link_args, |
||||||
|
override_options: exe_defaults, |
||||||
|
include_directories: fuc2_includes, |
||||||
|
link_with: [fuc2_lib], |
||||||
|
dependencies: dependencies) |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
mv .\subprojects\packagecache . |
||||||
|
rm -recurse -force .\subprojects\,.\builddir\ |
||||||
|
mkdir subprojects |
||||||
|
mv .\packagecache .\subprojects\ |
||||||
|
mkdir builddir |
||||||
|
cp wraps\*.wrap subprojects\ |
||||||
|
meson setup --default-library=static --prefer-static builddir |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
|
||||||
|
mv -f ./subprojects/packagecache . |
||||||
|
rm -rf subprojects builddir |
||||||
|
mkdir subprojects |
||||||
|
mv -f packagecache ./subprojects/ && true |
||||||
|
mkdir builddir |
||||||
|
cp wraps/*.wrap subprojects/ |
||||||
|
# on OSX you can't do this with static |
||||||
|
meson setup --default-library=static --prefer-static builddir |
||||||
@ -0,0 +1,94 @@ |
|||||||
|
#include <source_location> |
||||||
|
#include <string> |
||||||
|
#include <stdexcept> |
||||||
|
#include <iostream> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include "fuc2.hpp" |
||||||
|
|
||||||
|
namespace fuc2 { |
||||||
|
std::string craft_error( |
||||||
|
const std::string& type, |
||||||
|
const std::string& test, |
||||||
|
const std::string &message, |
||||||
|
const std::source_location location, |
||||||
|
const std::source_location test_sig) |
||||||
|
{ |
||||||
|
return fmt::format( |
||||||
|
"{} {}\n" // type message
|
||||||
|
" LOCATION: {}:{}:{}\n" // file:line:func
|
||||||
|
" TEST: {}\n" // test
|
||||||
|
" CALL: {}\n", // call
|
||||||
|
type, |
||||||
|
message, |
||||||
|
location.file_name(), |
||||||
|
location.line(), |
||||||
|
location.function_name(), |
||||||
|
test, |
||||||
|
test_sig.function_name()); |
||||||
|
} |
||||||
|
|
||||||
|
void CHECK(bool test, const std::string &message, const std::source_location location) |
||||||
|
{ |
||||||
|
if(!test) { |
||||||
|
auto test_value = fmt::format("{} != true", test); |
||||||
|
throw std::runtime_error( |
||||||
|
craft_error("CHECK", test_value, message, location)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void BLOWS_UP(std::function<void()> cb, const std::string &message, const std::source_location location) { |
||||||
|
bool it_failed = false; |
||||||
|
|
||||||
|
try { |
||||||
|
cb(); |
||||||
|
} catch(const std::exception& err) { |
||||||
|
// do it this way because I think an optimizer would remove this if empty
|
||||||
|
it_failed = true; |
||||||
|
} |
||||||
|
|
||||||
|
if(!it_failed) { |
||||||
|
throw std::runtime_error(craft_error("BLOWSUP", "", message, location)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int run(const Set& test_set) { |
||||||
|
int fail_count = 0; |
||||||
|
std::vector<std::string> errors; |
||||||
|
|
||||||
|
fmt::println("################# {} \"{}\" ###############", |
||||||
|
test_set.location.file_name(), test_set.name); |
||||||
|
|
||||||
|
for(const auto& [name, test] : test_set.tests) { |
||||||
|
bool did_fail = false; |
||||||
|
fmt::println("----------- START {}", name); |
||||||
|
|
||||||
|
try { |
||||||
|
test(); |
||||||
|
} catch(const std::exception& e) { |
||||||
|
fail_count++; |
||||||
|
did_fail = true; |
||||||
|
fmt::println("🚨 FAIL! {}", e.what()); |
||||||
|
errors.push_back(e.what()); |
||||||
|
|
||||||
|
if(test_set.options.fail_fast) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
std::string pass_fail = did_fail ? "🔴" : "🟢"; |
||||||
|
fmt::println("{} {}\n==========", pass_fail, name); |
||||||
|
} |
||||||
|
|
||||||
|
if(fail_count > 0) { |
||||||
|
fmt::println("🚨 FAIL COUNT: {}", fail_count); |
||||||
|
|
||||||
|
for(auto& msg : errors) { |
||||||
|
fmt::println("---------\n{}", msg); |
||||||
|
} |
||||||
|
} else { |
||||||
|
fmt::println("👍 ALL PASS"); |
||||||
|
} |
||||||
|
|
||||||
|
return fail_count; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
#include <fmt/core.h> |
||||||
|
#include <deque> |
||||||
|
#include <string> |
||||||
|
#include <fuc2.hpp> |
||||||
|
|
||||||
|
using namespace fuc2; |
||||||
|
|
||||||
|
void test_push_pop_back() { |
||||||
|
std::deque<int> ages; |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.push_back(i * 34); |
||||||
|
} |
||||||
|
|
||||||
|
CHECK(ages.size() == 5, "wrong count"); |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.pop_back(); |
||||||
|
fmt::println("count: {}", ages.size()); |
||||||
|
} |
||||||
|
|
||||||
|
EQUAL(ages.size(), size_t(0), "wrong count"); |
||||||
|
NOT_EQUAL(ages.size(), size_t(5), "wrong count"); |
||||||
|
} |
||||||
|
|
||||||
|
void test_push_pop_front() { |
||||||
|
std::deque<float> ages; |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.push_front(i * 34); |
||||||
|
} |
||||||
|
|
||||||
|
CHECK(ages.size() == 5, "wrong count"); |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.pop_front(); |
||||||
|
fmt::println("count: {}", ages.size()); |
||||||
|
} |
||||||
|
|
||||||
|
NOT_EQUAL(ages.size(), size_t(0), "wrong count"); |
||||||
|
} |
||||||
|
|
||||||
|
void test_push_blows_up() { |
||||||
|
std::deque<float> ages; |
||||||
|
|
||||||
|
auto runner = [&]() { |
||||||
|
// uncomment this to see how the C++ stdlib sabotages you
|
||||||
|
// ages.pop_front();
|
||||||
|
|
||||||
|
ages.at(10); |
||||||
|
}; |
||||||
|
|
||||||
|
BLOWS_UP(runner, "pop_front empty should crash"); |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char* argv[]) { |
||||||
|
return run({ |
||||||
|
.name="std::deque basic operations", |
||||||
|
.options={ .fail_fast=false }, |
||||||
|
.tests={ |
||||||
|
{"push_pop_back", test_push_pop_back}, |
||||||
|
{"push_pop_front", test_push_pop_front}, |
||||||
|
{"push_blows_up", test_push_blows_up}, |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
#include <fmt/core.h> |
||||||
|
#include <deque> |
||||||
|
#include <string> |
||||||
|
#include <fuc2.hpp> |
||||||
|
|
||||||
|
using namespace fuc2; |
||||||
|
|
||||||
|
void test_push_pop_back() { |
||||||
|
std::deque<int> ages; |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.push_back(i * 34); |
||||||
|
} |
||||||
|
|
||||||
|
CHECK(ages.size() == 5, "wrong count"); |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.pop_back(); |
||||||
|
fmt::println("count: {}", ages.size()); |
||||||
|
} |
||||||
|
|
||||||
|
EQUAL(ages.size(), size_t(0), "wrong count"); |
||||||
|
NOT_EQUAL(ages.size(), size_t(5), "wrong count"); |
||||||
|
} |
||||||
|
|
||||||
|
void test_push_pop_front() { |
||||||
|
std::deque<float> ages; |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.push_front(i * 34); |
||||||
|
} |
||||||
|
|
||||||
|
CHECK(ages.size() == 5, "wrong count"); |
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) { |
||||||
|
ages.pop_front(); |
||||||
|
fmt::println("count: {}", ages.size()); |
||||||
|
} |
||||||
|
|
||||||
|
NOT_EQUAL(ages.size(), size_t(0), "wrong count"); |
||||||
|
} |
||||||
|
|
||||||
|
void test_push_blows_up() { |
||||||
|
std::deque<float> ages; |
||||||
|
|
||||||
|
auto runner = [&]() { |
||||||
|
// uncomment this to see how the C++ stdlib sabotages you
|
||||||
|
// ages.pop_front();
|
||||||
|
|
||||||
|
ages.at(10); |
||||||
|
}; |
||||||
|
|
||||||
|
BLOWS_UP(runner, "pop_front empty should crash"); |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char* argv[]) { |
||||||
|
return run({ |
||||||
|
.name="std::deque basic operations", |
||||||
|
.options={ .fail_fast=false }, |
||||||
|
.tests={ |
||||||
|
{"push_pop_back", test_push_pop_back}, |
||||||
|
{"push_pop_front", test_push_pop_front}, |
||||||
|
{"push_blows_up", test_push_blows_up}, |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
[wrap-file] |
||||||
|
directory = fmt-12.0.0 |
||||||
|
source_url = https://github.com/fmtlib/fmt/archive/12.0.0.tar.gz |
||||||
|
source_filename = fmt-12.0.0.tar.gz |
||||||
|
source_hash = aa3e8fbb6a0066c03454434add1f1fc23299e85758ceec0d7d2d974431481e40 |
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_12.0.0-1/fmt-12.0.0.tar.gz |
||||||
|
patch_filename = fmt_12.0.0-1_patch.zip |
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch |
||||||
|
patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998 |
||||||
|
wrapdb_version = 12.0.0-1 |
||||||
|
|
||||||
|
[provide] |
||||||
|
dependency_names = fmt |
||||||
Loading…
Reference in new issue