Initial commit of a small project to keep a record of various things in C++ that confuses me, other people, or are just down right dumb and should be avoided. This will be where I link people who tell me something is fast or better.
parent
57b4dd6b61
commit
bba4b2463e
@ -0,0 +1,10 @@ |
|||||||
|
set confirm off |
||||||
|
set breakpoint pending on |
||||||
|
set logging on |
||||||
|
set logging overwrite on |
||||||
|
set print pretty on |
||||||
|
set pagination off |
||||||
|
break abort |
||||||
|
#break _invalid_parameter_noinfo |
||||||
|
#break _invalid_parameter |
||||||
|
catch throw |
@ -0,0 +1,29 @@ |
|||||||
|
# ---> 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 |
@ -0,0 +1 @@ |
|||||||
|
set makeprg=meson\ compile\ -C\ . |
@ -0,0 +1,29 @@ |
|||||||
|
all: build test |
||||||
|
|
||||||
|
reset: |
||||||
|
powershell -executionpolicy bypass .\scripts\reset_build.ps1
|
||||||
|
|
||||||
|
%.cpp : %.rl |
||||||
|
ragel -o $@ $<
|
||||||
|
|
||||||
|
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 --buildtype debug
|
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
tracy_build: |
||||||
|
meson setup --wipe builddir --buildtype debugoptimized -Dtracy_enable=true -Dtracy:on_demand=true
|
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
test: build |
||||||
|
./builddir/emplace_test.exe
|
||||||
|
./builddir/rvo_test.exe
|
||||||
|
|
||||||
|
clean: |
||||||
|
meson compile --clean -C builddir
|
@ -0,0 +1,61 @@ |
|||||||
|
//
|
||||||
|
// Tracy profiler
|
||||||
|
// ----------------
|
||||||
|
//
|
||||||
|
// For fast integration, compile and
|
||||||
|
// link with this source file (and none
|
||||||
|
// other) in your executable (or in the
|
||||||
|
// main DLL / shared object on multi-DLL
|
||||||
|
// projects).
|
||||||
|
//
|
||||||
|
|
||||||
|
// Define TRACY_ENABLE to enable profiler.
|
||||||
|
|
||||||
|
#include "common/TracySystem.cpp" |
||||||
|
|
||||||
|
#ifdef TRACY_ENABLE |
||||||
|
|
||||||
|
#ifdef _MSC_VER |
||||||
|
# pragma warning(push, 0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "common/tracy_lz4.cpp" |
||||||
|
#include "client/TracyProfiler.cpp" |
||||||
|
#include "client/TracyCallstack.cpp" |
||||||
|
#include "client/TracySysPower.cpp" |
||||||
|
#include "client/TracySysTime.cpp" |
||||||
|
#include "client/TracySysTrace.cpp" |
||||||
|
#include "common/TracySocket.cpp" |
||||||
|
#include "client/tracy_rpmalloc.cpp" |
||||||
|
#include "client/TracyDxt1.cpp" |
||||||
|
#include "client/TracyAlloc.cpp" |
||||||
|
#include "client/TracyOverride.cpp" |
||||||
|
#include "client/TracyKCore.cpp" |
||||||
|
|
||||||
|
#if defined(TRACY_HAS_CALLSTACK) |
||||||
|
# if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 |
||||||
|
# include "libbacktrace/alloc.cpp" |
||||||
|
# include "libbacktrace/dwarf.cpp" |
||||||
|
# include "libbacktrace/fileline.cpp" |
||||||
|
# include "libbacktrace/mmapio.cpp" |
||||||
|
# include "libbacktrace/posix.cpp" |
||||||
|
# include "libbacktrace/sort.cpp" |
||||||
|
# include "libbacktrace/state.cpp" |
||||||
|
# if TRACY_HAS_CALLSTACK == 4 |
||||||
|
# include "libbacktrace/macho.cpp" |
||||||
|
# else |
||||||
|
# include "libbacktrace/elf.cpp" |
||||||
|
# endif |
||||||
|
# include "common/TracyStackFrames.cpp" |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef _MSC_VER |
||||||
|
# pragma comment(lib, "ws2_32.lib") |
||||||
|
# pragma comment(lib, "dbghelp.lib") |
||||||
|
# pragma comment(lib, "advapi32.lib") |
||||||
|
# pragma comment(lib, "user32.lib") |
||||||
|
# pragma warning(pop) |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,44 @@ |
|||||||
|
#include "dbc.hpp" |
||||||
|
#include <iostream> |
||||||
|
|
||||||
|
void dbc::log(const string &message) { |
||||||
|
std::cerr << "!!!!!!!!!!" << message << std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
void dbc::sentinel(const string &message) { |
||||||
|
string err = fmt::format("[SENTINEL!] {}", message); |
||||||
|
dbc::log(err); |
||||||
|
throw dbc::SentinelError{err}; |
||||||
|
} |
||||||
|
|
||||||
|
void dbc::pre(const string &message, bool test) { |
||||||
|
if(!test) { |
||||||
|
string err = fmt::format("[PRE!] {}", message); |
||||||
|
dbc::log(err); |
||||||
|
throw dbc::PreCondError{err}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void dbc::pre(const string &message, std::function<bool()> tester) { |
||||||
|
dbc::pre(message, tester()); |
||||||
|
} |
||||||
|
|
||||||
|
void dbc::post(const string &message, bool test) { |
||||||
|
if(!test) { |
||||||
|
string err = fmt::format("[POST!] {}", message); |
||||||
|
dbc::log(err); |
||||||
|
throw dbc::PostCondError{err}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void dbc::post(const string &message, std::function<bool()> tester) { |
||||||
|
dbc::post(message, tester()); |
||||||
|
} |
||||||
|
|
||||||
|
void dbc::check(bool test, const string &message) { |
||||||
|
if(!test) { |
||||||
|
string err = fmt::format("[CHECK!] {}\n", message); |
||||||
|
dbc::log(err); |
||||||
|
throw dbc::CheckError{err}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <functional> |
||||||
|
|
||||||
|
using std::string; |
||||||
|
|
||||||
|
namespace dbc { |
||||||
|
class Error { |
||||||
|
public: |
||||||
|
const string message; |
||||||
|
Error(string m) : message{m} {} |
||||||
|
Error(const char *m) : message{m} {} |
||||||
|
}; |
||||||
|
|
||||||
|
class CheckError : public Error {}; |
||||||
|
class SentinelError : public Error {}; |
||||||
|
class PreCondError : public Error {}; |
||||||
|
class PostCondError : public Error {}; |
||||||
|
|
||||||
|
void log(const string &message); |
||||||
|
void sentinel(const string &message); |
||||||
|
void pre(const string &message, bool test); |
||||||
|
void pre(const string &message, std::function<bool()> tester); |
||||||
|
void post(const string &message, bool test); |
||||||
|
void post(const string &message, std::function<bool()> tester); |
||||||
|
void check(bool test, const string &message); |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
#include <catch2/catch_test_macros.hpp> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <string> |
||||||
|
#include <iostream> |
||||||
|
#include <vector> |
||||||
|
#include <cstdlib> |
||||||
|
|
||||||
|
using namespace fmt; |
||||||
|
|
||||||
|
// Some heavy object
|
||||||
|
struct A { |
||||||
|
A() = default; |
||||||
|
|
||||||
|
A(int val) : val(val) { |
||||||
|
std::cout << "called constructor with: " << val << std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
A(A const& other) { |
||||||
|
std::cout << "calling copy(A const& other): " << val << std::endl;; |
||||||
|
} |
||||||
|
A(A&& other) { |
||||||
|
std::cout << "calling move(A&& other): " << val << std::endl;; |
||||||
|
} |
||||||
|
|
||||||
|
A& operator=(A&& other) { |
||||||
|
std::cout << "calling move(A&& other)=: " << val << std::endl;; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
A& operator=(A const& other) { |
||||||
|
std::cout << "calling copy(A const& other)=: " << val << std::endl;; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
~A() = default; |
||||||
|
|
||||||
|
int val{}; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("emplace move tests", "[emplace]") { |
||||||
|
A a{10}; |
||||||
|
std::vector<A> test; |
||||||
|
test.reserve(10); // to prevent vector resizing and creating new objects on the way
|
||||||
|
std::cout << "===== Emplacing Start =====\n"; |
||||||
|
// pass by l-value and will call copy constructor since it'll match
|
||||||
|
// A(A const&)
|
||||||
|
std::cout << "== 1. Emplace: Calling copy constructor \n"; |
||||||
|
test.emplace_back(a); |
||||||
|
|
||||||
|
// pass by r-value and will call move constructor since it'll match
|
||||||
|
// A(A&&)
|
||||||
|
std::cout << "== 2. Emplace: Calling move constructor \n"; |
||||||
|
test.emplace_back(std::move(a)); |
||||||
|
|
||||||
|
std::cout << "== 3. Emplace: Calling move constructor without direct constructor\n"; |
||||||
|
test.emplace_back(100); |
||||||
|
|
||||||
|
// pass by pr-value (pure r-value which is those value that has not come to an existance yet)
|
||||||
|
// and will call move constructor since it'll match A(A&&).
|
||||||
|
// "copy-elision" could be applied here but I don't know why compilers
|
||||||
|
// refused to do it. Maybe how vectors are implemented and you need
|
||||||
|
// to put the value in a slot so the compiler had to call the move constructor
|
||||||
|
std::cout << "== 4. Emplace: Calling move constructor\n"; |
||||||
|
test.emplace_back(A{}); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_CASE("pushback move tests", "[push_back]") { |
||||||
|
std::cout << "\n\n!!!!!!!!!! PUSH BACK alternative !!!!!!!!!!\n"; |
||||||
|
|
||||||
|
A a{20}; |
||||||
|
std::vector<A> test; |
||||||
|
test.reserve(10); // to prevent vector resizing and creating new objects on the way
|
||||||
|
std::cout << "===== Push Back Start =====\n"; |
||||||
|
// pass by l-value and will call copy constructor since it'll match
|
||||||
|
// A(A const&)
|
||||||
|
std::cout << "== 1. Push Back: Calling copy constructor \n"; |
||||||
|
test.push_back(a); |
||||||
|
|
||||||
|
// pass by r-value and will call move constructor since it'll match
|
||||||
|
// A(A&&)
|
||||||
|
std::cout << "== 2. Push Back: Calling move constructor \n"; |
||||||
|
test.push_back(std::move(a)); |
||||||
|
|
||||||
|
std::cout << "== 3. Push Back: Calling move constructor without direct constructor\n"; |
||||||
|
test.push_back(200); |
||||||
|
|
||||||
|
// pass by pr-value (pure r-value which is those value that has not come to an existance yet)
|
||||||
|
// and will call move constructor since it'll match A(A&&).
|
||||||
|
// "copy-elision" could be applied here but I don't know why compilers
|
||||||
|
// refused to do it. Maybe how vectors are implemented and you need
|
||||||
|
// to put the value in a slot so the compiler had to call the move constructor
|
||||||
|
std::cout << "== 4. Push Back: Calling move constructor\n"; |
||||||
|
test.push_back(A{}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("proof you don't need emplace or std::move", "[proof]") { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
project('c-plus-plus-dafuq', 'cpp', |
||||||
|
version: '0.1.0', |
||||||
|
default_options: [ |
||||||
|
'cpp_std=c++20', |
||||||
|
'cpp_args=-DTRACY_ENABLE=1 -D_GLIBCXX_DEBUG=1 -D_GLIBCXX_DEBUG_PEDANTIC=1', |
||||||
|
'cpp_args=-DTRACY_ENABLE=1', |
||||||
|
]) |
||||||
|
|
||||||
|
exe_defaults = [] |
||||||
|
|
||||||
|
cc = meson.get_compiler('cpp') |
||||||
|
|
||||||
|
tracy = dependency('tracy', static: true) |
||||||
|
catch2 = dependency('catch2-with-main') |
||||||
|
fmt = dependency('fmt', allow_fallback: true) |
||||||
|
json = dependency('nlohmann_json') |
||||||
|
|
||||||
|
# not sure if tracy needs these |
||||||
|
opengl32 = cc.find_library('opengl32', required: true) |
||||||
|
winmm = cc.find_library('winmm', required: true) |
||||||
|
gdi32 = cc.find_library('gdi32', required: true) |
||||||
|
|
||||||
|
# i know for sure tracy needs these |
||||||
|
ws2_32 = cc.find_library('ws2_32', required: true) |
||||||
|
dbghelp = cc.find_library('dbghelp', required: true) |
||||||
|
|
||||||
|
if get_option('tracy_enable') and get_option('buildtype') != 'debugoptimized' |
||||||
|
warning('Profiling builds should set --buildtype=debugoptimized') |
||||||
|
endif |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
tracy, catch2, fmt, json, opengl32, |
||||||
|
ws2_32, dbghelp |
||||||
|
] |
||||||
|
|
||||||
|
# use this for common options only for our executables |
||||||
|
cpp_args=[ ] |
||||||
|
|
||||||
|
executable('emplace_test', [ |
||||||
|
'TracyClient.cpp', |
||||||
|
'emplace_move/test.cpp' |
||||||
|
], |
||||||
|
override_options: exe_defaults, |
||||||
|
dependencies: dependencies) |
||||||
|
|
||||||
|
executable('rvo_test', [ |
||||||
|
'TracyClient.cpp', |
||||||
|
'rvo/test.cpp' |
||||||
|
], |
||||||
|
override_options: exe_defaults, |
||||||
|
dependencies: dependencies) |
@ -0,0 +1 @@ |
|||||||
|
option('tracy_enable', type: 'boolean', value: false, description: 'Enable profiling') |
@ -0,0 +1,156 @@ |
|||||||
|
#include <catch2/catch_test_macros.hpp> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <string> |
||||||
|
#include <iostream> |
||||||
|
#include <vector> |
||||||
|
#include <cstdlib> |
||||||
|
|
||||||
|
using namespace fmt; |
||||||
|
|
||||||
|
|
||||||
|
// Some heavy object
|
||||||
|
struct A { |
||||||
|
A() = default; |
||||||
|
|
||||||
|
A(int val) : val(val) { |
||||||
|
std::cout << "called constructor with: " << val << std::endl; |
||||||
|
} |
||||||
|
|
||||||
|
A(A const& other) { |
||||||
|
std::cout << "calling copy(A const& other): " << val << std::endl;; |
||||||
|
} |
||||||
|
A(A&& other) { |
||||||
|
std::cout << "calling move(A&& other): " << val << std::endl;; |
||||||
|
} |
||||||
|
|
||||||
|
A& operator=(A&& other) { |
||||||
|
std::cout << "calling move(A&& other)=: " << val << std::endl;; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
A& operator=(A const& other) { |
||||||
|
std::cout << "calling copy(A const& other)=: " << val << std::endl;; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
~A() = default; |
||||||
|
|
||||||
|
int val{}; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
template <typename T> |
||||||
|
void print_helper(std::string_view var, T&&) { |
||||||
|
std::string name = typeid(T).name(); |
||||||
|
if constexpr (std::is_const_v<T>) { |
||||||
|
name += " const"; |
||||||
|
} |
||||||
|
if constexpr (std::is_lvalue_reference_v<T>) { |
||||||
|
name += "&"; |
||||||
|
} else { |
||||||
|
name += "&&"; |
||||||
|
} |
||||||
|
|
||||||
|
std::cout << "Type of '" << var << "': '" << name <<"'\n"; |
||||||
|
} |
||||||
|
|
||||||
|
#define print_t(VAR) print_helper(#VAR, VAR) |
||||||
|
|
||||||
|
A rvo_impl_1() { |
||||||
|
A a; |
||||||
|
std::cout << "rvo_impl_1\n"; |
||||||
|
a.val = rand() % 2; |
||||||
|
return a; |
||||||
|
} |
||||||
|
|
||||||
|
// calls the move constructor or it might optimize away it in -O3
|
||||||
|
std::string rvo_impl_2(int v) { |
||||||
|
std::string res; |
||||||
|
std::cout << "rvo_impl_2\n"; |
||||||
|
res = std::to_string(v); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
// It'll call copy constructors
|
||||||
|
std::string rvo_not_work_complex(int v) { |
||||||
|
if (v % 5 == 0) return "multiple of five"; |
||||||
|
if (v % 2 == 0) return "multiple of 2"; |
||||||
|
return std::to_string(v); |
||||||
|
} |
||||||
|
|
||||||
|
// call move constructor
|
||||||
|
A rvo_not_work_impl(int v) { |
||||||
|
std::cout << "rvo_not_work_impl: "; |
||||||
|
A a; |
||||||
|
if (v % 2) { |
||||||
|
a.val = v % 2; |
||||||
|
} else { |
||||||
|
// returning early
|
||||||
|
// you might think who would do that let me show you an example
|
||||||
|
return {}; |
||||||
|
} |
||||||
|
return a; |
||||||
|
} |
||||||
|
|
||||||
|
// copy-elision/RVO does not call any constructor since they get optimized away
|
||||||
|
A copy_elision() { |
||||||
|
std::cout << "copy_elision\n"; |
||||||
|
return A(); // pr-value
|
||||||
|
} |
||||||
|
|
||||||
|
// RVO(return value optimization) is a part of copy-elision, but "copy-elision" is
|
||||||
|
// a much wider concept that applies to other parts of the program. It removes
|
||||||
|
// copy/move constuctors
|
||||||
|
|
||||||
|
// What is l-value?
|
||||||
|
// l-values are references to the objects. These are objects you can hold onto
|
||||||
|
// like constructed objects, variables or references.
|
||||||
|
// example:
|
||||||
|
// 1. int&
|
||||||
|
// 2. int const&
|
||||||
|
// 3. int a = 4; foo(a <-- this will be a l-value)
|
||||||
|
|
||||||
|
// What is r-value?
|
||||||
|
// r-values are the values that is temporary.
|
||||||
|
// example:
|
||||||
|
// 1. literals like "hello", 1, 2.5
|
||||||
|
// 2. call to object constructor like A(), std::string("Hello"), ...
|
||||||
|
// 3. A&&, int&&, ... these are r-values that you've seen inside the move constructors
|
||||||
|
|
||||||
|
// There are more value that you can look into "pr-value", ...
|
||||||
|
// https://en.cppreference.com/w/cpp/language/value_category
|
||||||
|
|
||||||
|
// You may be thinking why i'm talking about them. The reason being these concept
|
||||||
|
// allows you understand when to use "std::move" and when it's useless. For that
|
||||||
|
// let me implement my version of move constructor
|
||||||
|
|
||||||
|
template <typename T> |
||||||
|
// decltype(auto) means forward the return type or whatever I'm returning infer the type with
|
||||||
|
// "const&", "&" or "&&"
|
||||||
|
decltype(auto) my_move(T&& val) { |
||||||
|
// here T&& is not a r-value. It's perfect forwarding. Whenever you see "&&" you see
|
||||||
|
// with template it means perfect forwading. I know cpp has fucked-up syntax.
|
||||||
|
using type = std::decay_t<T>; |
||||||
|
// all this does is cast l-value to r-value
|
||||||
|
return static_cast<type&&>(val); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_CASE("RVO tests", "[base]") { |
||||||
|
A a{10}; |
||||||
|
int argc; |
||||||
|
std::cout << "\n\n######### RVO TESTS ###############\n"; |
||||||
|
auto t0 = rvo_impl_1(); // no constructor will be called because of return value optimization
|
||||||
|
auto t1 = rvo_not_work_impl(argc); |
||||||
|
auto t2 = copy_elision(); |
||||||
|
auto t3 = rvo_not_work_complex(argc); |
||||||
|
auto t4 = rvo_impl_2(argc); |
||||||
|
|
||||||
|
print_t(a); // pass by l-value | output: Type of 'a': 'A&'
|
||||||
|
print_t(std::move(a)); // pass by r-value | output: Type of 'std::move(a)': 'A&&'
|
||||||
|
print_t(my_move(a)); // pass by r-value | output: Type of 'my_move(a)': 'A&&'
|
||||||
|
print_t(A{}); // pass by r-value | output: Type of 'A{}': 'A&&'
|
||||||
|
|
||||||
|
static_assert(!std::is_rvalue_reference_v<decltype(a)>, "'a' is l-value"); |
||||||
|
// you can remove the negation and see it failing
|
||||||
|
static_assert(!std::is_lvalue_reference_v<decltype(my_move(a))>, "This should pass if I've implement it correctly"); |
||||||
|
} |
@ -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 -Db_coverage=true builddir |
@ -0,0 +1,11 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
set -e |
||||||
|
|
||||||
|
mv -f ./subprojects/packagecache . |
||||||
|
rm -rf subprojects builddir |
||||||
|
mkdir subprojects |
||||||
|
mv packagecache ./subprojects/ |
||||||
|
mkdir builddir |
||||||
|
cp wraps/*.wrap subprojects/ |
||||||
|
# on OSX you can't do this with static |
||||||
|
meson setup -Db_coverage=true builddir |
@ -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,11 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
set -e |
||||||
|
|
||||||
|
mv -f ./subprojects/packagecache . |
||||||
|
rm -rf subprojects builddir |
||||||
|
mkdir subprojects |
||||||
|
mv packagecache ./subprojects/ |
||||||
|
mkdir builddir |
||||||
|
cp wraps/*.wrap subprojects/ |
||||||
|
# on OSX you can't do this with static |
||||||
|
meson setup builddir |
@ -0,0 +1,10 @@ |
|||||||
|
#include "stats.hpp" |
||||||
|
#include <fmt/core.h> |
||||||
|
|
||||||
|
void Stats::dump() |
||||||
|
{ |
||||||
|
fmt::println("sum: {}, sumsq: {}, n: {}, " |
||||||
|
"min: {}, max: {}, mean: {}, stddev: {}", |
||||||
|
sum, sumsq, n, min, max, mean(), |
||||||
|
stddev()); |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
#pragma once |
||||||
|
#include <cmath> |
||||||
|
|
||||||
|
struct Stats { |
||||||
|
double sum = 0.0; |
||||||
|
double sumsq = 0.0; |
||||||
|
unsigned long n = 0L; |
||||||
|
double min = 0.0; |
||||||
|
double max = 0.0; |
||||||
|
|
||||||
|
|
||||||
|
inline void reset() { |
||||||
|
sum = 0; |
||||||
|
sumsq = 0; |
||||||
|
n = 0L; |
||||||
|
min = 0; |
||||||
|
max = 0; |
||||||
|
} |
||||||
|
|
||||||
|
inline double mean() { |
||||||
|
return sum / n; |
||||||
|
} |
||||||
|
|
||||||
|
inline double stddev() { |
||||||
|
return std::sqrt((sumsq - (sum * sum / n)) / |
||||||
|
(n - 1)); |
||||||
|
} |
||||||
|
|
||||||
|
inline void sample(double s) { |
||||||
|
sum += s; |
||||||
|
sumsq += s * s; |
||||||
|
|
||||||
|
if (n == 0) { |
||||||
|
min = s; |
||||||
|
max = s; |
||||||
|
} else { |
||||||
|
if (min > s) min = s; |
||||||
|
if (max < s) max = s; |
||||||
|
} |
||||||
|
|
||||||
|
n += 1; |
||||||
|
} |
||||||
|
|
||||||
|
void dump(); |
||||||
|
}; |
@ -0,0 +1,9 @@ |
|||||||
|
#include <catch2/catch_test_macros.hpp> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
using namespace fmt; |
||||||
|
|
||||||
|
TEST_CASE("base test", "[base]") { |
||||||
|
REQUIRE(1 == 1); |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
[wrap-file] |
||||||
|
directory = Catch2-3.7.1 |
||||||
|
source_url = https://github.com/catchorg/Catch2/archive/v3.7.1.tar.gz |
||||||
|
source_filename = Catch2-3.7.1.tar.gz |
||||||
|
source_hash = c991b247a1a0d7bb9c39aa35faf0fe9e19764213f28ffba3109388e62ee0269c |
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/catch2_3.7.1-1/Catch2-3.7.1.tar.gz |
||||||
|
wrapdb_version = 3.7.1-1 |
||||||
|
|
||||||
|
[provide] |
||||||
|
catch2 = catch2_dep |
||||||
|
catch2-with-main = catch2_with_main_dep |
@ -0,0 +1,13 @@ |
|||||||
|
[wrap-file] |
||||||
|
directory = fmt-11.0.2 |
||||||
|
source_url = https://github.com/fmtlib/fmt/archive/11.0.2.tar.gz |
||||||
|
source_filename = fmt-11.0.2.tar.gz |
||||||
|
source_hash = 6cb1e6d37bdcb756dbbe59be438790db409cdb4868c66e888d5df9f13f7c027f |
||||||
|
patch_filename = fmt_11.0.2-1_patch.zip |
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_11.0.2-1/get_patch |
||||||
|
patch_hash = 90c9e3b8e8f29713d40ca949f6f93ad115d78d7fb921064112bc6179e6427c5e |
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_11.0.2-1/fmt-11.0.2.tar.gz |
||||||
|
wrapdb_version = 11.0.2-1 |
||||||
|
|
||||||
|
[provide] |
||||||
|
fmt = fmt_dep |
@ -0,0 +1,11 @@ |
|||||||
|
[wrap-file] |
||||||
|
directory = nlohmann_json-3.11.3 |
||||||
|
lead_directory_missing = true |
||||||
|
source_url = https://github.com/nlohmann/json/releases/download/v3.11.3/include.zip |
||||||
|
source_filename = nlohmann_json-3.11.3.zip |
||||||
|
source_hash = a22461d13119ac5c78f205d3df1db13403e58ce1bb1794edc9313677313f4a9d |
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/nlohmann_json_3.11.3-1/nlohmann_json-3.11.3.zip |
||||||
|
wrapdb_version = 3.11.3-1 |
||||||
|
|
||||||
|
[provide] |
||||||
|
nlohmann_json = nlohmann_json_dep |
@ -0,0 +1,7 @@ |
|||||||
|
[wrap-git] |
||||||
|
url=https://github.com/wolfpld/tracy.git |
||||||
|
revision=v0.11.1 |
||||||
|
depth=1 |
||||||
|
|
||||||
|
[provide] |
||||||
|
tracy = tracy_dep |
Loading…
Reference in new issue