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