This will let us detect problems with unused return values. For instance,
if you don’t remember that normalize(q) returns a pointer and expect it
to modify the object, you’ll get this warning:
warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
quat q(1,2,3,4); normalize(q);
^~~~~~~~~ ~
legacy
| @@ -50,7 +50,7 @@ enum class SortAlgorithm : uint8_t | |||||
| * m_count are allocated. The rest is uninitialised memory. | * m_count are allocated. The rest is uninitialised memory. | ||||
| */ | */ | ||||
| template<typename T, typename ARRAY> class array_base | |||||
| template<typename T, typename ARRAY> class LOL_ATTR_NODISCARD array_base | |||||
| { | { | ||||
| public: | public: | ||||
| typedef T element_t; | typedef T element_t; | ||||
| @@ -53,11 +53,17 @@ | |||||
| #undef LOL_FEATURE_CXX17_ATTRIBUTE_NODISCARD | #undef LOL_FEATURE_CXX17_ATTRIBUTE_NODISCARD | ||||
| /* Features detected through __has_cpp_attribute */ | |||||
| #ifdef __has_cpp_attribute | |||||
| # if __has_cpp_attribute(deprecated) | |||||
| # define LOL_FEATURE_CXX17_ATTRIBUTE_NODISCARD 1 | |||||
| # endif | |||||
| #endif | |||||
| /* Features supported by GCC */ | /* Features supported by GCC */ | ||||
| #if defined __GNUC__ | #if defined __GNUC__ | ||||
| # define LOL_FEATURE_CXX11_UNRESTRICTED_UNIONS 1 | # define LOL_FEATURE_CXX11_UNRESTRICTED_UNIONS 1 | ||||
| # define LOL_FEATURE_CXX11_INHERIT_CONSTRUCTORS 1 | # define LOL_FEATURE_CXX11_INHERIT_CONSTRUCTORS 1 | ||||
| # define LOL_FEATURE_CXX17_ATTRIBUTE_NODISCARD 1 | |||||
| # if defined(__GXX_EXPERIMENTAL_CXX0X) || __cplusplus >= 201103L | # if defined(__GXX_EXPERIMENTAL_CXX0X) || __cplusplus >= 201103L | ||||
| # define LOL_FEATURE_CXX11_CONSTEXPR 1 | # define LOL_FEATURE_CXX11_CONSTEXPR 1 | ||||
| # define LOL_FEATURE_CXX11_ISNAN 1 | # define LOL_FEATURE_CXX11_ISNAN 1 | ||||
| @@ -75,7 +81,6 @@ | |||||
| # define LOL_FEATURE_CXX11_UNRESTRICTED_UNIONS 1 | # define LOL_FEATURE_CXX11_UNRESTRICTED_UNIONS 1 | ||||
| # define LOL_FEATURE_CXX11_INHERIT_CONSTRUCTORS 1 | # define LOL_FEATURE_CXX11_INHERIT_CONSTRUCTORS 1 | ||||
| # define LOL_FEATURE_CXX11_ARRAY_INITIALIZERS 1 | # define LOL_FEATURE_CXX11_ARRAY_INITIALIZERS 1 | ||||
| # define LOL_FEATURE_CXX17_ATTRIBUTE_NODISCARD 1 | |||||
| # if __has_feature(cxx_constexpr) | # if __has_feature(cxx_constexpr) | ||||
| # define LOL_FEATURE_CXX11_CONSTEXPR 1 | # define LOL_FEATURE_CXX11_CONSTEXPR 1 | ||||
| # endif | # endif | ||||
| @@ -104,7 +109,6 @@ | |||||
| /* Still unsupported as of VS 2015 (TODO: check VS2017) */ | /* Still unsupported as of VS 2015 (TODO: check VS2017) */ | ||||
| # undef LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | # undef LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
| # undef LOL_FEATURE_CXX11_CONSTEXPR | # undef LOL_FEATURE_CXX11_CONSTEXPR | ||||
| # undef LOL_FEATURE_CXX17_ATTRIBUTE_NODISCARD | |||||
| #endif | #endif | ||||
| @@ -28,19 +28,19 @@ | |||||
| namespace lol | namespace lol | ||||
| { | { | ||||
| class String : protected array<char> | |||||
| class LOL_ATTR_NODISCARD String : protected array<char> | |||||
| { | { | ||||
| private: | private: | ||||
| typedef array<char> super; | typedef array<char> super; | ||||
| public: | public: | ||||
| inline LOL_ATTR_NODISCARD String() | |||||
| inline String() | |||||
| : super() | : super() | ||||
| { | { | ||||
| push('\0'); | push('\0'); | ||||
| } | } | ||||
| inline LOL_ATTR_NODISCARD String(char const *str) | |||||
| inline String(char const *str) | |||||
| : super() | : super() | ||||
| { | { | ||||
| using namespace std; | using namespace std; | ||||
| @@ -49,7 +49,7 @@ public: | |||||
| memcpy(&(*this)[0], str, count() + 1); | memcpy(&(*this)[0], str, count() + 1); | ||||
| } | } | ||||
| inline LOL_ATTR_NODISCARD String(char const *str, int item_count) | |||||
| inline String(char const *str, int item_count) | |||||
| : super() | : super() | ||||
| { | { | ||||
| using namespace std; | using namespace std; | ||||
| @@ -59,7 +59,7 @@ public: | |||||
| ((super &)*this)[item_count] = '\0'; | ((super &)*this)[item_count] = '\0'; | ||||
| } | } | ||||
| inline LOL_ATTR_NODISCARD String(String const &s) | |||||
| inline String(String const &s) | |||||
| : super((super const &)s) | : super((super const &)s) | ||||
| { | { | ||||
| } | } | ||||
| @@ -268,13 +268,13 @@ public: | |||||
| return true; | return true; | ||||
| } | } | ||||
| inline LOL_ATTR_NODISCARD String operator +(String const &s) const | |||||
| inline String operator +(String const &s) const | |||||
| { | { | ||||
| String ret(*this); | String ret(*this); | ||||
| return ret += s; | return ret += s; | ||||
| } | } | ||||
| inline LOL_ATTR_NODISCARD String operator +(char c) const | |||||
| inline String operator +(char c) const | |||||
| { | { | ||||
| String ret(*this); | String ret(*this); | ||||
| return ret += c; | return ret += c; | ||||
| @@ -338,12 +338,12 @@ public: | |||||
| static String vformat(char const *format, va_list ap); | static String vformat(char const *format, va_list ap); | ||||
| }; | }; | ||||
| inline LOL_ATTR_NODISCARD String operator +(char c, String const &s) | |||||
| inline String operator +(char c, String const &s) | |||||
| { | { | ||||
| return String() + c + s; | return String() + c + s; | ||||
| } | } | ||||
| inline LOL_ATTR_NODISCARD String operator +(char const *sz, String const &s) | |||||
| inline String operator +(char const *sz, String const &s) | |||||
| { | { | ||||
| return String(sz) + s; | return String(sz) + s; | ||||
| } | } | ||||
| @@ -36,7 +36,6 @@ namespace lol | |||||
| //VertexUsageBase ------------------------------------------------------------- | //VertexUsageBase ------------------------------------------------------------- | ||||
| struct VertexUsageBase : public StructSafeEnum | struct VertexUsageBase : public StructSafeEnum | ||||
| { | { | ||||
| enum Type | enum Type | ||||
| { | { | ||||
| Position, | Position, | ||||
| @@ -56,6 +55,7 @@ struct VertexUsageBase : public StructSafeEnum | |||||
| Sample, | Sample, | ||||
| MAX, | MAX, | ||||
| }; | }; | ||||
| protected: | protected: | ||||
| virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | virtual bool BuildEnumMap(map<int64_t, String>& enum_map) | ||||
| { | { | ||||
| @@ -91,13 +91,13 @@ public: | |||||
| void SetWrap(WrapMode wrap_x, WrapMode wrap_y); | void SetWrap(WrapMode wrap_x, WrapMode wrap_y); | ||||
| /* Lock continuous arrays of pixels for writing */ | /* Lock continuous arrays of pixels for writing */ | ||||
| template<PixelFormat T> typename PixelType<T>::type *lock(); | |||||
| void *lock(); | |||||
| template<PixelFormat T> LOL_ATTR_NODISCARD typename PixelType<T>::type *lock(); | |||||
| LOL_ATTR_NODISCARD void *lock(); | |||||
| void unlock(void const *pixels); | void unlock(void const *pixels); | ||||
| /* Lock 2D arrays of pixels for writing */ | /* Lock 2D arrays of pixels for writing */ | ||||
| template<PixelFormat T> | template<PixelFormat T> | ||||
| inline array2d<typename PixelType<T>::type> &lock2d() | |||||
| LOL_ATTR_NODISCARD inline array2d<typename PixelType<T>::type> &lock2d() | |||||
| { | { | ||||
| /* Hack: this indirection is needed because of a Visual Studio ICE */ | /* Hack: this indirection is needed because of a Visual Studio ICE */ | ||||
| return *(array2d<typename PixelType<T>::type> *)lock2d_helper(T); | return *(array2d<typename PixelType<T>::type> *)lock2d_helper(T); | ||||
| @@ -95,7 +95,7 @@ private: | |||||
| template<int N, typename... T> | template<int N, typename... T> | ||||
| class arraynd : protected array<T...> | |||||
| class LOL_ATTR_NODISCARD arraynd : protected array<T...> | |||||
| { | { | ||||
| public: | public: | ||||
| typedef array<T...> super; | typedef array<T...> super; | ||||
| @@ -40,7 +40,7 @@ namespace lol | |||||
| */ | */ | ||||
| template<unsigned int N = 16, typename T = uint32_t> | template<unsigned int N = 16, typename T = uint32_t> | ||||
| class bigint | |||||
| class LOL_ATTR_NODISCARD bigint | |||||
| { | { | ||||
| static int const bits_per_digit = sizeof(T) * 8 - 1; | static int const bits_per_digit = sizeof(T) * 8 - 1; | ||||
| static T const digit_mask = ~((T)1 << bits_per_digit); | static T const digit_mask = ~((T)1 << bits_per_digit); | ||||
| @@ -34,45 +34,45 @@ namespace lol | |||||
| #undef max | #undef max | ||||
| /* Standard cmath functions */ | /* Standard cmath functions */ | ||||
| static inline double sqrt(double const &x) { return std::sqrt(x); } | |||||
| static inline float sqrt(float const &x) { return std::sqrt(x); } | |||||
| static inline double cbrt(double const &x) { return std::cbrt(x); } | |||||
| static inline float cbrt(float const &x) { return std::cbrt(x); } | |||||
| static inline double exp(double const &x) { return std::exp(x); } | |||||
| static inline float exp(float const &x) { return std::exp(x); } | |||||
| static inline double sin(double const &x) { return std::sin(x); } | |||||
| static inline double cos(double const &x) { return std::cos(x); } | |||||
| static inline double tan(double const &x) { return std::tan(x); } | |||||
| static inline float sin(float const &x) { return std::sin(x); } | |||||
| static inline float cos(float const &x) { return std::cos(x); } | |||||
| static inline float tan(float const &x) { return std::tan(x); } | |||||
| static inline double asin(double const &x) { return std::asin(x); } | |||||
| static inline double acos(double const &x) { return std::acos(x); } | |||||
| static inline double atan(double const &x) { return std::atan(x); } | |||||
| static inline float asin(float const &x) { return std::asin(x); } | |||||
| static inline float acos(float const &x) { return std::acos(x); } | |||||
| static inline float atan(float const &x) { return std::atan(x); } | |||||
| static inline double atan2(double const &y, double const &x) | |||||
| LOL_ATTR_NODISCARD static inline double sqrt(double const &x) { return std::sqrt(x); } | |||||
| LOL_ATTR_NODISCARD static inline float sqrt(float const &x) { return std::sqrt(x); } | |||||
| LOL_ATTR_NODISCARD static inline double cbrt(double const &x) { return std::cbrt(x); } | |||||
| LOL_ATTR_NODISCARD static inline float cbrt(float const &x) { return std::cbrt(x); } | |||||
| LOL_ATTR_NODISCARD static inline double exp(double const &x) { return std::exp(x); } | |||||
| LOL_ATTR_NODISCARD static inline float exp(float const &x) { return std::exp(x); } | |||||
| LOL_ATTR_NODISCARD static inline double sin(double const &x) { return std::sin(x); } | |||||
| LOL_ATTR_NODISCARD static inline double cos(double const &x) { return std::cos(x); } | |||||
| LOL_ATTR_NODISCARD static inline double tan(double const &x) { return std::tan(x); } | |||||
| LOL_ATTR_NODISCARD static inline float sin(float const &x) { return std::sin(x); } | |||||
| LOL_ATTR_NODISCARD static inline float cos(float const &x) { return std::cos(x); } | |||||
| LOL_ATTR_NODISCARD static inline float tan(float const &x) { return std::tan(x); } | |||||
| LOL_ATTR_NODISCARD static inline double asin(double const &x) { return std::asin(x); } | |||||
| LOL_ATTR_NODISCARD static inline double acos(double const &x) { return std::acos(x); } | |||||
| LOL_ATTR_NODISCARD static inline double atan(double const &x) { return std::atan(x); } | |||||
| LOL_ATTR_NODISCARD static inline float asin(float const &x) { return std::asin(x); } | |||||
| LOL_ATTR_NODISCARD static inline float acos(float const &x) { return std::acos(x); } | |||||
| LOL_ATTR_NODISCARD static inline float atan(float const &x) { return std::atan(x); } | |||||
| LOL_ATTR_NODISCARD static inline double atan2(double const &y, double const &x) | |||||
| { | { | ||||
| return std::atan2(y, x); | return std::atan2(y, x); | ||||
| } | } | ||||
| static inline float atan2(float const &y, float const &x) | |||||
| LOL_ATTR_NODISCARD static inline float atan2(float const &y, float const &x) | |||||
| { | { | ||||
| return std::atan2(y, x); | return std::atan2(y, x); | ||||
| } | } | ||||
| static inline double pow(double const &x, double const &y) | |||||
| LOL_ATTR_NODISCARD static inline double pow(double const &x, double const &y) | |||||
| { | { | ||||
| return std::pow(x, y); | return std::pow(x, y); | ||||
| } | } | ||||
| static inline float pow(float const &x, float const &y) | |||||
| LOL_ATTR_NODISCARD static inline float pow(float const &x, float const &y) | |||||
| { | { | ||||
| return std::pow(x, y); | return std::pow(x, y); | ||||
| } | } | ||||
| @@ -91,180 +91,180 @@ static inline void sincos(float const &x, float *s, float *c) | |||||
| } | } | ||||
| /* Inherited from GLSL */ | /* Inherited from GLSL */ | ||||
| static inline float degrees(float radians) | |||||
| LOL_ATTR_NODISCARD static inline float degrees(float radians) | |||||
| { | { | ||||
| return radians * (180.0f / F_PI); | return radians * (180.0f / F_PI); | ||||
| } | } | ||||
| static inline double degrees(double radians) | |||||
| LOL_ATTR_NODISCARD static inline double degrees(double radians) | |||||
| { | { | ||||
| return radians * (180.0 / D_PI); | return radians * (180.0 / D_PI); | ||||
| } | } | ||||
| static inline ldouble degrees(ldouble radians) | |||||
| LOL_ATTR_NODISCARD static inline ldouble degrees(ldouble radians) | |||||
| { | { | ||||
| return radians * (180.0L / LD_PI); | return radians * (180.0L / LD_PI); | ||||
| } | } | ||||
| static inline float radians(float degrees) | |||||
| LOL_ATTR_NODISCARD static inline float radians(float degrees) | |||||
| { | { | ||||
| return degrees * (F_PI / 180.0f); | return degrees * (F_PI / 180.0f); | ||||
| } | } | ||||
| static inline double radians(double degrees) | |||||
| LOL_ATTR_NODISCARD static inline double radians(double degrees) | |||||
| { | { | ||||
| return degrees * (D_PI / 180.0); | return degrees * (D_PI / 180.0); | ||||
| } | } | ||||
| static inline ldouble radians(ldouble degrees) | |||||
| LOL_ATTR_NODISCARD static inline ldouble radians(ldouble degrees) | |||||
| { | { | ||||
| return degrees * (LD_PI / 180.0L); | return degrees * (LD_PI / 180.0L); | ||||
| } | } | ||||
| /* The integer versions return floating point values. This avoids nasty | /* The integer versions return floating point values. This avoids nasty | ||||
| * surprises when calling radians(180) instead of radians(180.0). */ | * surprises when calling radians(180) instead of radians(180.0). */ | ||||
| static inline float degrees(int8_t x) { return degrees(float(x)); } | |||||
| static inline float degrees(uint8_t x) { return degrees(float(x)); } | |||||
| static inline float degrees(int16_t x) { return degrees(float(x)); } | |||||
| static inline float degrees(uint16_t x) { return degrees(float(x)); } | |||||
| static inline double degrees(int32_t x) { return degrees(double(x)); } | |||||
| static inline double degrees(uint32_t x) { return degrees(double(x)); } | |||||
| static inline ldouble degrees(int64_t x) { return degrees(ldouble(x)); } | |||||
| static inline ldouble degrees(uint64_t x) { return degrees(ldouble(x)); } | |||||
| static inline float radians(int8_t x) { return radians(float(x)); } | |||||
| static inline float radians(uint8_t x) { return radians(float(x)); } | |||||
| static inline float radians(int16_t x) { return radians(float(x)); } | |||||
| static inline float radians(uint16_t x) { return radians(float(x)); } | |||||
| static inline double radians(int32_t x) { return radians(double(x)); } | |||||
| static inline double radians(uint32_t x) { return radians(double(x)); } | |||||
| static inline ldouble radians(int64_t x) { return radians(ldouble(x)); } | |||||
| static inline ldouble radians(uint64_t x) { return radians(ldouble(x)); } | |||||
| static inline float mix(float const &a, float const &b, float const &x) | |||||
| LOL_ATTR_NODISCARD static inline float degrees(int8_t x) { return degrees(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float degrees(uint8_t x) { return degrees(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float degrees(int16_t x) { return degrees(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float degrees(uint16_t x) { return degrees(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline double degrees(int32_t x) { return degrees(double(x)); } | |||||
| LOL_ATTR_NODISCARD static inline double degrees(uint32_t x) { return degrees(double(x)); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble degrees(int64_t x) { return degrees(ldouble(x)); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble degrees(uint64_t x) { return degrees(ldouble(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float radians(int8_t x) { return radians(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float radians(uint8_t x) { return radians(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float radians(int16_t x) { return radians(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float radians(uint16_t x) { return radians(float(x)); } | |||||
| LOL_ATTR_NODISCARD static inline double radians(int32_t x) { return radians(double(x)); } | |||||
| LOL_ATTR_NODISCARD static inline double radians(uint32_t x) { return radians(double(x)); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble radians(int64_t x) { return radians(ldouble(x)); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble radians(uint64_t x) { return radians(ldouble(x)); } | |||||
| LOL_ATTR_NODISCARD static inline float mix(float const &a, float const &b, float const &x) | |||||
| { | { | ||||
| return a + (b - a) * x; | return a + (b - a) * x; | ||||
| } | } | ||||
| static inline double mix(double const &a, double const &b, double const &x) | |||||
| LOL_ATTR_NODISCARD static inline double mix(double const &a, double const &b, double const &x) | |||||
| { | { | ||||
| return a + (b - a) * x; | return a + (b - a) * x; | ||||
| } | } | ||||
| static inline ldouble mix(ldouble const &a, ldouble const &b, ldouble const &x) | |||||
| LOL_ATTR_NODISCARD static inline ldouble mix(ldouble const &a, ldouble const &b, ldouble const &x) | |||||
| { | { | ||||
| return a + (b - a) * x; | return a + (b - a) * x; | ||||
| } | } | ||||
| /* Inherited from HLSL */ | /* Inherited from HLSL */ | ||||
| static inline float lerp(float const &a, float const &b, float const &x) | |||||
| LOL_ATTR_NODISCARD static inline float lerp(float const &a, float const &b, float const &x) | |||||
| { | { | ||||
| return mix(a, b, x); | return mix(a, b, x); | ||||
| } | } | ||||
| static inline double lerp(double const &a, double const &b, double const &x) | |||||
| LOL_ATTR_NODISCARD static inline double lerp(double const &a, double const &b, double const &x) | |||||
| { | { | ||||
| return mix(a, b, x); | return mix(a, b, x); | ||||
| } | } | ||||
| static inline ldouble lerp(ldouble const &a, ldouble const &b, ldouble const &x) | |||||
| LOL_ATTR_NODISCARD static inline ldouble lerp(ldouble const &a, ldouble const &b, ldouble const &x) | |||||
| { | { | ||||
| return mix(a, b, x); | return mix(a, b, x); | ||||
| } | } | ||||
| /* These accelerated functions will be merged into the above, one day */ | /* These accelerated functions will be merged into the above, one day */ | ||||
| double lol_sin(double); | |||||
| double lol_cos(double); | |||||
| double lol_tan(double); | |||||
| LOL_ATTR_NODISCARD double lol_sin(double); | |||||
| LOL_ATTR_NODISCARD double lol_cos(double); | |||||
| LOL_ATTR_NODISCARD double lol_tan(double); | |||||
| void lol_sincos(double, double*, double*); | void lol_sincos(double, double*, double*); | ||||
| void lol_sincos(float, float*, float*); | void lol_sincos(float, float*, float*); | ||||
| double lol_asin(double); | |||||
| double lol_acos(double); | |||||
| double lol_atan(double); | |||||
| double lol_atan2(double, double); | |||||
| LOL_ATTR_NODISCARD double lol_asin(double); | |||||
| LOL_ATTR_NODISCARD double lol_acos(double); | |||||
| LOL_ATTR_NODISCARD double lol_atan(double); | |||||
| LOL_ATTR_NODISCARD double lol_atan2(double, double); | |||||
| /* C++ doesn't define abs() and fmod() for all types; we add these for | /* C++ doesn't define abs() and fmod() for all types; we add these for | ||||
| * convenience to avoid adding complexity to vector.h. */ | * convenience to avoid adding complexity to vector.h. */ | ||||
| static inline int8_t abs(int8_t x) { return std::abs(x); } | |||||
| static inline uint8_t abs(uint8_t x) { return x; } | |||||
| static inline int16_t abs(int16_t x) { return std::abs(x); } | |||||
| static inline uint16_t abs(uint16_t x) { return x; } | |||||
| static inline int32_t abs(int32_t x) { return std::abs(x); } | |||||
| static inline uint32_t abs(uint32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int8_t abs(int8_t x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint8_t abs(uint8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int16_t abs(int16_t x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint16_t abs(uint16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int32_t abs(int32_t x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint32_t abs(uint32_t x) { return x; } | |||||
| #if defined __native_client__ || defined __ANDROID__ | #if defined __native_client__ || defined __ANDROID__ | ||||
| /* The pepper 19 toolchain doesn't provide abs() for long long int. */ | /* The pepper 19 toolchain doesn't provide abs() for long long int. */ | ||||
| static inline int64_t abs(int64_t x) { return x > 0 ? x : -x; } | |||||
| LOL_ATTR_NODISCARD static inline int64_t abs(int64_t x) { return x > 0 ? x : -x; } | |||||
| #else | #else | ||||
| static inline int64_t abs(int64_t x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline int64_t abs(int64_t x) { return std::abs(x); } | |||||
| #endif | #endif | ||||
| static inline uint64_t abs(uint64_t x) { return x; } | |||||
| static inline float abs(float x) { return std::abs(x); } | |||||
| static inline double abs(double x) { return std::abs(x); } | |||||
| static inline ldouble abs(ldouble x) { return std::abs(x); } | |||||
| static inline uint8_t fmod(uint8_t x, uint8_t y) { return x % y; } | |||||
| static inline int8_t fmod(int8_t x, int8_t y) { return x % y; } | |||||
| static inline uint16_t fmod(uint16_t x, uint16_t y) { return x % y; } | |||||
| static inline int16_t fmod(int16_t x, int16_t y) { return x % y; } | |||||
| static inline uint32_t fmod(uint32_t x, uint32_t y) { return x % y; } | |||||
| static inline int32_t fmod(int32_t x, int32_t y) { return x % y; } | |||||
| static inline uint64_t fmod(uint64_t x, uint64_t y) { return x % y; } | |||||
| static inline int64_t fmod(int64_t x, int64_t y) { return x % y; } | |||||
| static inline float fmod(float x, float y) { return std::fmod(x, y); } | |||||
| static inline double fmod(double x, double y) { return std::fmod(x, y); } | |||||
| static inline ldouble fmod(ldouble x, ldouble y) { return std::fmod(x, y); } | |||||
| static inline uint8_t floor(uint8_t x) { return x; } | |||||
| static inline int8_t floor(int8_t x) { return x; } | |||||
| static inline uint16_t floor(uint16_t x) { return x; } | |||||
| static inline int16_t floor(int16_t x) { return x; } | |||||
| static inline uint32_t floor(uint32_t x) { return x; } | |||||
| static inline int32_t floor(int32_t x) { return x; } | |||||
| static inline uint64_t floor(uint64_t x) { return x; } | |||||
| static inline int64_t floor(int64_t x) { return x; } | |||||
| static inline float floor(float x) { return std::floor(x); } | |||||
| static inline double floor(double x) { return std::floor(x); } | |||||
| static inline ldouble floor(ldouble x) { return std::floor(x); } | |||||
| static inline uint8_t ceil(uint8_t x) { return x; } | |||||
| static inline int8_t ceil(int8_t x) { return x; } | |||||
| static inline uint16_t ceil(uint16_t x) { return x; } | |||||
| static inline int16_t ceil(int16_t x) { return x; } | |||||
| static inline uint32_t ceil(uint32_t x) { return x; } | |||||
| static inline int32_t ceil(int32_t x) { return x; } | |||||
| static inline uint64_t ceil(uint64_t x) { return x; } | |||||
| static inline int64_t ceil(int64_t x) { return x; } | |||||
| static inline float ceil(float x) { return std::ceil(x); } | |||||
| static inline double ceil(double x) { return std::ceil(x); } | |||||
| static inline ldouble ceil(ldouble x) { return std::ceil(x); } | |||||
| static inline uint8_t round(uint8_t x) { return x; } | |||||
| static inline int8_t round(int8_t x) { return x; } | |||||
| static inline uint16_t round(uint16_t x) { return x; } | |||||
| static inline int16_t round(int16_t x) { return x; } | |||||
| static inline uint32_t round(uint32_t x) { return x; } | |||||
| static inline int32_t round(int32_t x) { return x; } | |||||
| static inline uint64_t round(uint64_t x) { return x; } | |||||
| static inline int64_t round(int64_t x) { return x; } | |||||
| static inline float round(float x) { return std::round(x); } | |||||
| static inline double round(double x) { return std::round(x); } | |||||
| static inline ldouble round(ldouble x) { return std::round(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint64_t abs(uint64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline float abs(float x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline double abs(double x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble abs(ldouble x) { return std::abs(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint8_t fmod(uint8_t x, uint8_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline int8_t fmod(int8_t x, int8_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline uint16_t fmod(uint16_t x, uint16_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline int16_t fmod(int16_t x, int16_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline uint32_t fmod(uint32_t x, uint32_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline int32_t fmod(int32_t x, int32_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline uint64_t fmod(uint64_t x, uint64_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline int64_t fmod(int64_t x, int64_t y) { return x % y; } | |||||
| LOL_ATTR_NODISCARD static inline float fmod(float x, float y) { return std::fmod(x, y); } | |||||
| LOL_ATTR_NODISCARD static inline double fmod(double x, double y) { return std::fmod(x, y); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble fmod(ldouble x, ldouble y) { return std::fmod(x, y); } | |||||
| LOL_ATTR_NODISCARD static inline uint8_t floor(uint8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int8_t floor(int8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint16_t floor(uint16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int16_t floor(int16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint32_t floor(uint32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int32_t floor(int32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint64_t floor(uint64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int64_t floor(int64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline float floor(float x) { return std::floor(x); } | |||||
| LOL_ATTR_NODISCARD static inline double floor(double x) { return std::floor(x); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble floor(ldouble x) { return std::floor(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint8_t ceil(uint8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int8_t ceil(int8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint16_t ceil(uint16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int16_t ceil(int16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint32_t ceil(uint32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int32_t ceil(int32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint64_t ceil(uint64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int64_t ceil(int64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline float ceil(float x) { return std::ceil(x); } | |||||
| LOL_ATTR_NODISCARD static inline double ceil(double x) { return std::ceil(x); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble ceil(ldouble x) { return std::ceil(x); } | |||||
| LOL_ATTR_NODISCARD static inline uint8_t round(uint8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int8_t round(int8_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint16_t round(uint16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int16_t round(int16_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint32_t round(uint32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int32_t round(int32_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline uint64_t round(uint64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline int64_t round(int64_t x) { return x; } | |||||
| LOL_ATTR_NODISCARD static inline float round(float x) { return std::round(x); } | |||||
| LOL_ATTR_NODISCARD static inline double round(double x) { return std::round(x); } | |||||
| LOL_ATTR_NODISCARD static inline ldouble round(ldouble x) { return std::round(x); } | |||||
| #define LOL_GENERIC_FUNC(T) \ | #define LOL_GENERIC_FUNC(T) \ | ||||
| static inline T sq(T x) { return x * x; } \ | |||||
| static inline T fract(T x) { return x - lol::floor(x); } \ | |||||
| static inline T min(T x, T y) { return std::min(x, y); } \ | |||||
| static inline T max(T x, T y) { return std::max(x, y); } \ | |||||
| static inline T clamp(T x, T y, T z) { return min(max(x, y), z); } \ | |||||
| static inline T saturate(T x) { return min(max(x, (T)0), (T)1); } | |||||
| LOL_ATTR_NODISCARD static inline T sq(T x) { return x * x; } \ | |||||
| LOL_ATTR_NODISCARD static inline T fract(T x) { return x - lol::floor(x); } \ | |||||
| LOL_ATTR_NODISCARD static inline T min(T x, T y) { return std::min(x, y); } \ | |||||
| LOL_ATTR_NODISCARD static inline T max(T x, T y) { return std::max(x, y); } \ | |||||
| LOL_ATTR_NODISCARD static inline T clamp(T x, T y, T z) { return min(max(x, y), z); } \ | |||||
| LOL_ATTR_NODISCARD static inline T saturate(T x) { return min(max(x, (T)0), (T)1); } | |||||
| #define LOL_GENERIC_FUNC_SIGNED(T) \ | #define LOL_GENERIC_FUNC_SIGNED(T) \ | ||||
| LOL_GENERIC_FUNC(T) \ | LOL_GENERIC_FUNC(T) \ | ||||
| static inline T sign(T x) { return (T)(((T)0 < x) - (x < (T)0)); } | |||||
| LOL_ATTR_NODISCARD static inline T sign(T x) { return (T)(((T)0 < x) - (x < (T)0)); } | |||||
| #define LOL_GENERIC_FUNC_UNSIGNED(T) \ | #define LOL_GENERIC_FUNC_UNSIGNED(T) \ | ||||
| LOL_GENERIC_FUNC(T) \ | LOL_GENERIC_FUNC(T) \ | ||||
| static inline T sign(T x) { return (T)((T)0 < x); } | |||||
| LOL_ATTR_NODISCARD static inline T sign(T x) { return (T)((T)0 < x); } | |||||
| LOL_GENERIC_FUNC_UNSIGNED(uint8_t) | LOL_GENERIC_FUNC_UNSIGNED(uint8_t) | ||||
| LOL_GENERIC_FUNC_SIGNED(int8_t) | LOL_GENERIC_FUNC_SIGNED(int8_t) | ||||
| @@ -29,7 +29,7 @@ namespace lol | |||||
| { | { | ||||
| //AxisBase -------------------------------------------------------------------- | //AxisBase -------------------------------------------------------------------- | ||||
| struct AxisBase : public StructSafeEnum | |||||
| struct AxisBase : public StructSafeEnum | |||||
| { | { | ||||
| enum Type | enum Type | ||||
| { | { | ||||
| @@ -90,7 +90,7 @@ T_(box_t<, C_ 4>, box4) | |||||
| #undef T_ | #undef T_ | ||||
| template<typename T, int N> | template<typename T, int N> | ||||
| struct box_t | |||||
| struct LOL_ATTR_NODISCARD box_t | |||||
| { | { | ||||
| inline box_t() | inline box_t() | ||||
| : aa(vec_t<T, N>(T(0))), | : aa(vec_t<T, N>(T(0))), | ||||
| @@ -153,12 +153,12 @@ struct box_t | |||||
| return *this = *this * s; | return *this = *this * s; | ||||
| } | } | ||||
| bool operator ==(box_t<T,N> const &box) const | |||||
| LOL_ATTR_NODISCARD bool operator ==(box_t<T,N> const &box) const | |||||
| { | { | ||||
| return aa == box.aa && bb == box.bb; | return aa == box.aa && bb == box.bb; | ||||
| } | } | ||||
| bool operator !=(box_t<T,N> const &box) const | |||||
| LOL_ATTR_NODISCARD bool operator !=(box_t<T,N> const &box) const | |||||
| { | { | ||||
| return aa != box.aa || bb != box.bb; | return aa != box.aa || bb != box.bb; | ||||
| } | } | ||||
| @@ -192,19 +192,19 @@ private: | |||||
| float Minus() const; | float Minus() const; | ||||
| float Plus() const; | float Plus() const; | ||||
| public: | public: | ||||
| bool operator==(float value) const; | |||||
| bool operator!=(float value) const; | |||||
| bool operator<(float value) const; | |||||
| bool operator<=(float value) const; | |||||
| bool operator>(float value) const; | |||||
| bool operator>=(float value) const; | |||||
| LOL_ATTR_NODISCARD bool operator==(float value) const; | |||||
| LOL_ATTR_NODISCARD bool operator!=(float value) const; | |||||
| LOL_ATTR_NODISCARD bool operator<(float value) const; | |||||
| LOL_ATTR_NODISCARD bool operator<=(float value) const; | |||||
| LOL_ATTR_NODISCARD bool operator>(float value) const; | |||||
| LOL_ATTR_NODISCARD bool operator>=(float value) const; | |||||
| }; | }; | ||||
| bool operator==(float value, const TestEpsilon& epsilon); | |||||
| bool operator!=(float value, const TestEpsilon& epsilon); | |||||
| bool operator<(float value, const TestEpsilon& epsilon); | |||||
| bool operator<=(float value, const TestEpsilon& epsilon); | |||||
| bool operator>(float value, const TestEpsilon& epsilon); | |||||
| bool operator>=(float value, const TestEpsilon& epsilon); | |||||
| LOL_ATTR_NODISCARD bool operator==(float value, const TestEpsilon& epsilon); | |||||
| LOL_ATTR_NODISCARD bool operator!=(float value, const TestEpsilon& epsilon); | |||||
| LOL_ATTR_NODISCARD bool operator<(float value, const TestEpsilon& epsilon); | |||||
| LOL_ATTR_NODISCARD bool operator<=(float value, const TestEpsilon& epsilon); | |||||
| LOL_ATTR_NODISCARD bool operator>(float value, const TestEpsilon& epsilon); | |||||
| LOL_ATTR_NODISCARD bool operator>=(float value, const TestEpsilon& epsilon); | |||||
| //-- | //-- | ||||
| static inline bool TestAABBVsAABB(box2 const &b1, box2 const &b2) | static inline bool TestAABBVsAABB(box2 const &b1, box2 const &b2) | ||||
| @@ -30,7 +30,7 @@ namespace lol | |||||
| namespace half_ops { struct base {}; } | namespace half_ops { struct base {}; } | ||||
| class half | |||||
| class LOL_ATTR_NODISCARD half | |||||
| : half_ops::base | : half_ops::base | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -42,22 +42,22 @@ public: | |||||
| inline half(double f) { *this = makefast((float)f); } | inline half(double f) { *this = makefast((float)f); } | ||||
| inline half(ldouble f) { *this = makefast((float)f); } | inline half(ldouble f) { *this = makefast((float)f); } | ||||
| inline int is_nan() const | |||||
| LOL_ATTR_NODISCARD inline int is_nan() const | |||||
| { | { | ||||
| return ((bits & 0x7c00u) == 0x7c00u) && (bits & 0x03ffu); | return ((bits & 0x7c00u) == 0x7c00u) && (bits & 0x03ffu); | ||||
| } | } | ||||
| inline int is_finite() const | |||||
| LOL_ATTR_NODISCARD inline int is_finite() const | |||||
| { | { | ||||
| return (bits & 0x7c00u) != 0x7c00u; | return (bits & 0x7c00u) != 0x7c00u; | ||||
| } | } | ||||
| inline int is_inf() const | |||||
| LOL_ATTR_NODISCARD inline int is_inf() const | |||||
| { | { | ||||
| return (uint16_t)(bits << 1) == (0x7c00u << 1); | return (uint16_t)(bits << 1) == (0x7c00u << 1); | ||||
| } | } | ||||
| inline int is_normal() const | |||||
| LOL_ATTR_NODISCARD inline int is_normal() const | |||||
| { | { | ||||
| return (is_finite() && (bits & 0x7c00u)) || ((bits & 0x7fffu) == 0); | return (is_finite() && (bits & 0x7c00u)) || ((bits & 0x7fffu) == 0); | ||||
| } | } | ||||
| @@ -67,33 +67,33 @@ public: | |||||
| inline half &operator =(float f) { return *this = makefast(f); } | inline half &operator =(float f) { return *this = makefast(f); } | ||||
| inline half &operator =(double f) { return *this = makefast((float)f); } | inline half &operator =(double f) { return *this = makefast((float)f); } | ||||
| inline half &operator =(ldouble f) { return *this = makefast((float)f); } | inline half &operator =(ldouble f) { return *this = makefast((float)f); } | ||||
| inline operator int8_t() const { return (int8_t)(float)*this; } | |||||
| inline operator uint8_t() const { return (uint8_t)(float)*this; } | |||||
| inline operator int16_t() const { return (int16_t)(float)*this; } | |||||
| inline operator uint16_t() const { return (uint16_t)(float)*this; } | |||||
| inline operator int32_t() const { return (int32_t)(float)*this; } | |||||
| inline operator uint32_t() const { return (uint32_t)(float)*this; } | |||||
| inline operator int64_t() const { return (int64_t)(float)*this; } | |||||
| inline operator uint64_t() const { return (uint64_t)(float)*this; } | |||||
| operator float() const; | |||||
| inline operator double() const { return (float)(*this); } | |||||
| inline operator ldouble() const { return (float)(*this); } | |||||
| LOL_ATTR_NODISCARD inline operator int8_t() const { return (int8_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator uint8_t() const { return (uint8_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator int16_t() const { return (int16_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator uint16_t() const { return (uint16_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator int32_t() const { return (int32_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator uint32_t() const { return (uint32_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator int64_t() const { return (int64_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD inline operator uint64_t() const { return (uint64_t)(float)*this; } | |||||
| LOL_ATTR_NODISCARD operator float() const; | |||||
| LOL_ATTR_NODISCARD inline operator double() const { return (float)(*this); } | |||||
| LOL_ATTR_NODISCARD inline operator ldouble() const { return (float)(*this); } | |||||
| /* Array conversions */ | /* Array conversions */ | ||||
| static size_t convert(half *dst, float const *src, size_t nelem); | |||||
| static size_t convert(float *dst, half const *src, size_t nelem); | |||||
| LOL_ATTR_NODISCARD static size_t convert(half *dst, float const *src, size_t nelem); | |||||
| LOL_ATTR_NODISCARD static size_t convert(float *dst, half const *src, size_t nelem); | |||||
| /* Operations */ | /* Operations */ | ||||
| bool operator ==(half x) const { return (float)*this == (float)x; } | |||||
| bool operator !=(half x) const { return (float)*this != (float)x; } | |||||
| bool operator <(half x) const { return (float)*this < (float)x; } | |||||
| bool operator >(half x) const { return (float)*this > (float)x; } | |||||
| bool operator <=(half x) const { return (float)*this <= (float)x; } | |||||
| bool operator >=(half x) const { return (float)*this >= (float)x; } | |||||
| LOL_ATTR_NODISCARD bool operator ==(half x) const { return (float)*this == (float)x; } | |||||
| LOL_ATTR_NODISCARD bool operator !=(half x) const { return (float)*this != (float)x; } | |||||
| LOL_ATTR_NODISCARD bool operator <(half x) const { return (float)*this < (float)x; } | |||||
| LOL_ATTR_NODISCARD bool operator >(half x) const { return (float)*this > (float)x; } | |||||
| LOL_ATTR_NODISCARD bool operator <=(half x) const { return (float)*this <= (float)x; } | |||||
| LOL_ATTR_NODISCARD bool operator >=(half x) const { return (float)*this >= (float)x; } | |||||
| bool operator !() const { return !(bits & 0x7fffu); } | |||||
| operator bool() const { return !!*this; } | |||||
| LOL_ATTR_NODISCARD bool operator !() const { return !(bits & 0x7fffu); } | |||||
| LOL_ATTR_NODISCARD operator bool() const { return !!*this; } | |||||
| inline half operator -() const { return makebits(bits ^ 0x8000u); } | inline half operator -() const { return makebits(bits ^ 0x8000u); } | ||||
| inline half operator +() const { return *this; } | inline half operator +() const { return *this; } | ||||
| @@ -102,10 +102,10 @@ public: | |||||
| inline half &operator *=(half h) { return (*this = (half)(*this * h)); } | inline half &operator *=(half h) { return (*this = (half)(*this * h)); } | ||||
| inline half &operator /=(half h) { return (*this = (half)(*this / h)); } | inline half &operator /=(half h) { return (*this = (half)(*this / h)); } | ||||
| inline float operator +(half h) const { return (float)*this + (float)h; } | |||||
| inline float operator -(half h) const { return (float)*this - (float)h; } | |||||
| inline float operator *(half h) const { return (float)*this * (float)h; } | |||||
| inline float operator /(half h) const { return (float)*this / (float)h; } | |||||
| LOL_ATTR_NODISCARD inline float operator +(half h) const { return (float)*this + (float)h; } | |||||
| LOL_ATTR_NODISCARD inline float operator -(half h) const { return (float)*this - (float)h; } | |||||
| LOL_ATTR_NODISCARD inline float operator *(half h) const { return (float)*this * (float)h; } | |||||
| LOL_ATTR_NODISCARD inline float operator /(half h) const { return (float)*this / (float)h; } | |||||
| /* Factories */ | /* Factories */ | ||||
| static half makefast(float f); | static half makefast(float f); | ||||
| @@ -34,7 +34,7 @@ namespace lol | |||||
| */ | */ | ||||
| template<typename T, int COLS, int ROWS> | template<typename T, int COLS, int ROWS> | ||||
| struct mat_t | |||||
| struct LOL_ATTR_NODISCARD mat_t | |||||
| : public linear_ops::base<vec_t<T,ROWS>> | : public linear_ops::base<vec_t<T,ROWS>> | ||||
| { | { | ||||
| static int const count = COLS; | static int const count = COLS; | ||||
| @@ -72,7 +72,7 @@ private: | |||||
| */ | */ | ||||
| template <typename T> | template <typename T> | ||||
| struct mat_t<T, 2, 2> | |||||
| struct LOL_ATTR_NODISCARD mat_t<T, 2, 2> | |||||
| : public linear_ops::base<vec_t<T,2>> | : public linear_ops::base<vec_t<T,2>> | ||||
| { | { | ||||
| static int const count = 2; | static int const count = 2; | ||||
| @@ -157,7 +157,7 @@ static_assert(sizeof(dmat2) == 32, "sizeof(dmat2) == 32"); | |||||
| */ | */ | ||||
| template <typename T> | template <typename T> | ||||
| struct mat_t<T, 3, 3> | |||||
| struct LOL_ATTR_NODISCARD mat_t<T, 3, 3> | |||||
| : public linear_ops::base<vec_t<T,3>> | : public linear_ops::base<vec_t<T,3>> | ||||
| { | { | ||||
| static int const count = 3; | static int const count = 3; | ||||
| @@ -288,7 +288,7 @@ static_assert(sizeof(dmat3) == 72, "sizeof(dmat3) == 72"); | |||||
| */ | */ | ||||
| template <typename T> | template <typename T> | ||||
| struct mat_t<T, 4, 4> | |||||
| struct LOL_ATTR_NODISCARD mat_t<T, 4, 4> | |||||
| : public linear_ops::base<vec_t<T,4>> | : public linear_ops::base<vec_t<T,4>> | ||||
| { | { | ||||
| static int const count = 4; | static int const count = 4; | ||||
| @@ -498,7 +498,7 @@ mat_t<T, N - 1, N - 1> submatrix(mat_t<T, N, N> const &m, int i, int j) | |||||
| * Compute square matrix cofactor | * Compute square matrix cofactor | ||||
| */ | */ | ||||
| template<typename T, int N> | |||||
| template<typename T, int N> LOL_ATTR_NODISCARD | |||||
| T cofactor(mat_t<T, N, N> const &m, int i, int j) | T cofactor(mat_t<T, N, N> const &m, int i, int j) | ||||
| { | { | ||||
| ASSERT(i >= 0); ASSERT(j >= 0); ASSERT(i < N); ASSERT(j < N); | ASSERT(i >= 0); ASSERT(j >= 0); ASSERT(i < N); ASSERT(j < N); | ||||
| @@ -506,7 +506,7 @@ T cofactor(mat_t<T, N, N> const &m, int i, int j) | |||||
| return ((i + j) & 1) ? -tmp : tmp; | return ((i + j) & 1) ? -tmp : tmp; | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| T cofactor(mat_t<T, 2, 2> const &m, int i, int j) | T cofactor(mat_t<T, 2, 2> const &m, int i, int j) | ||||
| { | { | ||||
| /* This specialisation shouldn't be needed, but Visual Studio. */ | /* This specialisation shouldn't be needed, but Visual Studio. */ | ||||
| @@ -548,7 +548,7 @@ void lu_decomposition(mat_t<T, N, N> const &m, mat_t<T, N, N> & L, mat_t<T, N, N | |||||
| * Compute square matrix determinant, with a specialisation for 1×1 matrices | * Compute square matrix determinant, with a specialisation for 1×1 matrices | ||||
| */ | */ | ||||
| template<typename T, int N> | |||||
| template<typename T, int N> LOL_ATTR_NODISCARD | |||||
| T determinant(mat_t<T, N, N> const &m) | T determinant(mat_t<T, N, N> const &m) | ||||
| { | { | ||||
| mat_t<T, N, N> L, U; | mat_t<T, N, N> L, U; | ||||
| @@ -562,7 +562,7 @@ T determinant(mat_t<T, N, N> const &m) | |||||
| return permutation_det(P) * det; | return permutation_det(P) * det; | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| T const & determinant(mat_t<T, 1, 1> const &m) | T const & determinant(mat_t<T, 1, 1> const &m) | ||||
| { | { | ||||
| return m[0][0]; | return m[0][0]; | ||||
| @@ -655,7 +655,7 @@ vec_t<int, N> p_transpose(vec_t<int, N> P) | |||||
| * Compute the determinant of a permutation square matrix corresponding to the permutation vector | * Compute the determinant of a permutation square matrix corresponding to the permutation vector | ||||
| */ | */ | ||||
| template<int N> | |||||
| template<int N> LOL_ATTR_NODISCARD | |||||
| int permutation_det(vec_t<int, N> const & permutation) | int permutation_det(vec_t<int, N> const & permutation) | ||||
| { | { | ||||
| int result = 1; | int result = 1; | ||||
| @@ -70,14 +70,14 @@ namespace swizzle_ops | |||||
| namespace swizzle_ops | namespace swizzle_ops | ||||
| { | { | ||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> | |||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> LOL_ATTR_NODISCARD | |||||
| static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type | static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type | ||||
| operator ==(vec_t<T,N,SWIZZLE1> const &a, vec_t<T,N,SWIZZLE2> const &b) | operator ==(vec_t<T,N,SWIZZLE1> const &a, vec_t<T,N,SWIZZLE2> const &b) | ||||
| { | { | ||||
| return vec_t<T,N>(a) == vec_t<T,N>(b); | return vec_t<T,N>(a) == vec_t<T,N>(b); | ||||
| } | } | ||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> | |||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> LOL_ATTR_NODISCARD | |||||
| static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type | static inline typename std::enable_if<SWIZZLE1 != FULL_SWIZZLE || SWIZZLE2 != FULL_SWIZZLE, bool>::type | ||||
| operator !=(vec_t<T,N,SWIZZLE1> const &a, vec_t<T,N,SWIZZLE2> const &b) | operator !=(vec_t<T,N,SWIZZLE1> const &a, vec_t<T,N,SWIZZLE2> const &b) | ||||
| { | { | ||||
| @@ -135,7 +135,7 @@ namespace linear_ops | |||||
| * Comparisons | * Comparisons | ||||
| */ | */ | ||||
| template<typename V> | |||||
| template<typename V> LOL_ATTR_NODISCARD | |||||
| static inline typename std::enable_if<std::is_base_of<base<typename V::element>, V>::value, bool>::type | static inline typename std::enable_if<std::is_base_of<base<typename V::element>, V>::value, bool>::type | ||||
| operator ==(V const &a, V const &b) | operator ==(V const &a, V const &b) | ||||
| { | { | ||||
| @@ -145,7 +145,7 @@ operator ==(V const &a, V const &b) | |||||
| return true; | return true; | ||||
| } | } | ||||
| template<typename V> | |||||
| template<typename V> LOL_ATTR_NODISCARD | |||||
| static inline typename std::enable_if<std::is_base_of<base<typename V::element>, V>::value, bool>::type | static inline typename std::enable_if<std::is_base_of<base<typename V::element>, V>::value, bool>::type | ||||
| operator !=(V const &a, V const &b) | operator !=(V const &a, V const &b) | ||||
| { | { | ||||
| @@ -25,7 +25,7 @@ namespace lol | |||||
| { | { | ||||
| template<typename T> | template<typename T> | ||||
| struct polynomial | |||||
| struct LOL_ATTR_NODISCARD polynomial | |||||
| { | { | ||||
| /* The zero polynomial */ | /* The zero polynomial */ | ||||
| explicit inline polynomial() {} | explicit inline polynomial() {} | ||||
| @@ -90,7 +90,7 @@ struct polynomial | |||||
| /* Evaluate polynomial at a given value. This method can also | /* Evaluate polynomial at a given value. This method can also | ||||
| * be used to compose polynomials, i.e. using another polynomial | * be used to compose polynomials, i.e. using another polynomial | ||||
| * as the value instead of a scalar. */ | * as the value instead of a scalar. */ | ||||
| template<typename U> U eval(U x) const | |||||
| template<typename U> LOL_ATTR_NODISCARD U eval(U x) const | |||||
| { | { | ||||
| U ret(leading()); | U ret(leading()); | ||||
| for (int i = degree() - 1; i >= 0; --i) | for (int i = degree() - 1; i >= 0; --i) | ||||
| @@ -260,7 +260,7 @@ struct polynomial | |||||
| * copy because we cannot let the user mess with the integrity of | * copy because we cannot let the user mess with the integrity of | ||||
| * the structure (i.e. the guarantee that the leading coefficient | * the structure (i.e. the guarantee that the leading coefficient | ||||
| * remains non-zero). */ | * remains non-zero). */ | ||||
| inline T operator[](ptrdiff_t n) const | |||||
| LOL_ATTR_NODISCARD inline T operator[](ptrdiff_t n) const | |||||
| { | { | ||||
| if (n < 0 || n > degree()) | if (n < 0 || n > degree()) | ||||
| return T(0); | return T(0); | ||||
| @@ -269,7 +269,7 @@ struct polynomial | |||||
| } | } | ||||
| /* Return the leading coefficient */ | /* Return the leading coefficient */ | ||||
| inline T leading() const | |||||
| LOL_ATTR_NODISCARD inline T leading() const | |||||
| { | { | ||||
| return (*this)[degree()]; | return (*this)[degree()]; | ||||
| } | } | ||||
| @@ -22,48 +22,48 @@ namespace lol | |||||
| { | { | ||||
| /* Random number generators */ | /* Random number generators */ | ||||
| template<typename T> static inline T rand(); | |||||
| template<typename T> static inline T rand(T a); | |||||
| template<typename T> static inline T rand(T a, T b); | |||||
| template<typename T> LOL_ATTR_NODISCARD static inline T rand(); | |||||
| template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a); | |||||
| template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a, T b); | |||||
| /* One-value random number generators */ | /* One-value random number generators */ | ||||
| template<typename T> static inline T rand(T a) | |||||
| template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a) | |||||
| { | { | ||||
| return a ? rand<T>() % a : T(0); | return a ? rand<T>() % a : T(0); | ||||
| } | } | ||||
| template<> inline half rand<half>(half a) | |||||
| template<> LOL_ATTR_NODISCARD inline half rand<half>(half a) | |||||
| { | { | ||||
| float f = (float)std::rand() / (float)RAND_MAX; | float f = (float)std::rand() / (float)RAND_MAX; | ||||
| return (half)(a * f); | return (half)(a * f); | ||||
| } | } | ||||
| template<> inline float rand<float>(float a) | |||||
| template<> LOL_ATTR_NODISCARD inline float rand<float>(float a) | |||||
| { | { | ||||
| float f = (float)std::rand() / (float)RAND_MAX; | float f = (float)std::rand() / (float)RAND_MAX; | ||||
| return a * f; | return a * f; | ||||
| } | } | ||||
| template<> inline double rand<double>(double a) | |||||
| template<> LOL_ATTR_NODISCARD inline double rand<double>(double a) | |||||
| { | { | ||||
| double f = (double)std::rand() / (double)RAND_MAX; | double f = (double)std::rand() / (double)RAND_MAX; | ||||
| return a * f; | return a * f; | ||||
| } | } | ||||
| template<> inline ldouble rand<ldouble>(ldouble a) | |||||
| template<> LOL_ATTR_NODISCARD inline ldouble rand<ldouble>(ldouble a) | |||||
| { | { | ||||
| ldouble f = (ldouble)std::rand() / (ldouble)RAND_MAX; | ldouble f = (ldouble)std::rand() / (ldouble)RAND_MAX; | ||||
| return a * f; | return a * f; | ||||
| } | } | ||||
| /* Two-value random number generator -- no need for specialisation */ | /* Two-value random number generator -- no need for specialisation */ | ||||
| template<typename T> static inline T rand(T a, T b) | |||||
| template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a, T b) | |||||
| { | { | ||||
| return a + rand<T>(b - a); | return a + rand<T>(b - a); | ||||
| } | } | ||||
| /* Default random number generator */ | /* Default random number generator */ | ||||
| template<typename T> static inline T rand() | |||||
| template<typename T> LOL_ATTR_NODISCARD static inline T rand() | |||||
| { | { | ||||
| switch (sizeof(T)) | switch (sizeof(T)) | ||||
| { | { | ||||
| @@ -117,10 +117,10 @@ template<typename T> static inline T rand() | |||||
| } | } | ||||
| } | } | ||||
| template<> inline half rand<half>() { return rand<half>(1.f); } | |||||
| template<> inline float rand<float>() { return rand<float>(1.f); } | |||||
| template<> inline double rand<double>() { return rand<double>(1.0); } | |||||
| template<> inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); } | |||||
| template<> LOL_ATTR_NODISCARD inline half rand<half>() { return rand<half>(1.f); } | |||||
| template<> LOL_ATTR_NODISCARD inline float rand<float>() { return rand<float>(1.f); } | |||||
| template<> LOL_ATTR_NODISCARD inline double rand<double>() { return rand<double>(1.0); } | |||||
| template<> LOL_ATTR_NODISCARD inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); } | |||||
| } /* namespace lol */ | } /* namespace lol */ | ||||
| @@ -35,7 +35,8 @@ namespace lol | |||||
| * avoid accidental implicit conversions ("int x = 1; sqrt(x)" will never | * avoid accidental implicit conversions ("int x = 1; sqrt(x)" will never | ||||
| * call real::sqrt). | * call real::sqrt). | ||||
| */ | */ | ||||
| template<int N> class Real | |||||
| template<int N> | |||||
| class LOL_ATTR_NODISCARD Real | |||||
| { | { | ||||
| public: | public: | ||||
| Real(); | Real(); | ||||
| @@ -53,11 +54,11 @@ public: | |||||
| Real(char const *str); | Real(char const *str); | ||||
| operator float() const; | |||||
| operator double() const; | |||||
| operator long double() const; | |||||
| operator int() const; | |||||
| operator unsigned int() const; | |||||
| LOL_ATTR_NODISCARD operator float() const; | |||||
| LOL_ATTR_NODISCARD operator double() const; | |||||
| LOL_ATTR_NODISCARD operator long double() const; | |||||
| LOL_ATTR_NODISCARD operator int() const; | |||||
| LOL_ATTR_NODISCARD operator unsigned int() const; | |||||
| Real<N> operator +() const; | Real<N> operator +() const; | ||||
| Real<N> operator -() const; | Real<N> operator -() const; | ||||
| @@ -70,15 +71,15 @@ public: | |||||
| Real<N> const &operator *=(Real<N> const &x); | Real<N> const &operator *=(Real<N> const &x); | ||||
| Real<N> const &operator /=(Real<N> const &x); | Real<N> const &operator /=(Real<N> const &x); | ||||
| bool operator ==(Real<N> const &x) const; | |||||
| bool operator !=(Real<N> const &x) const; | |||||
| bool operator <(Real<N> const &x) const; | |||||
| bool operator >(Real<N> const &x) const; | |||||
| bool operator <=(Real<N> const &x) const; | |||||
| bool operator >=(Real<N> const &x) const; | |||||
| LOL_ATTR_NODISCARD bool operator ==(Real<N> const &x) const; | |||||
| LOL_ATTR_NODISCARD bool operator !=(Real<N> const &x) const; | |||||
| LOL_ATTR_NODISCARD bool operator <(Real<N> const &x) const; | |||||
| LOL_ATTR_NODISCARD bool operator >(Real<N> const &x) const; | |||||
| LOL_ATTR_NODISCARD bool operator <=(Real<N> const &x) const; | |||||
| LOL_ATTR_NODISCARD bool operator >=(Real<N> const &x) const; | |||||
| bool operator !() const; | |||||
| operator bool() const; | |||||
| LOL_ATTR_NODISCARD bool operator !() const; | |||||
| LOL_ATTR_NODISCARD operator bool() const; | |||||
| /* Comparison functions */ | /* Comparison functions */ | ||||
| template<int K> friend Real<K> min(Real<K> const &a, Real<K> const &b); | template<int K> friend Real<K> min(Real<K> const &a, Real<K> const &b); | ||||
| @@ -238,11 +239,11 @@ template<> real::Real(int64_t i); | |||||
| template<> real::Real(uint64_t i); | template<> real::Real(uint64_t i); | ||||
| template<> real::Real(char const *str); | template<> real::Real(char const *str); | ||||
| template<> real::operator float() const; | |||||
| template<> real::operator double() const; | |||||
| template<> real::operator long double() const; | |||||
| template<> real::operator int() const; | |||||
| template<> real::operator unsigned int() const; | |||||
| template<> LOL_ATTR_NODISCARD real::operator float() const; | |||||
| template<> LOL_ATTR_NODISCARD real::operator double() const; | |||||
| template<> LOL_ATTR_NODISCARD real::operator long double() const; | |||||
| template<> LOL_ATTR_NODISCARD real::operator int() const; | |||||
| template<> LOL_ATTR_NODISCARD real::operator unsigned int() const; | |||||
| template<> real real::operator +() const; | template<> real real::operator +() const; | ||||
| template<> real real::operator -() const; | template<> real real::operator -() const; | ||||
| template<> real real::operator +(real const &x) const; | template<> real real::operator +(real const &x) const; | ||||
| @@ -253,14 +254,14 @@ template<> real const &real::operator +=(real const &x); | |||||
| template<> real const &real::operator -=(real const &x); | template<> real const &real::operator -=(real const &x); | ||||
| template<> real const &real::operator *=(real const &x); | template<> real const &real::operator *=(real const &x); | ||||
| template<> real const &real::operator /=(real const &x); | template<> real const &real::operator /=(real const &x); | ||||
| template<> bool real::operator ==(real const &x) const; | |||||
| template<> bool real::operator !=(real const &x) const; | |||||
| template<> bool real::operator <(real const &x) const; | |||||
| template<> bool real::operator >(real const &x) const; | |||||
| template<> bool real::operator <=(real const &x) const; | |||||
| template<> bool real::operator >=(real const &x) const; | |||||
| template<> bool real::operator !() const; | |||||
| template<> real::operator bool() const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator ==(real const &x) const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator !=(real const &x) const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator <(real const &x) const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator >(real const &x) const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator <=(real const &x) const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator >=(real const &x) const; | |||||
| template<> LOL_ATTR_NODISCARD bool real::operator !() const; | |||||
| template<> LOL_ATTR_NODISCARD real::operator bool() const; | |||||
| template<int K> Real<K> min(Real<K> const &a, Real<K> const &b); | template<int K> Real<K> min(Real<K> const &a, Real<K> const &b); | ||||
| template<int K> Real<K> max(Real<K> const &a, Real<K> const &b); | template<int K> Real<K> max(Real<K> const &a, Real<K> const &b); | ||||
| @@ -31,7 +31,7 @@ namespace lol | |||||
| */ | */ | ||||
| template<typename T> | template<typename T> | ||||
| struct cmplx_t : public linear_ops::base<T> | |||||
| struct LOL_ATTR_NODISCARD cmplx_t : public linear_ops::base<T> | |||||
| { | { | ||||
| static int const count = 2; | static int const count = 2; | ||||
| typedef T scalar_element; | typedef T scalar_element; | ||||
| @@ -78,7 +78,7 @@ static_assert(sizeof(dcmplx) == 16, "sizeof(dcmplx) == 16"); | |||||
| */ | */ | ||||
| template<typename T> | template<typename T> | ||||
| struct quat_t : public linear_ops::base<T> | |||||
| struct LOL_ATTR_NODISCARD quat_t : public linear_ops::base<T> | |||||
| { | { | ||||
| static int const count = 4; | static int const count = 4; | ||||
| typedef T scalar_element; | typedef T scalar_element; | ||||
| @@ -233,7 +233,7 @@ struct quat_t : public linear_ops::base<T> | |||||
| return normalize(v); | return normalize(v); | ||||
| } | } | ||||
| inline T angle() | |||||
| LOL_ATTR_NODISCARD inline T angle() | |||||
| { | { | ||||
| vec_t<T,3> v(x, y, z); | vec_t<T,3> v(x, y, z); | ||||
| T n2 = sqlength(v); | T n2 = sqlength(v); | ||||
| @@ -258,7 +258,7 @@ static_assert(sizeof(dquat) == 32, "sizeof(dquat) == 32"); | |||||
| */ | */ | ||||
| template<typename T> | template<typename T> | ||||
| struct sqt_t | |||||
| struct LOL_ATTR_NODISCARD sqt_t | |||||
| { | { | ||||
| /* Default constructor and copy constructor */ | /* Default constructor and copy constructor */ | ||||
| inline constexpr sqt_t() : s(), q(), t() {} | inline constexpr sqt_t() : s(), q(), t() {} | ||||
| @@ -325,7 +325,7 @@ struct sqt_t | |||||
| * Common operations on transforms | * Common operations on transforms | ||||
| */ | */ | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T dot(cmplx_t<T> const &t1, cmplx_t<T> const &t2) | static inline T dot(cmplx_t<T> const &t1, cmplx_t<T> const &t2) | ||||
| { | { | ||||
| T ret(0); | T ret(0); | ||||
| @@ -334,20 +334,20 @@ static inline T dot(cmplx_t<T> const &t1, cmplx_t<T> const &t2) | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T sqlength(cmplx_t<T> const &t) | static inline T sqlength(cmplx_t<T> const &t) | ||||
| { | { | ||||
| return dot(t, t); | return dot(t, t); | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T length(cmplx_t<T> const &t) | static inline T length(cmplx_t<T> const &t) | ||||
| { | { | ||||
| /* FIXME: this is not very nice */ | /* FIXME: this is not very nice */ | ||||
| return (T)sqrt((double)sqlength(t)); | return (T)sqrt((double)sqlength(t)); | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T norm(cmplx_t<T> const &t) | static inline T norm(cmplx_t<T> const &t) | ||||
| { | { | ||||
| return length(t); | return length(t); | ||||
| @@ -362,7 +362,7 @@ static inline cmplx_t<T> normalize(cmplx_t<T> const &z) | |||||
| /* XXX: duplicate */ | /* XXX: duplicate */ | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T dot(quat_t<T> const &t1, quat_t<T> const &t2) | static inline T dot(quat_t<T> const &t1, quat_t<T> const &t2) | ||||
| { | { | ||||
| T ret(0); | T ret(0); | ||||
| @@ -371,20 +371,20 @@ static inline T dot(quat_t<T> const &t1, quat_t<T> const &t2) | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T sqlength(quat_t<T> const &t) | static inline T sqlength(quat_t<T> const &t) | ||||
| { | { | ||||
| return dot(t, t); | return dot(t, t); | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T length(quat_t<T> const &t) | static inline T length(quat_t<T> const &t) | ||||
| { | { | ||||
| /* FIXME: this is not very nice */ | /* FIXME: this is not very nice */ | ||||
| return (T)sqrt((double)sqlength(t)); | return (T)sqrt((double)sqlength(t)); | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline T norm(quat_t<T> const &t) | static inline T norm(quat_t<T> const &t) | ||||
| { | { | ||||
| return length(t); | return length(t); | ||||
| @@ -419,22 +419,22 @@ static inline cmplx_t<T> operator /(cmplx_t<T> a, cmplx_t<T> const &b) | |||||
| return a * inverse(b); | return a * inverse(b); | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline bool operator ==(cmplx_t<T> const &a, T b) | static inline bool operator ==(cmplx_t<T> const &a, T b) | ||||
| { | { | ||||
| return (a.x == b) && !a.y; | return (a.x == b) && !a.y; | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline bool operator !=(cmplx_t<T> const &a, T b) | static inline bool operator !=(cmplx_t<T> const &a, T b) | ||||
| { | { | ||||
| return (a.x != b) || a.y; | return (a.x != b) || a.y; | ||||
| } | } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline bool operator ==(T a, cmplx_t<T> const &b) { return b == a; } | static inline bool operator ==(T a, cmplx_t<T> const &b) { return b == a; } | ||||
| template<typename T> | |||||
| template<typename T> LOL_ATTR_NODISCARD | |||||
| static inline bool operator !=(T a, cmplx_t<T> const &b) { return b != a; } | static inline bool operator !=(T a, cmplx_t<T> const &b) { return b != a; } | ||||
| /* | /* | ||||
| @@ -57,7 +57,7 @@ namespace lol | |||||
| */ | */ | ||||
| template<typename T, int N, int SWIZZLE> | template<typename T, int N, int SWIZZLE> | ||||
| struct vec_t | |||||
| struct LOL_ATTR_NODISCARD vec_t | |||||
| /* MUST have a different base than e.g. vec_t<T,2> otherwise the unions | /* MUST have a different base than e.g. vec_t<T,2> otherwise the unions | ||||
| * in vec_t<T,2> with the same base will cause empty base optimisation | * in vec_t<T,2> with the same base will cause empty base optimisation | ||||
| * failures. */ | * failures. */ | ||||
| @@ -108,7 +108,7 @@ struct vec_t | |||||
| /* The generic “vec_t” type, which is a fixed-size vector with no | /* The generic “vec_t” type, which is a fixed-size vector with no | ||||
| * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */ | * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */ | ||||
| template<typename T, int N> | template<typename T, int N> | ||||
| struct vec_t<T, N, FULL_SWIZZLE> | |||||
| struct LOL_ATTR_NODISCARD vec_t<T, N, FULL_SWIZZLE> | |||||
| : public componentwise_ops::base<T> | : public componentwise_ops::base<T> | ||||
| { | { | ||||
| static int const count = N; | static int const count = N; | ||||
| @@ -221,7 +221,7 @@ private: | |||||
| */ | */ | ||||
| template <typename T> | template <typename T> | ||||
| struct vec_t<T,2> | |||||
| struct LOL_ATTR_NODISCARD vec_t<T,2> | |||||
| : public swizzle_ops::base<T> | : public swizzle_ops::base<T> | ||||
| { | { | ||||
| static int const count = 2; | static int const count = 2; | ||||
| @@ -337,7 +337,7 @@ static_assert(sizeof(dvec2) == 16, "sizeof(dvec2) == 16"); | |||||
| */ | */ | ||||
| template <typename T> | template <typename T> | ||||
| struct vec_t<T,3> | |||||
| struct LOL_ATTR_NODISCARD vec_t<T,3> | |||||
| : public swizzle_ops::base<T> | : public swizzle_ops::base<T> | ||||
| { | { | ||||
| static int const count = 3; | static int const count = 3; | ||||
| @@ -583,7 +583,7 @@ static_assert(sizeof(dvec3) == 24, "sizeof(dvec3) == 24"); | |||||
| */ | */ | ||||
| template <typename T> | template <typename T> | ||||
| struct vec_t<T,4> | |||||
| struct LOL_ATTR_NODISCARD vec_t<T,4> | |||||
| : public swizzle_ops::base<T> | : public swizzle_ops::base<T> | ||||
| { | { | ||||
| static int const count = 4; | static int const count = 4; | ||||
| @@ -1138,7 +1138,7 @@ static inline vec_t<T,N> mix(vec_t<T,N,SWIZZLE1> const &x, | |||||
| * Some GLSL-like functions. | * Some GLSL-like functions. | ||||
| */ | */ | ||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> | |||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> LOL_ATTR_NODISCARD | |||||
| static inline T dot(vec_t<T,N,SWIZZLE1> const &a, | static inline T dot(vec_t<T,N,SWIZZLE1> const &a, | ||||
| vec_t<T,N,SWIZZLE2> const &b) | vec_t<T,N,SWIZZLE2> const &b) | ||||
| { | { | ||||
| @@ -1148,13 +1148,13 @@ static inline T dot(vec_t<T,N,SWIZZLE1> const &a, | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| template<typename T, int N, int SWIZZLE> | |||||
| template<typename T, int N, int SWIZZLE> LOL_ATTR_NODISCARD | |||||
| static inline T sqlength(vec_t<T,N,SWIZZLE> const &a) | static inline T sqlength(vec_t<T,N,SWIZZLE> const &a) | ||||
| { | { | ||||
| return dot(a, a); | return dot(a, a); | ||||
| } | } | ||||
| template<typename T, int N, int SWIZZLE> | |||||
| template<typename T, int N, int SWIZZLE> LOL_ATTR_NODISCARD | |||||
| static inline T length(vec_t<T,N,SWIZZLE> const &a) | static inline T length(vec_t<T,N,SWIZZLE> const &a) | ||||
| { | { | ||||
| /* FIXME: this is not very nice */ | /* FIXME: this is not very nice */ | ||||
| @@ -1172,7 +1172,7 @@ static inline vec_t<T,N> lerp(vec_t<T,N,SWIZZLE1> const &a, | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> | |||||
| template<typename T, int N, int SWIZZLE1, int SWIZZLE2> LOL_ATTR_NODISCARD | |||||
| static inline T distance(vec_t<T,N,SWIZZLE1> const &a, | static inline T distance(vec_t<T,N,SWIZZLE1> const &a, | ||||
| vec_t<T,N,SWIZZLE2> const &b) | vec_t<T,N,SWIZZLE2> const &b) | ||||
| { | { | ||||