diff -r 568fcfc6da71 -r 39d7a9642eea src/basics.h --- a/src/basics.h Sat Mar 24 11:05:40 2018 +0200 +++ b/src/basics.h Sat Mar 24 11:57:24 2018 +0200 @@ -17,68 +17,37 @@ */ #pragma once -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include "macros.h" -#include "transform.h" +#include +#include +#include +#include +#include +#include +#include +#include "generics/functions.h" -#if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) -template -struct QNonConstOverload -{ - template - Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr) - { return ptr; } - template - static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr) - { return ptr; } -}; -template -struct QConstOverload -{ - template - Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr) - { return ptr; } - template - static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr) - { return ptr; } -}; -template -struct QOverload : QConstOverload, QNonConstOverload -{ - using QConstOverload::of; - using QConstOverload::operator(); - using QNonConstOverload::of; - using QNonConstOverload::operator(); - template - Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr) - { return ptr; } - template - static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr) - { return ptr; } -}; -template Q_CONSTEXPR Q_DECL_UNUSED QOverload qOverload = {}; -template Q_CONSTEXPR Q_DECL_UNUSED QConstOverload qConstOverload = {}; -template Q_CONSTEXPR Q_DECL_UNUSED QNonConstOverload qNonConstOverload = {}; +#ifndef __GNUC__ +# define __attribute__(X) #endif -class Matrix; -struct Vertex; +#define DEFINE_CLASS(SELF, SUPER) \ +public: \ + using Self = SELF; \ + using Super = SUPER; + +// TODO: get rid of this +#ifdef WIN32 +# define DIRSLASH "\\" +# define DIRSLASH_CHAR '\\' +#else // WIN32 +# define DIRSLASH "/" +# define DIRSLASH_CHAR '/' +#endif // WIN32 + using GLRotationMatrix = QMatrix4x4; -template -using Pair = std::pair; - enum Axis { X, @@ -93,346 +62,41 @@ Clockwise, }; -Winding operator^(Winding one, Winding other); -Winding& operator^=(Winding& one, Winding other); +/* + * Special operator definition that implements the XOR operator for windings. + * However, if either winding is NoWinding, then this function returns NoWinding. + */ +inline Winding operator^(Winding one, Winding other) +{ + if (one == NoWinding or other == NoWinding) + return NoWinding; + else + return static_cast(static_cast(one) ^ static_cast(other)); +} +inline Winding& operator^=(Winding& one, Winding other) +{ + one = one ^ other; + return one; +} + +static const double pi = 3.14159265358979323846; + +/* + * Returns the norm of a vector. + */ static inline qreal abs(const QVector3D &vector) { return vector.length(); } -static const double pi = 3.14159265358979323846; - - -// ============================================================================= -// Plural expression -template -static inline const char* plural (T n) -{ - return (n != 1) ? "s" : ""; -} - -template -bool isZero (T a) -{ - return qFuzzyCompare (a + 1.0, 1.0); -} - -template -bool isInteger (T a) -{ - return (qAbs (a - floor(a)) < 0.00001) or (qAbs (a - ceil(a)) < 0.00001); -} - -// -// Returns true if first arg is equal to any of the other args -// -template -bool isOneOf (T const& a, Arg const& arg, Args const&... args) -{ - if (a == arg) - return true; - - return isOneOf (a, args...); -} - -template -bool isOneOf (T const&) -{ - return false; -} - -inline void toggle (bool& a) -{ - a = not a; -} - -// -// Iterates an enum -// -template -struct EnumIterShell -{ - struct Iterator - { - Iterator(typename std::underlying_type::type i) : - i(i) {} - - Iterator& operator++() { ++i; return *this; } - bool operator==(Iterator other) { return i == other.i; } - bool operator!=(Iterator other) { return i != other.i; } - Enum operator*() const { return Enum(i); } - - typename std::underlying_type::type i; - }; - - Iterator begin() - { - return Iterator(EnumLimits::First); - }; - - Iterator end() - { - return Iterator(EnumLimits::Last + 1); - } -}; - -template -EnumIterShell iterateEnum() -{ - return EnumIterShell(); -} - -// Is a value inside an enum? -template -bool valueInEnum(Enum enumerator) -{ - typename std::underlying_type::type index = static_cast::type>(enumerator); - return index >= EnumLimits::First and index <= EnumLimits::Last; -} - -double getRadialPoint(int segment, int divisions, double(*func)(double)); -QVector makeCircle(int segments, int divisions, double radius); -qreal distanceFromPointToRectangle(const QPointF& point, const QRectF& rectangle); - -/* - * Implements a ring adapter over T. This class corrects indices given to the element-operator so that they're within bounds. - * The maximum amount can be specified manually. - * - * Example: - * - * int A[] = {10,20,30,40}; - * ring(A)[0] == A[0 % 4] == A[0] - * ring(A)[5] == A[5 % 4] == A[1] - * ring(A)[-1] == ring(A)[-1 + 4] == A[3] - */ -template -class RingAdapter -{ -private: - // The private section must come first because _collection is used in decltype() below. - T& _collection; - const int _count; - -public: - RingAdapter(T& collection, int count) : - _collection {collection}, - _count {count} {} - - template - decltype(_collection[IndexType()]) operator[](IndexType index) - { - if (_count == 0) - { - // Argh! ...let the collection deal with this case. - return _collection[0]; - } - else - { - index %= _count; - - // Fix negative modulus... - if (index < 0) - index += _count; - - return _collection[index]; - } - } - - int size() const - { - return _count; - } -}; - -/* - * Casts a reference to an enum into a reference to its underlying integer type. - */ -template -typename std::underlying_type::type& enum_cast(T& enu) -{ - return *reinterpret_cast::type*>(&enu); -} - -/* - * Convenience function for RingAdapter so that the template parameter does not have to be provided. The ring amount is assumed - * to be the amount of elements in the collection. - */ -template -RingAdapter ring(T& collection) -{ - return RingAdapter {collection, countof(collection)}; -} +using ApplyToMatrixFunction = std::function; +using ApplyToMatrixConstFunction = std::function; -/* - * Version of ring() that allows manual specification of the count. - */ -template -RingAdapter ring(T& collection, int count) -{ - return RingAdapter {collection, count}; -} - -struct Library -{ - QString path; - enum - { - ReadOnlyStorage, // for official files, etc - UnofficialFiles, // put downloaded files here - WorkingDirectory, // for editable documents - } role = ReadOnlyStorage; - - bool operator==(const Library& other) const - { - return (this->path == other.path) and (this->role == other.role); - } -}; - -Q_DECLARE_METATYPE(Library) -using Libraries = QVector; - -QDataStream& operator<<(QDataStream& out, const Library& library); -QDataStream& operator>>(QDataStream& in, Library& library); - -// -// Get the amount of elements in something. -// -template -int countof(T(&)[N]) -{ - return N; -} - -static inline int countof(const QString& string) -{ - return string.length(); -} - -template -int countof(const QVector& vector) -{ - return vector.size(); -} - -template -int countof(const QList& vector) -{ - return vector.size(); -} - -template -int countof(const QSet& set) -{ - return set.size(); -} - -template -int countof(const std::initializer_list& vector) -{ - return vector.size(); -} - -template -int countof(const RingAdapter& ring) -{ - return ring.size(); -} - -/* - * Extracts the sign of x. - */ -template -T sign(T x) -{ - if (isZero(x)) - return {}; - else - return x / qAbs(x); -} - -template<> -inline int sign(int x) -{ - if (x == 0) - return 0; - else - return x / qAbs(x); -} - -/* - * Returns the maximum of a single parameter (the parameter itself). - */ -template -T max(T a) -{ - return a; -} - -/* - * Returns the maximum of two parameters. - */ -template -T max(T a, T b) -{ - return a > b ? a : b; -} - -/* - * Returns the maximum of n parameters. - */ -template -T max(T a, Rest&&... rest) -{ - return max(a, max(rest...)); -} - -/* - * Returns the minimum of a single parameter (the parameter itself). - */ -template -T min(T a) -{ - return a; -} - -/* - * Returns the minimum of two parameters. - */ -template -T min(T a, T b) -{ - return a < b ? a : b; -} - -/* - * Returns the minimum of n parameters. - */ -template -T min(T a, Rest&&... rest) -{ - return min(a, min(rest...)); -} - -/* - * Assigns the value of a single flag in a flagset - */ -template -void assignFlag(QFlags& flagset, bool value) -{ - if (value) - flagset |= static_cast(Flag); - else - flagset &= ~static_cast(Flag); -} - -/* - * Returns a singleton of type T, useful for providing a valid but unused - * pointer. - */ -template -inline T& sink() -{ - static T result; - return result; -} +void applyToMatrix(class Matrix& a, ApplyToMatrixFunction func); +void applyToMatrix(const class Matrix& a, ApplyToMatrixConstFunction func); +QString formatFileSize(qint64 size); +int gcd(int a, int b); +QString joinStrings(const QList& values, QString delimeter = " "); +void roundToDecimals(double& value, int decimals); +void simplify(int& numerator, int& denominator);