From f791b672ed92f5ced9f33d74a4a140f8d54ddda3 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 11 Feb 2015 18:59:36 +0000 Subject: [PATCH] misc: lots of compilation fixes for Visual Studio (related to mediocre support for enable_if and other template metaprogramming techniques), for Clang (related to static const template class member initialisation) and for GCC (related to forward declaration of non-int enum classes). --- src/Makefile.am | 2 +- src/lol/algorithm/aabb_tree.h | 20 +++--- src/lol/algorithm/portal.h | 18 +++--- src/lol/algorithm/sort.h | 6 -- src/lol/base/array.h | 12 +++- src/lol/math/bigint.h | 30 ++++++--- src/lol/math/matrix.h | 27 +++++--- src/lol/math/vector.h | 112 +++++++++++++++++++++++----------- src/lolcore.vcxproj | 1 + src/lolcore.vcxproj.filters | 3 + src/math/constants.cpp | 74 +++------------------- src/sys/hacks.cpp | 42 +++++++++++++ tools/lolunit/lolunit.h | 15 +++-- 13 files changed, 214 insertions(+), 148 deletions(-) create mode 100644 src/sys/hacks.cpp diff --git a/src/Makefile.am b/src/Makefile.am index f9a6d470..d1cbb45e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -100,7 +100,7 @@ liblolcore_sources = \ mesh/mesh.cpp mesh/mesh.h \ mesh/primitive.cpp mesh/primitive.h \ \ - sys/init.cpp sys/timer.cpp sys/file.cpp \ + sys/init.cpp sys/timer.cpp sys/file.cpp sys/hacks.cpp \ sys/thread.cpp sys/threadbase.h \ \ image/image.cpp image/image-private.h image/kernel.cpp image/pixel.cpp \ diff --git a/src/lol/algorithm/aabb_tree.h b/src/lol/algorithm/aabb_tree.h index d9c1719c..fc6c385b 100644 --- a/src/lol/algorithm/aabb_tree.h +++ b/src/lol/algorithm/aabb_tree.h @@ -1,12 +1,14 @@ // -// Lol Engine +// Lol Engine // -// Copyright: (c) 2010-2014 Sam Hocevar -// (c) 2013-2014 Benjamin "Touky" Huet -// This program is free software; you can redistribute it and/or -// modify it under the terms of the Do What The Fuck You Want To -// Public License, Version 2, as published by Sam Hocevar. See -// http://www.wtfpl.net/ for more details. +// Copyright © 2010—2015 Sam Hocevar +// © 2013—2015 Benjamin "Touky" Huet +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. // #pragma once @@ -66,7 +68,7 @@ void DrawInner(TREE *tree, array &boxes, } //-- -template +template void Draw(Quadtree* tree, vec4 color) { array boxes; @@ -97,7 +99,7 @@ void Draw(Quadtree* tree, vec4 color) } } //-- -template +template void Draw(Octree* tree, vec4 color) { array boxes; diff --git a/src/lol/algorithm/portal.h b/src/lol/algorithm/portal.h index de83ea9d..c5937b40 100644 --- a/src/lol/algorithm/portal.h +++ b/src/lol/algorithm/portal.h @@ -1,12 +1,14 @@ // -// Lol Engine +// Lol Engine // -// Copyright: (c) 2010-2014 Sam Hocevar -// (c) 2013-2014 Benjamin "Touky" Huet -// This program is free software; you can redistribute it and/or -// modify it under the terms of the Do What The Fuck You Want To -// Public License, Version 2, as published by Sam Hocevar. See -// http://www.wtfpl.net/ for more details. +// Copyright © 2010—2015 Sam Hocevar +// © 2013—2015 Benjamin "Touky" Huet +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. // #pragma once @@ -27,7 +29,7 @@ template class PortalSet; //-- namespace Debug { -template +template void Draw(PortalDoor& port, vec4 color) { vec3 points[4]; port.GetPoints(points); diff --git a/src/lol/algorithm/sort.h b/src/lol/algorithm/sort.h index 06629568..4febfae1 100644 --- a/src/lol/algorithm/sort.h +++ b/src/lol/algorithm/sort.h @@ -18,12 +18,6 @@ namespace lol { -enum class SortAlgorithm : uint8_t -{ - QuickSwap, - Bubble, -}; - template void array_base::Shuffle() { diff --git a/src/lol/base/array.h b/src/lol/base/array.h index e71c9f91..11194427 100644 --- a/src/lol/base/array.h +++ b/src/lol/base/array.h @@ -33,6 +33,16 @@ namespace lol static ptrdiff_t const INDEX_NONE = -1; +/* + * Sorting algorithm list + */ + +enum class SortAlgorithm : uint8_t +{ + QuickSwap, + Bubble, +}; + /* * The base array type. * @@ -383,7 +393,7 @@ public: } void Shuffle(); - void Sort(enum class SortAlgorithm : uint8_t); + void Sort(SortAlgorithm algorithm); void SortQuickSwap(ptrdiff_t start, ptrdiff_t stop); /* TODO: remove these legacy functions one day */ diff --git a/src/lol/math/bigint.h b/src/lol/math/bigint.h index 2e7f3ebf..a4743611 100644 --- a/src/lol/math/bigint.h +++ b/src/lol/math/bigint.h @@ -31,6 +31,20 @@ namespace lol /* Avoid issues with NaCl headers */ #undef log2 +template +class bigint_digits +{ +protected: + T m_digits[N]; +}; + +template +class bigint_digits<0, T> +{ +protected: + static T const m_digits[1]; +}; + /* * A bigint stores its digits in an array of integers. The MSB of the * integers are unused. The highest used bit is the sign bit. @@ -39,7 +53,7 @@ namespace lol */ template -class bigint +class bigint : public bigint_digits { static int const bits_per_digit = sizeof(T) * 8 - 1; static T const digit_mask = ~((T)1 << bits_per_digit); @@ -190,9 +204,9 @@ public: * and pad missing digits if one of the two operands is shorter. */ template - bigint<(N > M) ? N : M, T> operator +(bigint const &x) const + bigint<((N > M) ? N : M), T> operator +(bigint const &x) const { - bigint<(N > M) ? N : M, T> ret; + bigint<((N > M) ? N : M), T> ret; T padding = is_negative() ? digit_mask : (T)0; T x_padding = x.is_negative() ? digit_mask : (T)0; T carry(0); @@ -213,7 +227,7 @@ public: * FIXME: this could be factored with operator+(). */ template - bigint<(N > M) ? N : M, T> operator -(bigint const &x) const + bigint<((N > M) ? N : M), T> operator -(bigint const &x) const { bigint<(N > M) ? N : M, T> ret; T padding = is_negative() ? digit_mask : (T)0; @@ -359,7 +373,7 @@ private: } template - typename std::enable_if<(N == M && N >= 64), bigint> + typename std::enable_if<(N == M) && (N >= 64), bigint> ::type inline multiply(bigint const &b) const { bigint<2 * N, T> ret, tmp(0); @@ -379,8 +393,8 @@ private: return ret + tmp; } - template - typename std::enable_if<(N == M && N == 1), bigint> + template + typename std::enable_if<(N == M) && (N == 1), bigint> ::type inline multiply(bigint const &b) const { bigint<2, T> ret; @@ -404,8 +418,6 @@ private: ret |= m_digits[digit_index + 1] << (bits_per_digit - bit_index); return ret; } - - T m_digits[N]; }; /* diff --git a/src/lol/math/matrix.h b/src/lol/math/matrix.h index 4612b11f..f21151f0 100644 --- a/src/lol/math/matrix.h +++ b/src/lol/math/matrix.h @@ -1,11 +1,13 @@ // -// Lol Engine +// Lol Engine // -// Copyright: (c) 2010-2014 Sam Hocevar -// This program is free software; you can redistribute it and/or -// modify it under the terms of the Do What The Fuck You Want To -// Public License, Version 2, as published by Sam Hocevar. See -// http://www.wtfpl.net/ for more details. +// Copyright © 2010-2015 Sam Hocevar +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. // #pragma once @@ -531,7 +533,7 @@ void lu_decomposition(mat_t const &m, mat_t & L, mat_t= j) */ { - L[i][j] = i == j ? 1 : 0; + L[i][j] = i == j ? T(1) : T(0); U[i][j] = (m[i][j] - sum) / L[j][j]; } } @@ -697,6 +699,17 @@ outer(mat_t const &a, mat_t const &b) return ret; } +/* + * Constants + */ + +template +mat_t const mat_t::identity = mat_t((T)1); +template +mat_t const mat_t::identity = mat_t((T)1); +template +mat_t const mat_t::identity = mat_t((T)1); + #if !LOL_FEATURE_CXX11_CONSTEXPR #undef constexpr #endif diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index 61459f11..8aa4ed0f 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -1,11 +1,13 @@ // -// Lol Engine +// Lol Engine // -// Copyright: (c) 2010-2014 Sam Hocevar -// This program is free software; you can redistribute it and/or -// modify it under the terms of the Do What The Fuck You Want To -// Public License, Version 2, as published by Sam Hocevar. See -// http://www.wtfpl.net/ for more details. +// Copyright © 2010-2015 Sam Hocevar +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. // #pragma once @@ -123,10 +125,17 @@ struct vec_t /* Explicit constructor that takes exactly N arguments thanks to SFINAE. */ template - explicit inline vec_t(typename std::enable_if - ::type const &x, ARGS... args) + explicit inline vec_t(typename std::enable_if<(sizeof...(ARGS) == N - 1) && (N > 1), T> + ::type const &X, ARGS... args) + { + internal_init(m_data, X, args...); + } + + /* Various explicit constructors */ + explicit inline vec_t(T const &X) { - internal_init(m_data, x, args...); + for (auto &value : m_data) + value = X; } /* Explicit constructor for type conversion */ @@ -134,7 +143,7 @@ struct vec_t explicit inline vec_t(vec_t const &v) { for (int i = 0; i < N; ++i) - m_data[i] = (T)v[i]; + m_data[i] = T(v[i]); } /* Factory for base axis vectors, e.g. [1,0,0,…,0] */ @@ -142,8 +151,8 @@ struct vec_t { ASSERT(i >= 0); ASSERT(i < N); - vec_t ret((T)0); - ret[i] = (T)1; + vec_t ret(T(0)); + ret[i] = T(1); return ret; } @@ -154,20 +163,15 @@ struct vec_t auto l = list.begin(); for (int i = 0; i < count && l != list.end(); ++i, ++l) m_data[i] = *l; - for (int i = list.size(); i < count; ++i) - m_data[i] = (T)0; - } - - /* Various explicit constructors */ - explicit inline vec_t(T X) - { - for (int i = 0; i < N; ++i) - m_data[i] = X; + for (int i = (int)list.size(); i < count; ++i) + m_data[i] = T(0); } inline T& operator[](size_t n) { return m_data[n]; } inline T const& operator[](size_t n) const { return m_data[n]; } + static const vec_t zero; + private: template static inline void internal_init(T *data, T const &x, ARGS... args) @@ -228,7 +232,7 @@ struct vec_t /* Explicit constructor for type conversion */ template explicit inline constexpr vec_t(vec_t const &v) - : x(v[0]), y(v[1]) {} + : x(T(v[0])), y(T(v[1])) {} /* Constructor for initializer_list. We need these ugly * loops until C++ lets us initialize m_data directly. */ @@ -237,8 +241,8 @@ struct vec_t auto l = list.begin(); for (int i = 0; i < count && l != list.end(); ++i, ++l) m_data[i] = *l; - for (int i = list.size(); i < count; ++i) - m_data[i] = (T)0; + for (int i = (int)list.size(); i < count; ++i) + m_data[i] = T(0); } /* Various explicit constructors */ @@ -252,7 +256,7 @@ struct vec_t { ASSERT(i >= 0); ASSERT(i < 2); - return vec_t((T)(i == 0), (T)(i == 1)); + return vec_t(T(i == 0), T(i == 1)); } LOL_COMMON_MEMBER_OPS(x) @@ -343,7 +347,7 @@ struct vec_t /* Explicit constructor for type conversion */ template explicit inline constexpr vec_t(vec_t const &v) - : x(v[0]), y(v[1]), z(v[2]) {} + : x(T(v[0])), y(T(v[1])), z(T(v[2])) {} /* Constructor for initializer_list. We need these ugly * loops until C++ lets us initialize m_data directly. */ @@ -352,8 +356,8 @@ struct vec_t auto l = list.begin(); for (int i = 0; i < count && l != list.end(); ++i, ++l) m_data[i] = *l; - for (int i = list.size(); i < count; ++i) - m_data[i] = (T)0; + for (int i = (int)list.size(); i < count; ++i) + m_data[i] = T(0); } /* Various explicit constructors */ @@ -371,7 +375,7 @@ struct vec_t { ASSERT(i >= 0); ASSERT(i < 3); - return vec_t((T)(i == 0), (T)(i == 1), (T)(i == 2)); + return vec_t(T(i == 0), T(i == 1), T(i == 2)); } LOL_COMMON_MEMBER_OPS(x) @@ -402,8 +406,8 @@ struct vec_t friend inline type orthogonal(type const &a) { return lol::abs(a.x) > lol::abs(a.z) - ? type(-a.y, a.x, (T)0) - : type((T)0, -a.z, a.y); + ? type(-a.y, a.x, T(0)) + : type(T(0), -a.z, a.y); } /* Return a vector that is orthonormal to “a” */ @@ -589,7 +593,7 @@ struct vec_t /* Explicit constructor for type conversion */ template explicit inline constexpr vec_t(vec_t const &v) - : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {} + : x(T(v[0])), y(T(v[1])), z(T(v[2])), w(T(v[3])) {} /* Constructor for initializer_list. We need these ugly * loops until C++ lets us initialize m_data directly. */ @@ -598,8 +602,8 @@ struct vec_t auto l = list.begin(); for (int i = 0; i < count && l != list.end(); ++i, ++l) m_data[i] = *l; - for (int i = list.size(); i < count; ++i) - m_data[i] = (T)0; + for (int i = (int)list.size(); i < count; ++i) + m_data[i] = T(0); } /* Various explicit constructors */ @@ -625,7 +629,7 @@ struct vec_t { ASSERT(i >= 0); ASSERT(i < 4); - return vec_t((T)(i == 0), (T)(i == 1), (T)(i == 2), (T)(i == 3)); + return vec_t(T(i == 0), T(i == 1), T(i == 2), T(i == 3)); } LOL_COMMON_MEMBER_OPS(x) @@ -1142,7 +1146,7 @@ template static inline T length(vec_t const &a) { /* FIXME: this is not very nice */ - return (T)sqrt((double)sqlength(a)); + return T(sqrt((double)sqlength(a))); } template @@ -1184,7 +1188,7 @@ static inline vec_t saturate(vec_t const &a) template static inline vec_t normalize(vec_t const &a) { - T norm = (T)length(a); + T norm = T(length(a)); return norm ? a / norm : vec_t(T(0)); } @@ -1272,6 +1276,40 @@ inline vec_const_iter end(vec_t const &a) return vec_const_iter(a, N); } +/* + * Constants + */ + +template +vec_t const vec_t::zero = vec_t(T(0)); +template +vec_t const vec_t::zero = vec_t(T(0)); +template +vec_t const vec_t::zero = vec_t(T(0)); +template +vec_t const vec_t::zero = vec_t(T(0)); + +template +vec_t const vec_t::axis_x = vec_t(T(1), T(0)); +template +vec_t const vec_t::axis_y = vec_t(T(0), T(1)); + +template +vec_t const vec_t::axis_x = vec_t(T(1), T(0), T(0)); +template +vec_t const vec_t::axis_y = vec_t(T(0), T(1), T(0)); +template +vec_t const vec_t::axis_z = vec_t(T(0), T(0), T(1)); + +template +vec_t const vec_t::axis_x = vec_t(T(1), T(0), T(0), T(0)); +template +vec_t const vec_t::axis_y = vec_t(T(0), T(1), T(0), T(0)); +template +vec_t const vec_t::axis_z = vec_t(T(0), T(0), T(1), T(0)); +template +vec_t const vec_t::axis_w = vec_t(T(0), T(0), T(0), T(1)); + #if !LOL_FEATURE_CXX11_CONSTEXPR #undef constexpr #endif diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj index 5c3744ff..8fa5a6a8 100644 --- a/src/lolcore.vcxproj +++ b/src/lolcore.vcxproj @@ -212,6 +212,7 @@ + diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters index 1e0f23e2..cae81669 100644 --- a/src/lolcore.vcxproj.filters +++ b/src/lolcore.vcxproj.filters @@ -297,6 +297,9 @@ easymesh + + sys + sys diff --git a/src/math/constants.cpp b/src/math/constants.cpp index 7caf8266..246d66bc 100644 --- a/src/math/constants.cpp +++ b/src/math/constants.cpp @@ -1,75 +1,21 @@ // -// Lol Engine +// Lol Engine // -// Copyright: (c) 2010-2013 Sam Hocevar -// This program is free software; you can redistribute it and/or -// modify it under the terms of the Do What The Fuck You Want To -// Public License, Version 2, as published by Sam Hocevar. See -// http://www.wtfpl.net/ for more details. +// Copyright © 2010-2015 Sam Hocevar +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. // #include namespace lol { -#define LOL_VEC_2_CONST(T, name, a, b) \ - template<> \ - vec_t const vec_t::name = vec_t((T)a, (T)b); - -#define LOL_VEC_3_CONST(T, name, a, b, c) \ - template<> \ - vec_t const vec_t::name = vec_t((T)a, (T)b, (T)c); - -#define LOL_VEC_4_CONST(T, name, a, b, c, d) \ - template<> \ - vec_t const vec_t::name = vec_t((T)a, (T)b, (T)c, (T)d); - -#define LOL_MAT_CONST(T, name, a) \ - template<> \ - mat_t const mat_t::name = mat_t((T)a); \ - \ - template<> \ - mat_t const mat_t::name = mat_t((T)a); \ - \ - template<> \ - mat_t const mat_t::name = mat_t((T)a); - -#define LOL_ALL_CONST_INNER(T) \ - LOL_VEC_2_CONST(T, zero, 0, 0) \ - LOL_VEC_2_CONST(T, axis_x, 1, 0) \ - LOL_VEC_2_CONST(T, axis_y, 0, 1) \ - \ - LOL_VEC_3_CONST(T, zero, 0, 0, 0) \ - LOL_VEC_3_CONST(T, axis_x, 1, 0, 0) \ - LOL_VEC_3_CONST(T, axis_y, 0, 1, 0) \ - LOL_VEC_3_CONST(T, axis_z, 0, 0, 1) \ - \ - LOL_VEC_4_CONST(T, zero, 0, 0, 0, 0) \ - LOL_VEC_4_CONST(T, axis_x, 1, 0, 0, 0) \ - LOL_VEC_4_CONST(T, axis_y, 0, 1, 0, 0) \ - LOL_VEC_4_CONST(T, axis_z, 0, 0, 1, 0) \ - LOL_VEC_4_CONST(T, axis_w, 0, 0, 0, 1) \ - \ - LOL_MAT_CONST(T, identity, 1) - -#if LOL_FEATURE_CXX11_UNRESTRICTED_UNIONS -LOL_ALL_CONST_INNER(half) -#endif -LOL_ALL_CONST_INNER(float) -LOL_ALL_CONST_INNER(double) -LOL_ALL_CONST_INNER(ldouble) -#if LOL_FEATURE_CXX11_UNRESTRICTED_UNIONS -LOL_ALL_CONST_INNER(real) -#endif - -LOL_ALL_CONST_INNER(int8_t) -LOL_ALL_CONST_INNER(uint8_t) -LOL_ALL_CONST_INNER(int16_t) -LOL_ALL_CONST_INNER(uint16_t) -LOL_ALL_CONST_INNER(int32_t) -LOL_ALL_CONST_INNER(uint32_t) -LOL_ALL_CONST_INNER(int64_t) -LOL_ALL_CONST_INNER(uint64_t) +// There is nothing here for now. +extern int unused_file_constants_cpp; }; /* namespace lol */ diff --git a/src/sys/hacks.cpp b/src/sys/hacks.cpp new file mode 100644 index 00000000..46f2cfc1 --- /dev/null +++ b/src/sys/hacks.cpp @@ -0,0 +1,42 @@ +// +// Lol Engine +// +// Copyright © 2010-2015 Sam Hocevar +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. +// + +#include + +/* + * VS 2015 hack: the CRT was fully rewritten, and functions such + * as _iob_func() and fprintf() have disappeared. Since we link with + * libSDL which uses these versions, we need to provide them. + */ + +#if _MSC_VER >= 1900 +#include + +extern "C" { + +void *__imp___iob_func(void) +{ + return NULL; +} + +int __imp_fprintf(FILE *stream, char const *fmt, ...) +{ + va_list va; + va_start(va, fmt); + int ret = vfprintf(stream, fmt, va); + va_end(va); + return ret; +} + +} +#endif + diff --git a/tools/lolunit/lolunit.h b/tools/lolunit/lolunit.h index c3bdac3a..4469e123 100644 --- a/tools/lolunit/lolunit.h +++ b/tools/lolunit/lolunit.h @@ -1,11 +1,13 @@ // -// Lol Engine +// Lol Engine // -// Copyright: (c) 2010-2011 Sam Hocevar -// This program is free software; you can redistribute it and/or -// modify it under the terms of the Do What The Fuck You Want To -// Public License, Version 2, as published by Sam Hocevar. See -// http://www.wtfpl.net/ for more details. +// Copyright © 2010-2015 Sam Hocevar +// +// This library is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. // #pragma once @@ -324,6 +326,7 @@ public: public: \ lol_unit_helper_test_##N() \ { \ + (void)lol_unit_helper_name(nullptr); \ AddTestCase(this, #N, \ (void (FixtureClass::*)()) &FixtureClass::N); \ } \