diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/activation-context.cpp | 51 | ||||
-rw-r--r-- | compat/activation-context.hpp | 26 | ||||
-rw-r--r-- | compat/arch.hpp | 50 | ||||
-rw-r--r-- | compat/base-path.cpp | 4 | ||||
-rw-r--r-- | compat/base-path.hpp | 3 | ||||
-rw-r--r-- | compat/check-visible.cpp | 92 | ||||
-rw-r--r-- | compat/check-visible.hpp | 11 | ||||
-rw-r--r-- | compat/copyable-mutex.cpp | 33 | ||||
-rw-r--r-- | compat/copyable-mutex.hpp | 27 | ||||
-rw-r--r-- | compat/correlation-calibrator.cpp | 31 | ||||
-rw-r--r-- | compat/correlation-calibrator.hpp | 26 | ||||
-rw-r--r-- | compat/enum-operators.hpp | 33 | ||||
-rw-r--r-- | compat/library-path.hpp | 2 | ||||
-rw-r--r-- | compat/linkage-macros.hpp | 6 | ||||
-rw-r--r-- | compat/macros.hpp | 75 | ||||
-rw-r--r-- | compat/macros1.h | 43 | ||||
-rw-r--r-- | compat/math.hpp | 4 | ||||
-rw-r--r-- | compat/mutex.cpp | 33 | ||||
-rw-r--r-- | compat/mutex.hpp | 24 | ||||
-rw-r--r-- | compat/qt-signal.cpp | 13 | ||||
-rw-r--r-- | compat/qt-signal.hpp | 30 | ||||
-rw-r--r-- | compat/run-in-thread.hpp | 6 | ||||
-rw-r--r-- | compat/shm.cpp | 2 | ||||
-rw-r--r-- | compat/shm.h | 10 | ||||
-rw-r--r-- | compat/simple-mat.hpp | 96 | ||||
-rw-r--r-- | compat/sleep.cpp | 2 | ||||
-rw-r--r-- | compat/sysexits.hpp | 32 | ||||
-rw-r--r-- | compat/timer.cpp | 2 | ||||
-rw-r--r-- | compat/warn.hpp | 67 |
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) |