summaryrefslogtreecommitdiffhomepage
path: root/compat
diff options
context:
space:
mode:
Diffstat (limited to 'compat')
-rw-r--r--compat/activation-context.cpp51
-rw-r--r--compat/activation-context.hpp26
-rw-r--r--compat/arch.hpp50
-rw-r--r--compat/base-path.cpp4
-rw-r--r--compat/base-path.hpp3
-rw-r--r--compat/check-visible.cpp92
-rw-r--r--compat/check-visible.hpp11
-rw-r--r--compat/copyable-mutex.cpp33
-rw-r--r--compat/copyable-mutex.hpp27
-rw-r--r--compat/correlation-calibrator.cpp31
-rw-r--r--compat/correlation-calibrator.hpp26
-rw-r--r--compat/enum-operators.hpp33
-rw-r--r--compat/library-path.hpp2
-rw-r--r--compat/linkage-macros.hpp6
-rw-r--r--compat/macros.hpp75
-rw-r--r--compat/macros1.h43
-rw-r--r--compat/math.hpp4
-rw-r--r--compat/mutex.cpp33
-rw-r--r--compat/mutex.hpp24
-rw-r--r--compat/qt-signal.cpp13
-rw-r--r--compat/qt-signal.hpp30
-rw-r--r--compat/run-in-thread.hpp6
-rw-r--r--compat/shm.cpp2
-rw-r--r--compat/shm.h10
-rw-r--r--compat/simple-mat.hpp96
-rw-r--r--compat/sleep.cpp2
-rw-r--r--compat/sysexits.hpp32
-rw-r--r--compat/timer.cpp2
-rw-r--r--compat/warn.hpp67
29 files changed, 483 insertions, 351 deletions
diff --git a/compat/activation-context.cpp b/compat/activation-context.cpp
new file mode 100644
index 00000000..8d34243d
--- /dev/null
+++ b/compat/activation-context.cpp
@@ -0,0 +1,51 @@
+#ifdef _WIN32
+
+#include "activation-context.hpp"
+#include "compat/library-path.hpp"
+
+#include <QString>
+#include <QFile>
+#include <QDebug>
+
+#include <windows.h>
+
+static_assert(sizeof(std::uintptr_t) == sizeof(ULONG_PTR));
+
+activation_context::activation_context(const QString& module_name, int resid)
+{
+ static const QString prefix = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH + OPENTRACK_LIBRARY_PREFIX;
+ QString path = prefix + module_name;
+ QByteArray name = QFile::encodeName(path);
+
+ ACTCTXA actx = {};
+ actx.cbSize = sizeof(actx);
+ actx.lpResourceName = MAKEINTRESOURCEA(resid);
+ actx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
+ actx.lpSource = name.constData();
+
+ handle = CreateActCtxA(&actx);
+
+ if (handle != INVALID_HANDLE_VALUE)
+ {
+ if (!ActivateActCtx(handle, (ULONG_PTR*)&cookie))
+ {
+ qDebug() << "win32: can't set activation context" << GetLastError();
+ ReleaseActCtx(handle);
+ handle = INVALID_HANDLE_VALUE;
+ }
+ else
+ ok = true;
+ } else {
+ qDebug() << "win32: can't create activation context" << GetLastError();
+ }
+}
+
+activation_context::~activation_context()
+{
+ if (handle != INVALID_HANDLE_VALUE)
+ {
+ DeactivateActCtx(0, cookie);
+ ReleaseActCtx(handle);
+ }
+}
+#endif
diff --git a/compat/activation-context.hpp b/compat/activation-context.hpp
new file mode 100644
index 00000000..a3b0429e
--- /dev/null
+++ b/compat/activation-context.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#ifdef _WIN32
+
+#include "export.hpp"
+
+#include <cstdint>
+#include <QString>
+
+class OTR_COMPAT_EXPORT activation_context
+{
+public:
+ explicit activation_context(const QString& module_name, int resid);
+ ~activation_context();
+
+ explicit operator bool() const { return ok; }
+
+private:
+ std::uintptr_t cookie = 0;
+ void* handle = (void*)-1;
+ bool ok = false;
+};
+
+#else
+# error "tried to use win32-only activation context"
+#endif
diff --git a/compat/arch.hpp b/compat/arch.hpp
new file mode 100644
index 00000000..33f8f8ca
--- /dev/null
+++ b/compat/arch.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+// fix MSVC arch check macros
+
+// this file is too simple to fall under copyright, and
+// can be copied, modified, and redistributed freely with
+// no conditions. there's no warranty. -sh 20181226
+
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wreserved-id-macro"
+# pragma clang diagnostic ignored "-Wunused-macros"
+#endif
+
+#if defined _MSC_VER
+# if defined _M_AMD64
+# undef __x86_64__
+# define __x86_64__ 1
+# elif defined _M_IX86
+# undef __i386__
+# define __i386__ 1
+# endif
+
+# if defined __AVX__ || defined __x86_64__ || \
+ defined _M_IX86 && _M_IX86_FP >= 2
+# undef __SSE__
+# undef __SSE2__
+# undef __SSE3__
+# define __SSE__ 1
+# define __SSE2__ 1
+# define __SSE3__ 1 // assume SSE3 in the _M_IX86_FP >= 2 case
+# endif
+#endif
+
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
+#if defined __SSE3__
+# define OTR_ARCH_DENORM_DAZ
+# include <pmmintrin.h>
+#elif defined __SSE2__
+# define OTR_ARCH_DENORM_FTZ
+# include <emmintrin.h>
+#endif
+
+#if defined __SSE2__
+# define OTR_ARCH_FPU_MASK
+# include <xmmintrin.h>
+#endif
diff --git a/compat/base-path.cpp b/compat/base-path.cpp
index 4ef3762e..b544a3d1 100644
--- a/compat/base-path.cpp
+++ b/compat/base-path.cpp
@@ -1,8 +1,12 @@
+#undef NDEBUG
+#include <cassert>
+
#include "base-path.hpp"
#include <QCoreApplication>
const QString& application_base_path()
{
+ assert(qApp && "logic error");
static QString const& const_path = QCoreApplication::applicationDirPath();
return const_path;
}
diff --git a/compat/base-path.hpp b/compat/base-path.hpp
index 06e2c703..54e094f4 100644
--- a/compat/base-path.hpp
+++ b/compat/base-path.hpp
@@ -5,8 +5,7 @@
#include <QString>
-OTR_COMPAT_EXPORT
-cc_noinline
+OTR_COMPAT_EXPORT never_inline
const QString& application_base_path();
#define OPENTRACK_BASE_PATH (application_base_path())
diff --git a/compat/check-visible.cpp b/compat/check-visible.cpp
index 96dba60f..f786ca14 100644
--- a/compat/check-visible.cpp
+++ b/compat/check-visible.cpp
@@ -1,67 +1,89 @@
#include "check-visible.hpp"
+#include <QMutex>
+#include <QWidget>
+#include <QDebug>
+
+static QMutex lock;
+static bool visible = true;
+
#if defined _WIN32
#include "timer.hpp"
+#include "macros.hpp"
-#include <QMutex>
-
-#include <windows.h>
+static Timer timer;
-constexpr int visible_timeout = 5000;
+constexpr int visible_timeout = 1000;
constexpr int invisible_timeout = 250;
-static Timer timer;
-static QMutex mtx;
-static bool visible = true;
+#include <windows.h>
void set_is_visible(const QWidget& w, bool force)
{
- QMutexLocker l(&mtx);
+ QMutexLocker l(&lock);
- if (!force && timer.elapsed_ms() < (visible ? visible_timeout : invisible_timeout))
+ if (w.isHidden() || w.windowState() & Qt::WindowMinimized)
+ {
+ visible = false;
return;
+ }
- timer.start();
+ HWND hwnd = (HWND)w.winId();
- const HWND id = (HWND) w.winId();
- const QPoint pt = w.mapToGlobal({ 0, 0 });
+ if (!force && timer.elapsed_ms() < (visible ? visible_timeout : invisible_timeout))
+ return;
- const int W = w.width(), H = w.height();
+ timer.start();
- const QPoint points[] =
+ if (RECT r; GetWindowRect(hwnd, &r))
{
- pt,
- pt + QPoint(W - 1, 0),
- pt + QPoint(0, H - 1),
- pt + QPoint(W - 1, H - 1),
- pt + QPoint(W / 2, H / 2),
- };
-
- for (const QPoint& pt : points)
+ const int x = r.left, y = r.top;
+ const int w = r.right - x, h = r.bottom - y;
+
+ const POINT xs[] {
+ { x + w - 1, y + 1 },
+ { x + 1, y + h - 1 },
+ { x + w - 1, y + h - 1 },
+ { x + 1, y + 1 },
+ { x + w/2, y + h/2 },
+ };
+
+ visible = false;
+
+ for (const POINT& pt : xs)
+ if (WindowFromPoint(pt) == hwnd)
+ {
+
+ visible = true;
+ break;
+ }
+ }
+ else
{
- visible = WindowFromPoint({ pt.x(), pt.y() }) == id;
- if (visible)
- break;
+ eval_once(qDebug() << "check-visible: GetWindowRect failed");
+ visible = true;
}
}
-bool check_is_visible()
-{
- QMutexLocker l(&mtx);
-
- return visible;
-}
-
#else
-void set_is_visible(const QWidget&, bool)
+void set_is_visible(const QWidget& w, bool)
{
+ QMutexLocker l(&lock);
+ visible = !(w.isHidden() || w.windowState() & Qt::WindowMinimized);
}
+#endif
+
bool check_is_visible()
{
- return true;
+ QMutexLocker l(&lock);
+ return visible;
}
-#endif
+void force_is_visible(bool value)
+{
+ QMutexLocker l(&lock);
+ visible = value;
+}
diff --git a/compat/check-visible.hpp b/compat/check-visible.hpp
index e24a654b..e24260ab 100644
--- a/compat/check-visible.hpp
+++ b/compat/check-visible.hpp
@@ -1,12 +1,15 @@
#pragma once
#include "export.hpp"
-#include "macros.hpp"
+#include "macros1.h"
-#include <QWidget>
+class QWidget;
-cc_noinline OTR_COMPAT_EXPORT
+never_inline OTR_COMPAT_EXPORT
void set_is_visible(QWidget const& w, bool force = false);
-cc_noinline OTR_COMPAT_EXPORT
+OTR_COMPAT_EXPORT
bool check_is_visible();
+
+OTR_COMPAT_EXPORT
+void force_is_visible(bool value);
diff --git a/compat/copyable-mutex.cpp b/compat/copyable-mutex.cpp
deleted file mode 100644
index dde84c83..00000000
--- a/compat/copyable-mutex.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "copyable-mutex.hpp"
-
-mutex& mutex::operator=(const mutex& datum)
-{
- inner.emplace(datum->isRecursive() ? QMutex::Recursive : QMutex::NonRecursive);
- return *this;
-}
-
-mutex::mutex(const mutex& datum)
-{
- *this = datum;
-}
-
-mutex::mutex(mutex::mode m) :
- inner { std::in_place, static_cast<QMutex::RecursionMode>(int(m)) }
-{
-}
-
-QMutex* mutex::operator&() const
-{
- return *this;
-}
-
-QMutex* mutex::operator->() const
-{
- return *this;
-}
-
-mutex::operator QMutex*() const
-{
- return const_cast<QMutex*>(&inner.value());
-}
-
diff --git a/compat/copyable-mutex.hpp b/compat/copyable-mutex.hpp
deleted file mode 100644
index 46c6c88c..00000000
--- a/compat/copyable-mutex.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <optional>
-
-#include <QMutex>
-
-#include "export.hpp"
-
-class OTR_COMPAT_EXPORT mutex
-{
- std::optional<QMutex> inner;
-
-public:
- enum mode
- {
- recursive = QMutex::Recursive,
- normal = QMutex::NonRecursive,
- };
-
- mutex& operator=(const mutex& datum);
- mutex(const mutex& datum);
- explicit mutex(mode m = normal);
-
- QMutex* operator&() const;
- operator QMutex*() const;
- QMutex* operator->() const;
-};
diff --git a/compat/correlation-calibrator.cpp b/compat/correlation-calibrator.cpp
index a58d31cd..01f3b14f 100644
--- a/compat/correlation-calibrator.cpp
+++ b/compat/correlation-calibrator.cpp
@@ -11,12 +11,9 @@
#define DEBUG_PRINT
#ifdef DEBUG_PRINT
# include <cstdio>
-# include <cwchar>
- using std::fwprintf;
- using std::fflush;
#endif
-using namespace correlation_calibrator_impl;
+namespace correlation_calibrator_impl {
static constexpr unsigned nbuckets[6] =
{
@@ -40,9 +37,9 @@ static constexpr double spacing[6] =
roll_spacing_in_degrees,
};
-static constexpr wchar_t const* const names[6] {
- L"x", L"y", L"z",
- L"yaw", L"pitch", L"roll",
+static constexpr char const* const names[6] {
+ "x", "y", "z",
+ "yaw", "pitch", "roll",
};
bool correlation_calibrator::check_buckets(const vec6& data)
@@ -53,7 +50,7 @@ bool correlation_calibrator::check_buckets(const vec6& data)
for (unsigned k = 0; k < 6; k++)
{
const double val = clamp(data[k], min[k], max[k]);
- pos[k] = (val-min[k])/spacing[k];
+ pos[k] = unsigned((val-min[k])/spacing[k]);
if (pos[k] >= nbuckets[k])
{
@@ -129,18 +126,18 @@ mat66 correlation_calibrator::get_coefficients() const
cs = cs * (1./(data.size() - 1));
#if defined DEBUG_PRINT
- fwprintf(stderr, L"v:change-of h:due-to\n");
- fwprintf(stderr, L"%10s ", L"");
- for (wchar_t const* k : names)
- fwprintf(stderr, L"%10s", k);
- fwprintf(stderr, L"\n");
+ fprintf(stderr, "v:change-of h:due-to\n");
+ fprintf(stderr, "%10s ", "");
+ for (char const* k : names)
+ fprintf(stderr, "%10s", k);
+ fprintf(stderr, "\n");
for (unsigned i = 0; i < 6; i++)
{
- fwprintf(stderr, L"%10s ", names[i]);
+ fprintf(stderr, "%10s ", names[i]);
for (unsigned k = 0; k < 6; k++)
- fwprintf(stderr, L"%10.3f", cs(i, k));
- fwprintf(stderr, L"\n");
+ fprintf(stderr, "%10.3f", cs(i, k));
+ fprintf(stderr, "\n");
}
fflush(stderr);
#endif
@@ -158,3 +155,5 @@ unsigned correlation_calibrator::sample_count() const
{
return data.size();
}
+
+} // ns correlation_calibrator_impl
diff --git a/compat/correlation-calibrator.hpp b/compat/correlation-calibrator.hpp
index 2c9e1937..44aee537 100644
--- a/compat/correlation-calibrator.hpp
+++ b/compat/correlation-calibrator.hpp
@@ -9,7 +9,7 @@
namespace correlation_calibrator_impl {
-static constexpr inline double min[6] = {
+static constexpr double min[6] = {
-50,
-50,
250,
@@ -19,7 +19,7 @@ static constexpr inline double min[6] = {
-180,
};
-static constexpr inline double max[6] = {
+static constexpr double max[6] = {
50,
50,
250,
@@ -29,18 +29,18 @@ static constexpr inline double max[6] = {
180,
};
-static constexpr inline double yaw_spacing_in_degrees = 1.5;
-static constexpr inline double pitch_spacing_in_degrees = 1;
-static constexpr inline double roll_spacing_in_degrees = 1;
+static constexpr double yaw_spacing_in_degrees = 1.5;
+static constexpr double pitch_spacing_in_degrees = 1;
+static constexpr double roll_spacing_in_degrees = 1;
-static constexpr inline unsigned yaw_nbuckets = 1+ 360./yaw_spacing_in_degrees;
-static constexpr inline unsigned pitch_nbuckets = 1+ 360./pitch_spacing_in_degrees;
-static constexpr inline unsigned roll_nbuckets = 1+ 360./roll_spacing_in_degrees;
+static constexpr unsigned yaw_nbuckets = unsigned(1+ 360./yaw_spacing_in_degrees);
+static constexpr unsigned pitch_nbuckets = unsigned(1+ 360./pitch_spacing_in_degrees);
+static constexpr unsigned roll_nbuckets = unsigned(1+ 360./roll_spacing_in_degrees);
-static constexpr inline double translation_spacing = .25;
-static constexpr inline unsigned x_nbuckets = 1+ (max[0]-min[0])/translation_spacing;
-static constexpr inline unsigned y_nbuckets = 1+ (max[1]-min[1])/translation_spacing;
-static constexpr inline unsigned z_nbuckets = 1+ (max[2]-min[2])/translation_spacing;
+static constexpr double translation_spacing = .25;
+static constexpr unsigned x_nbuckets = unsigned(1+ (max[0]-min[0])/translation_spacing);
+static constexpr unsigned y_nbuckets = unsigned(1+ (max[1]-min[1])/translation_spacing);
+static constexpr unsigned z_nbuckets = unsigned(1+ (max[2]-min[2])/translation_spacing);
using vec6 = Mat<double, 6, 1>;
using mat66 = Mat<double, 6, 6>;
@@ -68,7 +68,7 @@ public:
mat66 get_coefficients() const;
unsigned sample_count() const;
- static constexpr inline unsigned min_samples = 25;
+ static constexpr unsigned min_samples = 25;
};
} // ns correlation_calibrator_impl
diff --git a/compat/enum-operators.hpp b/compat/enum-operators.hpp
index dc39f2f1..188a081d 100644
--- a/compat/enum-operators.hpp
+++ b/compat/enum-operators.hpp
@@ -5,24 +5,41 @@
#define OTR_FLAGS_OP2(type, op) \
inline type operator op (type a, type b) \
{ \
- using t__ = std::underlying_type_t<type>; \
- return static_cast<type>(t__((a)) op t__((b))); \
+ using t_ = std::underlying_type_t<type>; \
+ return type(t_((a)) op t_((b))); \
} // end
-#define OTR_FLAGS_SHIFT(type, op) \
- type operator op (type, unsigned) = delete
+#define OTR_FLAGS_DELETE_SHIFT(type, op) \
+ template<typename u> \
+ type operator op (type, u) = delete // end
#define OTR_FLAGS_OP1(type, op) \
inline type operator op (type x) \
{ \
- using t__ = std::underlying_type_t<type>; \
- return static_cast<type>(t__((x))); \
+ using t_ = std::underlying_type_t<type>; \
+ return type(op t_((x))); \
} // end
+#define OTR_FLAGS_ASSIGN_OP(type, op) \
+ inline type& operator op ## = (type& lhs, type rhs) \
+ { \
+ using t_ = std::underlying_type_t<decltype(rhs)>; \
+ lhs = type(t_((lhs)) op t_((rhs))); \
+ return lhs; \
+ } //end
+
+#define OTR_FLAGS_DELETE_SHIFT_ASSIGN(type, op) \
+ type operator op ## = (type& lhs, type rhs) = delete //end
+
#define DEFINE_ENUM_OPERATORS(type) \
OTR_FLAGS_OP2(type, |) \
OTR_FLAGS_OP2(type, &) \
OTR_FLAGS_OP2(type, ^) \
OTR_FLAGS_OP1(type, ~) \
- OTR_FLAGS_SHIFT(type, <<); \
- OTR_FLAGS_SHIFT(type, >>) // end
+ OTR_FLAGS_DELETE_SHIFT(type, <<); \
+ OTR_FLAGS_DELETE_SHIFT(type, >>); \
+ OTR_FLAGS_ASSIGN_OP(type, |) \
+ OTR_FLAGS_ASSIGN_OP(type, &) \
+ OTR_FLAGS_ASSIGN_OP(type, ^) \
+ OTR_FLAGS_DELETE_SHIFT_ASSIGN(type, <<); \
+ OTR_FLAGS_DELETE_SHIFT_ASSIGN(type, >>) // end
diff --git a/compat/library-path.hpp b/compat/library-path.hpp
index e14cf5e0..49e2c414 100644
--- a/compat/library-path.hpp
+++ b/compat/library-path.hpp
@@ -1,4 +1,4 @@
#pragma once
// from build directory
-#include "__opentrack-library-path.h"
+#include "opentrack-library-path.hxx"
diff --git a/compat/linkage-macros.hpp b/compat/linkage-macros.hpp
index dff9a34c..3a64648a 100644
--- a/compat/linkage-macros.hpp
+++ b/compat/linkage-macros.hpp
@@ -5,13 +5,13 @@
# define OTR_GENERIC_IMPORT __declspec(dllimport)
#elif defined _WIN32 && !defined __WINE__
# define OTR_GENERIC_EXPORT __attribute__((dllexport, visibility ("default")))
-# define OTR_GENERIC_IMPORT __attribute__((dllimport, visibility ("default")))
+# define OTR_GENERIC_IMPORT __attribute__((dllimport))
#else
# define OTR_GENERIC_EXPORT __attribute__((visibility ("default")))
-# define OTR_GENERIC_IMPORT __attribute__((visibility ("default")))
+# define OTR_GENERIC_IMPORT
#endif
-#if defined __APPLE__ || (defined __MINGW32__ && defined _WIN64)
+#if defined __APPLE__ || (defined __MINGW32__ && (defined __clang__ || defined _WIN64))
# define OTR_NO_TMPL_INST // link failure on both targets
#endif
diff --git a/compat/macros.hpp b/compat/macros.hpp
index 5d82c4ee..08be9b4a 100644
--- a/compat/macros.hpp
+++ b/compat/macros.hpp
@@ -1,46 +1,8 @@
#pragma once
-#if defined _MSC_VER
-# define cc_noinline __declspec(noinline)
-#else
-# define cc_noinline __attribute__((noinline))
-#endif
-
-#if defined _MSC_VER
-# define cc_forceinline __forceinline
-#else
-# define cc_forceinline __attribute__((always_inline))
-#endif
-
-#if !defined likely
-# if defined __GNUC__
-# define likely(x) __builtin_expect(!!(x),1)
-# define unlikely(x) __builtin_expect(!!(x),0)
-# else
-# define likely(x) (x)
-# define unlikely(x) (x)
-# endif
-#endif
+#include "macros1.h"
-#if defined _MSC_VER
-# define cc_function_name __FUNCSIG__
-#else
-# define cc_function_name __PRETTY_FUNCTION__
-#endif
-
-#if !defined PP_CAT
-# define PP_CAT(x,y) PP_CAT1(x,y)
-# define PP_CAT1(x,y) PP_CAT2(x,y)
-# define PP_CAT2(x,y) x ## y
-#endif
-
-#ifndef PP_EXPAND
-# define PP_EXPAND(x) PP_EXPAND__2(x)
-# define PP_EXPAND__2(x) PP_EXPAND__3(x) x
-# define PP_EXPAND__3(x) x
-#endif
-
-#if defined __cplusplus
+#ifdef __cplusplus
// from now only C++
@@ -59,45 +21,26 @@ template<typename t>
using remove_cvref_t = typename cxx20_compat::remove_cvref<t>::type;
template<typename t>
-using to_const_cvref_t = std::add_lvalue_reference_t<std::add_const_t<remove_cvref_t<t>>>;
+using to_const_ref_t = std::add_lvalue_reference_t<std::add_const_t<remove_cvref_t<t>>>;
// causes ICE in Visual Studio 2017 Preview. the ICE was reported and they handle them seriously in due time.
// the ICE is caused by decltype(auto) and const& return value
//#define eval_once(expr) ([&]() -> decltype(auto) { static decltype(auto) ret___1132 = (expr); return (decltype(ret___1132) const&) ret___1132; }())
-#define eval_once(expr) eval_once__2(expr, PP_CAT(_EVAL_ONCE__, __COUNTER__))
-#define eval_once__2(expr, ident) eval_once__3(expr, ident)
+#define eval_once(expr) eval_once2(expr, __COUNTER__)
-#define eval_once__3(expr, ident) \
- ([&]() -> decltype(auto) { \
- static auto INIT##ident = (expr); \
- return static_cast<to_const_cvref_t<decltype(INIT##ident)>>(INIT##ident); \
+#define eval_once2(expr, ctr) \
+ ([&] { \
+ [[maybe_unused]] \
+ static auto PP_CAT(init, ctr) = (((void)(expr)), 0); \
}())
-#include <type_traits>
-
template<typename t>
using cv_qualified = std::conditional_t<std::is_fundamental_v<remove_cvref_t<t>>,
remove_cvref_t<t>,
- to_const_cvref_t<t>>;
-
-template<bool>
-[[deprecated]] constexpr cc_forceinline void static_warn() {}
-
-template<>
-constexpr cc_forceinline void static_warn<true>() {}
+ to_const_ref_t<t>>;
-#define static_warning(cond) \
- static_warn<(cond)>(); \
-
-#define typed_progn(type, ...) ([&]() -> type { __VA_ARGS__ }())
#define progn(...) ([&]() -> decltype(auto) { __VA_ARGS__ }())
-#define prog1(x, ...) ([&]() -> decltype(auto) \
- { \
- decltype(auto) ret1324 = (x); __VA_ARGS__; return ret1324; \
- }())
-
// end c++-only macros
#endif
-
diff --git a/compat/macros1.h b/compat/macros1.h
new file mode 100644
index 00000000..915b8d29
--- /dev/null
+++ b/compat/macros1.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#if defined _MSC_VER
+# define never_inline __declspec(noinline)
+#else
+# define never_inline __attribute__((noinline))
+#endif
+
+#if defined _MSC_VER
+# define force_inline __forceinline
+#else
+# define force_inline __attribute__((always_inline))
+#endif
+
+#if !defined likely
+# if defined __GNUC__
+# define likely(x) __builtin_expect(!!(x),1)
+# define unlikely(x) __builtin_expect(!!(x),0)
+# else
+# define likely(x) (x)
+# define unlikely(x) (x)
+# endif
+#endif
+
+#if defined _MSC_VER
+# define function_name __FUNCSIG__
+#else
+# define function_name __PRETTY_FUNCTION__
+#endif
+
+#define PP_CAT(x,y) PP_CAT1(x,y)
+#define PP_CAT1(x,y) PP_CAT2(x,y)
+#define PP_CAT2(x,y) x ## y
+
+#define PP_EXPAND(x) PP_EXPAND2(x)
+#define PP_EXPAND2(x) PP_EXPAND3(x) x
+#define PP_EXPAND3(x) x
+
+#ifdef _MSC_VER
+# define unreachable() do { __assume(0); *(volatile int*)nullptr = 0; } while (0) /* NOLINT(clang-analyzer-core.NullDereference) */
+#else
+# define unreachable() do { __builtin_unreachable(); *(volatile int*)nullptr = 0; } while (0) /* NOLINT(clang-analyzer-core.NullDereference) */
+#endif
diff --git a/compat/math.hpp b/compat/math.hpp
index 656e10a8..b8cba8f2 100644
--- a/compat/math.hpp
+++ b/compat/math.hpp
@@ -50,7 +50,7 @@ template<typename t, typename u, typename v>
inline auto clamp(const t& val, const u& min, const v& max)
{
using w = cv_qualified<decltype(val + min + max)>;
- return ::util_detail::clamp<w>::clamp_(val, min, max);
+ return util_detail::clamp<w>::clamp_(val, min, max);
}
template<typename t>
@@ -66,7 +66,7 @@ inline auto uround(t val) -> std::enable_if_t<std::is_floating_point_v<remove_cv
}
template <typename t>
-static cc_forceinline constexpr int signum(const t& x)
+static force_inline constexpr int signum(const t& x)
{
return x < t{0} ? -1 : 1;
}
diff --git a/compat/mutex.cpp b/compat/mutex.cpp
new file mode 100644
index 00000000..664677ea
--- /dev/null
+++ b/compat/mutex.cpp
@@ -0,0 +1,33 @@
+#include "mutex.hpp"
+#include <cstdlib>
+
+mutex& mutex::operator=(const mutex& rhs)
+{
+ if (rhs->isRecursive() != inner.isRecursive())
+ std::abort();
+
+ return *this;
+}
+
+mutex::mutex(const mutex& datum) : mutex{datum.inner.isRecursive() ? Recursive : NonRecursive}
+{
+}
+
+mutex::mutex(RecursionMode m) : inner{m}
+{
+}
+
+QMutex* mutex::operator&() const noexcept
+{
+ return &inner;
+}
+
+mutex::operator QMutex*() const noexcept
+{
+ return &inner;
+}
+
+QMutex* mutex::operator->() const noexcept
+{
+ return &inner;
+}
diff --git a/compat/mutex.hpp b/compat/mutex.hpp
new file mode 100644
index 00000000..54758a08
--- /dev/null
+++ b/compat/mutex.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <QMutex>
+
+#include "export.hpp"
+
+class OTR_COMPAT_EXPORT mutex
+{
+ mutable QMutex inner;
+
+public:
+ using RecursionMode = QMutex::RecursionMode;
+ static constexpr RecursionMode Recursive = RecursionMode::Recursive;
+ static constexpr RecursionMode NonRecursive = RecursionMode::NonRecursive;
+
+ mutex& operator=(const mutex& datum);
+ mutex(const mutex& datum);
+ explicit mutex(RecursionMode m);
+ mutex() : mutex{NonRecursive} {}
+
+ QMutex* operator&() const noexcept;
+ explicit operator QMutex*() const noexcept;
+ QMutex* operator->() const noexcept;
+};
diff --git a/compat/qt-signal.cpp b/compat/qt-signal.cpp
new file mode 100644
index 00000000..08aac663
--- /dev/null
+++ b/compat/qt-signal.cpp
@@ -0,0 +1,13 @@
+#include "qt-signal.hpp"
+
+namespace qt_sig {
+
+nullary::nullary(QObject* parent) : QObject(parent) {}
+nullary::~nullary() = default;
+
+void nullary::operator()() const
+{
+ notify();
+}
+
+} // ns qt_sig
diff --git a/compat/qt-signal.hpp b/compat/qt-signal.hpp
new file mode 100644
index 00000000..119e063c
--- /dev/null
+++ b/compat/qt-signal.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+// this is to avoid dealing with QMetaObject for the time being -sh 20190203
+
+#include "export.hpp"
+#include <QObject>
+
+namespace qt_sig {
+
+class OTR_COMPAT_EXPORT nullary : public QObject
+{
+ Q_OBJECT
+
+public:
+ template<typename t, typename F>
+ nullary(t* datum, F&& f, Qt::ConnectionType conntype = Qt::AutoConnection) : QObject(datum)
+ {
+ connect(this, &nullary::notify, datum, f, conntype);
+ }
+
+ nullary(QObject* parent = nullptr);
+ ~nullary() override;
+
+ void operator()() const;
+
+signals:
+ void notify() const;
+};
+
+} // ns qt_sig
diff --git a/compat/run-in-thread.hpp b/compat/run-in-thread.hpp
index afe279f2..b8ffc179 100644
--- a/compat/run-in-thread.hpp
+++ b/compat/run-in-thread.hpp
@@ -53,7 +53,7 @@ struct run_in_thread_traits<void>
}
template<typename F>
-auto cc_noinline
+auto never_inline
run_in_thread_sync(QObject* obj, F&& fun)
-> typename qt_impl_detail::run_in_thread_traits<decltype(fun())>::ret_type
{
@@ -108,8 +108,8 @@ template<typename F>
void run_in_thread_async(QObject* obj, F&& fun)
{
QObject src;
- QThread* t(obj->thread());
- assert(t);
+ QThread* t = obj->thread();
+ if (!t) abort();
src.moveToThread(t);
QObject::connect(&src, &QObject::destroyed, obj, std::move(fun), Qt::AutoConnection);
}
diff --git a/compat/shm.cpp b/compat/shm.cpp
index 791cb303..1f863190 100644
--- a/compat/shm.cpp
+++ b/compat/shm.cpp
@@ -15,7 +15,7 @@
#include <accctrl.h>
#include <aclapi.h>
-#if !defined __WINE__
+#ifdef QT_CORE_LIB
# include <QDebug>
# define warn(str, ...) (qDebug() << "shm:" str ": " << __VA_ARGS__)
#else
diff --git a/compat/shm.h b/compat/shm.h
index 814ce90c..5ea6c80a 100644
--- a/compat/shm.h
+++ b/compat/shm.h
@@ -32,10 +32,10 @@ class OTR_COMPAT_EXPORT shm_wrapper final
#endif
public:
- cc_noinline shm_wrapper(const char *shm_name, const char *mutex_name, int map_size);
- cc_noinline ~shm_wrapper();
- cc_noinline bool lock();
- cc_noinline bool unlock();
- cc_noinline bool success();
+ never_inline shm_wrapper(const char *shm_name, const char *mutex_name, int map_size);
+ never_inline ~shm_wrapper();
+ never_inline bool lock();
+ never_inline bool unlock();
+ never_inline bool success();
inline void* ptr() { return mem; }
};
diff --git a/compat/simple-mat.hpp b/compat/simple-mat.hpp
index 87e1ae83..43d136f9 100644
--- a/compat/simple-mat.hpp
+++ b/compat/simple-mat.hpp
@@ -8,13 +8,11 @@
#pragma once
-#include "export.hpp"
-
#include <type_traits>
#include <utility>
#include <cmath>
-namespace simple_mat_detail {
+namespace simple_mat {
// last param to fool SFINAE into overloading
template<int i, int j, int>
struct equals
@@ -67,73 +65,63 @@ public:
// parameters w_ and h_ are rebound so that SFINAE occurs
// removing them causes a compile-time error -sh 20150811
- template<int Q = w_> std::enable_if_t<equals<Q, 1, 0>::value, num>
- constexpr inline operator()(unsigned i) const& { return data[i][0]; }
+ template<typename t, int Q = w_> std::enable_if_t<equals<Q, 1, 0>::value, num>
+ constexpr inline operator()(t i) const& { return data[(unsigned)i][0]; }
- template<int P = h_> std::enable_if_t<equals<P, 1, 1>::value, num>
- constexpr inline operator()(unsigned i) const& { return data[0][i]; }
+ template<typename t, int P = h_> std::enable_if_t<equals<P, 1, 1>::value, num>
+ constexpr inline operator()(t i) const& { return data[0][(unsigned)i]; }
- template<int Q = w_> std::enable_if_t<equals<Q, 1, 2>::value, num&>
- constexpr inline operator()(unsigned i) & { return data[i][0]; }
+ template<typename t, int Q = w_> std::enable_if_t<equals<Q, 1, 2>::value, num&>
+ constexpr inline operator()(t i) & { return data[(unsigned)i][0]; }
- template<int P = h_> std::enable_if_t<equals<P, 1, 3>::value, num&>
- constexpr inline operator()(unsigned i) & { return data[0][i]; }
+ template<typename t, int P = h_> std::enable_if_t<equals<P, 1, 3>::value, num&>
+ constexpr inline operator()(t i) & { return data[0][(unsigned)i]; }
-#define OPENTRACK_ASSERT_SWIZZLE static_assert(P == h_ && Q == w_)
+#define OTR_MAT_ASSERT_SWIZZLE static_assert(P == h_ && Q == w_)
// const variants
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 1, 4>::value, num>
- constexpr inline x() const& { OPENTRACK_ASSERT_SWIZZLE; return operator()(0); }
+ constexpr inline x() const& { OTR_MAT_ASSERT_SWIZZLE; return operator()(0); }
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 2, 4>::value, num>
- constexpr inline y() const& { OPENTRACK_ASSERT_SWIZZLE; return operator()(1); }
+ constexpr inline y() const& { OTR_MAT_ASSERT_SWIZZLE; return operator()(1); }
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 3, 4>::value, num>
- constexpr inline z() const& { OPENTRACK_ASSERT_SWIZZLE; return operator()(2); }
+ constexpr inline z() const& { OTR_MAT_ASSERT_SWIZZLE; return operator()(2); }
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 4, 4>::value, num>
- constexpr inline w() const& { OPENTRACK_ASSERT_SWIZZLE; return operator()(3); }
+ constexpr inline w() const& { OTR_MAT_ASSERT_SWIZZLE; return operator()(3); }
// mutable variants
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 1, 4>::value, num&>
- constexpr inline x() & { OPENTRACK_ASSERT_SWIZZLE; return operator()(0); }
+ constexpr inline x() & { OTR_MAT_ASSERT_SWIZZLE; return operator()(0); }
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 2, 4>::value, num&>
- constexpr inline y() & { OPENTRACK_ASSERT_SWIZZLE; return operator()(1); }
+ constexpr inline y() & { OTR_MAT_ASSERT_SWIZZLE; return operator()(1); }
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 3, 4>::value, num&>
- constexpr inline z() & { OPENTRACK_ASSERT_SWIZZLE; return operator()(2); }
+ constexpr inline z() & { OTR_MAT_ASSERT_SWIZZLE; return operator()(2); }
template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 4, 4>::value, num&>
- constexpr inline w() & { OPENTRACK_ASSERT_SWIZZLE; return operator()(3); }
-
- template<int h_pos, int w_pos>
- constexpr Mat<num, h_ - h_pos, w_ - w_pos> slice() const
- {
- return (const double*)*this;
- }
-
- template<int off> std::enable_if_t<equals<h_, 1, 0>::value, Mat<num, 1, w_ - off>>
- slice() const { return ((double const*)*this) + off; }
-
- template<int off> std::enable_if_t<!equals<h_, 1, 2>::value && equals<w_, 1, 1>::value,
- Mat<num, h_ - off, 1>>
- slice() const { return ((double const*)*this) + off; }
+ constexpr inline w() & { OTR_MAT_ASSERT_SWIZZLE; return operator()(3); }
template<int P = h_, int Q = w_>
- std::enable_if_t<is_vector<P, Q>::value, num>
- norm() const
+ constexpr auto norm_squared() const -> std::enable_if_t<is_vector<P, Q>::value, num>
{
static_assert(P == h_ && Q == w_);
const num val = dot(*this);
+ constexpr num eps = num(1e-4);
- if (val < num(1e-4))
+ if (val < eps)
return num(0);
else
- return std::sqrt(val);
+ return val;
}
+ template<int P = h_, int Q = w_>
+ inline auto norm() const { return num(std::sqrt(norm_squared())); }
+
template<int R, int S, int P = h_, int Q = w_>
std::enable_if_t<is_vector_pair<R, S, P, Q>::value, num>
constexpr dot(const Mat<num, R, S>& p2) const
@@ -152,7 +140,7 @@ public:
constexpr cross(const Mat<num, R, S>& b) const
{
static_assert(P == h_ && Q == w_);
- auto& a = *this;
+ const auto& a = *this;
return Mat<num, R, S>(a.y()*b.z() - a.z()*b.y(),
a.z()*b.x() - a.x()*b.z(),
@@ -221,15 +209,10 @@ public:
}
template<typename t, typename u>
- constexpr inline num operator()(t j, u i) const& { return data[(int) j][(int) i]; }
+ constexpr inline num operator()(t j, u i) const& { return data[(unsigned)j][(unsigned)i]; }
template<typename t, typename u>
- constexpr inline num& operator()(t j, u i) & { return data[(int) j][(int) i]; }
-
-#ifdef __GNUG__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmissing-braces"
-#endif
+ constexpr inline num& operator()(t j, u i) & { return data[(unsigned)j][(unsigned)i]; }
template<typename... ts, int h__ = h_, int w__ = w_,
typename = std::enable_if_t<is_arglist_correct<num, h__, w__, ts...>::value>>
@@ -238,10 +221,6 @@ public:
static_assert(h__ == h_ && w__ == w_);
}
-#ifdef __GNUG__
-# pragma GCC diagnostic pop
-#endif
-
constexpr Mat()
{
for (int j = 0; j < h_; j++)
@@ -256,8 +235,8 @@ public:
data[j][i] = mem[i*h_+j];
}
- operator num*() { return reinterpret_cast<num*>(data); }
- operator const num*() const { return reinterpret_cast<const num*>(data); }
+ constexpr operator num*() & { return (num*)data; }
+ constexpr operator const num*() const& { return (const num*)data; }
// XXX add more operators as needed, third-party dependencies mostly
// not needed merely for matrix algebra -sh 20141030
@@ -288,6 +267,15 @@ public:
return ret;
}
+
+ constexpr Mat<num, w_, h_>& operator=(const Mat<num, w_, h_>& rhs)
+ {
+ for (unsigned j = 0; j < h_; j++)
+ for (unsigned i = 0; i < w_; i++)
+ data[j][i] = rhs(j, i);
+
+ return *this;
+ }
};
template<typename num, int h, int w>
@@ -318,9 +306,7 @@ OTR_GENERIC_EXPORT inline void test()
}
#endif
-} // ns simple_mat_detail
+} // ns detail
template<typename num, int h, int w>
-using Mat = simple_mat_detail::Mat<num, h, w>;
-
-
+using Mat = simple_mat::Mat<num, h, w>;
diff --git a/compat/sleep.cpp b/compat/sleep.cpp
index 5178ae2f..e64e6254 100644
--- a/compat/sleep.cpp
+++ b/compat/sleep.cpp
@@ -14,7 +14,7 @@ namespace portable
{
#ifdef _WIN32
- Sleep(milliseconds);
+ Sleep((unsigned)milliseconds);
#else
usleep(unsigned(milliseconds) * 1000U); // takes microseconds
#endif
diff --git a/compat/sysexits.hpp b/compat/sysexits.hpp
index 33f19b9d..6747fc88 100644
--- a/compat/sysexits.hpp
+++ b/compat/sysexits.hpp
@@ -2,13 +2,27 @@
#include <cstdlib> // for EXIT_SUCCESS, EXIT_FAILRUE
-/* FreeBSD sysexits(3)
- *
- * The input data was incorrect in some way. This
- * should only be used for user's data and not system
- * files.
- */
-
-#if !defined EX_OSFILE
-# define EX_OSFILE 72
+#ifndef _WIN32
+# include <sysexits.h>
+#else
+// this conforms to BSD sysexits(3)
+// reference the manual page on FreeBSD or Linux for semantics
+# define EX_OK 0
+# define EX_USAGE 64
+# define EX_DATAERR 65
+# define EX_NOINPUT 66
+# define EX_NOUSER 67
+# define EX_NOHOST 68
+# define EX_UNAVAILABLE 69
+# define EX_SOFTWARE 70
+# define EX_OSERR 71
+# define EX_OSFILE 72
+# define EX_CANTCREAT 73
+# define EX_IOERR 74
+# define EX_TEMPFAIL 75
+# define EX_PROTOCOL 76
+# define EX_NOPERM 77
+# define EX_CONFIG 78
#endif
+
+
diff --git a/compat/timer.cpp b/compat/timer.cpp
index 15e9d8a4..b46ebe4a 100644
--- a/compat/timer.cpp
+++ b/compat/timer.cpp
@@ -6,6 +6,8 @@
* notice appear in all copies.
*/
+#undef NDEBUG
+
#include "timer.hpp"
#include <cassert>
#include <cmath>
diff --git a/compat/warn.hpp b/compat/warn.hpp
deleted file mode 100644
index 7f3e21d0..00000000
--- a/compat/warn.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include "macros.hpp"
-
-#include <sstream>
-#include <iostream>
-#include <locale>
-#include <utility>
-
-#include <string>
-
-namespace warn_detail {
-template<typename t> using basic_string_stream = std::basic_ostringstream<t, std::char_traits<t>, std::allocator<t>>;
-using string_stream = basic_string_stream<wchar_t>;
-
-cc_forceinline void do_warn(string_stream&) {}
-
-template<typename x, typename... xs>
-cc_forceinline void do_warn(string_stream& acc, const x& datum, const xs&... rest)
-{
- acc << datum;
- if (sizeof...(rest) > 0u)
- acc << L' ';
- do_warn(acc, rest...);
-}
-
-template<typename... xs>
-cc_noinline void warn_(const char* file, int line, const char* level, const xs&... seq)
-{
- using namespace warn_detail;
- string_stream stream;
-
- do_warn(stream, seq...);
-
- std::wcerr << L'[' << level << L' '
- << file << L':' << line
- << L"] "
- << std::boolalpha
- << stream.str()
- << L'\n';
- std::wcerr.flush();
-}
-
-} // ns warn_detail
-
-// todo add runtime loglevel
-
-#define otr_impl_warn_base(level, ...) \
- (warn_detail::warn_(__FILE__, __LINE__, (level), __VA_ARGS__))
-
-#define dbg_warn(...) \
- otr_impl_warn_base("WARN", __VA_ARGS__)
-
-#define dbg_log(...) \
- otr_impl_warn_base("INFO", __VA_ARGS__)
-
-#define dbg_crit(...) \
- otr_impl_warn_base("CRIT", __VA_ARGS__)
-
-#include <cstdlib>
-
-#define dbg_fatal(...) \
- do \
- { \
- otr_impl_warn_base("FATAL", __VA_ARGS__); \
- std::abort(); \
- } while (0)