aboutsummaryrefslogtreecommitdiffstats
path: root/libprakpp/include/prakcommon.hpp
diff options
context:
space:
mode:
authorjustanothercatgirl <sotov2070@gmail.com>2025-03-09 23:15:32 +0300
committerjustanothercatgirl <sotov2070@gmail.com>2025-03-09 23:15:32 +0300
commit320bf2f0155edd67557a3042403eeb843b90a41d (patch)
treec570a5cec849f12f068f4f4d3853793d974d7d8b /libprakpp/include/prakcommon.hpp
parent620b996f2ffe5e9e426b88f57e4f46bc9af7f237 (diff)
added 219
Diffstat (limited to 'libprakpp/include/prakcommon.hpp')
-rw-r--r--libprakpp/include/prakcommon.hpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/libprakpp/include/prakcommon.hpp b/libprakpp/include/prakcommon.hpp
index 47c793c..074e290 100644
--- a/libprakpp/include/prakcommon.hpp
+++ b/libprakpp/include/prakcommon.hpp
@@ -44,6 +44,16 @@ typedef long double _f64;
#define SUBSCR_OPRTR operator()
#endif
+#ifndef ENDCHAR
+# define ENDCHAR '\n'
+#endif
+#define var(v) << #v " = " << v << ENDCHAR
+
+#define FOR_EACH(fn, first, ...) fn(first) __VA_OPT__(FOR_EACH_AGAIN(fn, __VA_ARGS__))
+#define FOR_EACH_AGAIN(fn, ...) FOR_EACH(fn, __VA_ARGS__)
+#define APPLY_VARS(...) FOR_EACH(var, __VA_ARGS__)
+#define vars(...) APPLY_VARS(__VA_ARGS__)
+
template <typename T>
using function_t = std::function<T(const std::vector<T> &)>;
@@ -97,7 +107,7 @@ struct align_alloc : public std::allocator<T> {
constexpr void deallocate( T* p, std::size_t n ) {
::operator delete(p, std::align_val_t{64});
}
-};;
+};
/// alias prak::vector that is the same as std::vector, but uses aligned allocator
template <typename T>
@@ -106,9 +116,11 @@ using vector = std::vector<T, align_alloc<T>>;
/// prak value / pair value: a value with an error
template <typename T>
struct pvalue { T val, err; };
+template <typename T> struct pvalue<T> operator^(const struct pvalue<T> &v, const T &a) { return {std::pow(v.val, a), a * std::pow(v.val, a-1) * v.err}; }
template <typename T> struct pvalue<T> operator*(const struct pvalue<T> &v, const T &a) { return {v.val * a, v.err * a}; }
template <typename T> struct pvalue<T> operator*(const T &a, const struct pvalue<T> &v) { return {v.val * a, v.err * a}; }
template <typename T> struct pvalue<T> operator*(const struct pvalue<T> &a, const struct pvalue<T> &b) { return {a.val * b.val, a.val * b.val * std::hypot(a.err/a.val, b.err/b.val)}; }
+template <typename T> struct pvalue<T> operator/(const T &a, const struct pvalue<T> &v) { return {a / v.val, a * v.err / (v.val * v.val)}; }
template <typename T> struct pvalue<T> operator/(const struct pvalue<T> &v, const T &a) { return {v.val / a, v.err / a}; }
template <typename T> struct pvalue<T> operator/(const struct pvalue<T> &a, const struct pvalue<T> &b) { return {a.val / b.val, a.val / b.val * std::hypot(a.err/a.val, b.err/b.val)}; }
template <typename T> struct pvalue<T> operator+(const struct pvalue<T> &a, const struct pvalue<T> &b) { return {a.val + b.val, std::hypot(a.err, b.err)}; }