Explicitly instantiate float vector members in cpp

This commit is contained in:
Vittorio Romeo 2022-06-24 01:33:33 +02:00 committed by Lukas Dürrenberger
parent a3dd3e02aa
commit 8a2aa6397f
10 changed files with 231 additions and 147 deletions

View File

@ -26,9 +26,8 @@
#define SFML_VECTOR2_HPP
#include <SFML/System/Angle.hpp>
#include <SFML/System/Export.hpp>
#include <cassert>
#include <cmath>
#include <type_traits>
namespace sf
@ -75,7 +74,7 @@ public:
constexpr explicit Vector2(const Vector2<U>& vector);
////////////////////////////////////////////////////////////
/// \brief Construct the vector from polar coordinates
/// \brief Construct the vector from polar coordinates <i><b>(floating-point)</b></i>
///
/// \param r Length of vector (can be negative)
/// \param phi Angle from X axis
@ -88,7 +87,7 @@ public:
/// * Vector2(r, phi) == Vector2(r, phi + n * 360_deg)
///
////////////////////////////////////////////////////////////
Vector2(T r, Angle phi);
SFML_SYSTEM_API Vector2(T r, Angle phi);
////////////////////////////////////////////////////////////
/// \brief Length of the vector <i><b>(floating-point)</b></i>.
@ -96,7 +95,7 @@ public:
/// If you are not interested in the actual length, but only in comparisons, consider using lengthSq().
///
////////////////////////////////////////////////////////////
T length() const;
SFML_SYSTEM_API T length() const;
////////////////////////////////////////////////////////////
/// \brief Square of vector's length.
@ -112,7 +111,7 @@ public:
/// \pre \c *this is no zero vector.
///
////////////////////////////////////////////////////////////
[[nodiscard]] Vector2 normalized() const;
[[nodiscard]] SFML_SYSTEM_API Vector2 normalized() const;
////////////////////////////////////////////////////////////
/// \brief Signed angle from \c *this to \c rhs <i><b>(floating-point)</b></i>.
@ -123,7 +122,7 @@ public:
/// \pre Neither \c *this nor \c rhs is a zero vector.
///
////////////////////////////////////////////////////////////
Angle angleTo(const Vector2& rhs) const;
SFML_SYSTEM_API Angle angleTo(const Vector2& rhs) const;
////////////////////////////////////////////////////////////
/// \brief Signed angle from +X or (1,0) vector <i><b>(floating-point)</b></i>.
@ -134,7 +133,7 @@ public:
/// \pre This vector is no zero vector.
///
////////////////////////////////////////////////////////////
Angle angle() const;
SFML_SYSTEM_API Angle angle() const;
////////////////////////////////////////////////////////////
/// \brief Rotate by angle \c phi <i><b>(floating-point)</b></i>.
@ -145,7 +144,7 @@ public:
/// this amounts to a clockwise rotation by \c phi.
///
////////////////////////////////////////////////////////////
[[nodiscard]] Vector2 rotatedBy(Angle phi) const;
[[nodiscard]] SFML_SYSTEM_API Vector2 rotatedBy(Angle phi) const;
////////////////////////////////////////////////////////////
/// \brief Projection of this vector onto \c axis <i><b>(floating-point)</b></i>.
@ -154,7 +153,7 @@ public:
/// \pre \c axis must not have length zero.
///
////////////////////////////////////////////////////////////
[[nodiscard]] constexpr Vector2 projectedOnto(const Vector2& axis) const;
[[nodiscard]] SFML_SYSTEM_API Vector2 projectedOnto(const Vector2& axis) const;
////////////////////////////////////////////////////////////
/// \brief Returns a perpendicular vector.

View File

@ -53,26 +53,6 @@ y(static_cast<T>(vector.y))
}
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T>::Vector2(T r, Angle phi) :
x(r * static_cast<T>(std::cos(phi.asRadians()))),
y(r * static_cast<T>(std::sin(phi.asRadians())))
{
static_assert(std::is_floating_point_v<T>, "Vector2::Vector2(T, Angle) is only supported for floating point types");
}
////////////////////////////////////////////////////////////
template <typename T>
T Vector2<T>::length() const
{
static_assert(std::is_floating_point_v<T>, "Vector2::length() is only supported for floating point types");
return std::hypot(x, y);
}
////////////////////////////////////////////////////////////
template <typename T>
constexpr T Vector2<T>::lengthSq() const
@ -81,68 +61,6 @@ constexpr T Vector2<T>::lengthSq() const
}
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> Vector2<T>::normalized() const
{
static_assert(std::is_floating_point_v<T>, "Vector2::normalized() is only supported for floating point types");
assert(*this != Vector2<T>());
return (*this) / length();
}
////////////////////////////////////////////////////////////
template <typename T>
Angle Vector2<T>::angleTo(const Vector2<T>& rhs) const
{
static_assert(std::is_floating_point_v<T>, "Vector2::angleTo() is only supported for floating point types");
assert(*this != Vector2<T>());
assert(rhs != Vector2<T>());
return radians(std::atan2(cross(rhs), dot(rhs)));
}
////////////////////////////////////////////////////////////
template <typename T>
Angle Vector2<T>::angle() const
{
static_assert(std::is_floating_point_v<T>, "Vector2::angle() is only supported for floating point types");
assert(*this != Vector2<T>());
return radians(std::atan2(y, x));
}
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> Vector2<T>::rotatedBy(Angle angle) const
{
static_assert(std::is_floating_point_v<T>, "Vector2::rotatedBy() is only supported for floating point types");
// No zero vector assert, because rotating a zero vector is well-defined (yields always itself)
T cos = std::cos(angle.asRadians());
T sin = std::sin(angle.asRadians());
// Don't manipulate x and y separately, otherwise they're overwritten too early
return Vector2<T>(
cos * x - sin * y,
sin * x + cos * y);
}
////////////////////////////////////////////////////////////
template <typename T>
constexpr Vector2<T> Vector2<T>::projectedOnto(const Vector2<T>& axis) const
{
static_assert(std::is_floating_point_v<T>, "Vector2::projectedOnto() is only supported for floating point types");
assert(axis != Vector2<T>());
return dot(axis) / axis.lengthSq() * axis;
}
////////////////////////////////////////////////////////////
template <typename T>
constexpr Vector2<T> Vector2<T>::perpendicular() const

View File

@ -25,9 +25,8 @@
#ifndef SFML_VECTOR3_HPP
#define SFML_VECTOR3_HPP
#include <SFML/System/Export.hpp>
#include <cassert>
#include <cmath>
#include <type_traits>
namespace sf
{
@ -79,7 +78,7 @@ public:
/// If you are not interested in the actual length, but only in comparisons, consider using lengthSq().
///
////////////////////////////////////////////////////////////
T length() const;
SFML_SYSTEM_API T length() const;
////////////////////////////////////////////////////////////
/// \brief Square of vector's length.
@ -95,7 +94,7 @@ public:
/// \pre \c *this is no zero vector.
///
////////////////////////////////////////////////////////////
[[nodiscard]] Vector3 normalized() const;
[[nodiscard]] SFML_SYSTEM_API Vector3 normalized() const;
////////////////////////////////////////////////////////////
/// \brief Dot product of two 3D vectors.

View File

@ -56,15 +56,6 @@ z(static_cast<T>(vector.z))
}
////////////////////////////////////////////////////////////
template <typename T>
T Vector3<T>::length() const
{
static_assert(std::is_floating_point_v<T>, "Vector3::length() is only supported for floating point types");
return std::hypot(x, y, z);
}
////////////////////////////////////////////////////////////
template <typename T>
@ -74,17 +65,6 @@ constexpr T Vector3<T>::lengthSq() const
}
////////////////////////////////////////////////////////////
template <typename T>
Vector3<T> Vector3<T>::normalized() const
{
static_assert(std::is_floating_point_v<T>, "Vector3::normalized() is only supported for floating point types");
assert(*this != Vector3<T>());
return (*this) / length();
}
////////////////////////////////////////////////////////////
template <typename T>
constexpr T Vector3<T>::dot(const Vector3<T>& rhs) const

View File

@ -22,8 +22,10 @@ set(SRC
${INCROOT}/Time.inl
${INCROOT}/Utf.hpp
${INCROOT}/Utf.inl
${SRCROOT}/Vector2.cpp
${INCROOT}/Vector2.hpp
${INCROOT}/Vector2.inl
${SRCROOT}/Vector3.cpp
${INCROOT}/Vector3.hpp
${INCROOT}/Vector3.inl
${SRCROOT}/FileInputStream.cpp

123
src/SFML/System/Vector2.cpp Normal file
View File

@ -0,0 +1,123 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2022 Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#include <SFML/System/Vector2.hpp>
#include <type_traits>
#include <cassert>
#include <cmath>
namespace sf
{
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> Vector2<T>::normalized() const
{
static_assert(std::is_floating_point_v<T>, "Vector2::normalized() is only supported for floating point types");
assert(*this != Vector2<T>());
return (*this) / length();
}
////////////////////////////////////////////////////////////
template <typename T>
Angle Vector2<T>::angleTo(const Vector2<T>& rhs) const
{
static_assert(std::is_floating_point_v<T>, "Vector2::angleTo() is only supported for floating point types");
assert(*this != Vector2<T>());
assert(rhs != Vector2<T>());
return radians(static_cast<float>(std::atan2(cross(rhs), dot(rhs))));
}
////////////////////////////////////////////////////////////
template <typename T>
Angle Vector2<T>::angle() const
{
static_assert(std::is_floating_point_v<T>, "Vector2::angle() is only supported for floating point types");
assert(*this != Vector2<T>());
return radians(static_cast<float>(std::atan2(y, x)));
}
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> Vector2<T>::rotatedBy(Angle angle) const
{
static_assert(std::is_floating_point_v<T>, "Vector2::rotatedBy() is only supported for floating point types");
// No zero vector assert, because rotating a zero vector is well-defined (yields always itself)
T cos = std::cos(static_cast<T>(angle.asRadians()));
T sin = std::sin(static_cast<T>(angle.asRadians()));
// Don't manipulate x and y separately, otherwise they're overwritten too early
return Vector2<T>(
cos * x - sin * y,
sin * x + cos * y);
}
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T> Vector2<T>::projectedOnto(const Vector2<T>& axis) const
{
static_assert(std::is_floating_point_v<T>, "Vector2::projectedOnto() is only supported for floating point types");
assert(axis != Vector2<T>());
return dot(axis) / axis.lengthSq() * axis;
}
////////////////////////////////////////////////////////////
template <typename T>
Vector2<T>::Vector2(T r, Angle phi) :
x(r * static_cast<T>(std::cos(phi.asRadians()))),
y(r * static_cast<T>(std::sin(phi.asRadians())))
{
static_assert(std::is_floating_point_v<T>, "Vector2::Vector2(T, Angle) is only supported for floating point types");
}
////////////////////////////////////////////////////////////
template <typename T>
T Vector2<T>::length() const
{
static_assert(std::is_floating_point_v<T>, "Vector2::length() is only supported for floating point types");
return std::hypot(x, y);
}
}
////////////////////////////////////////////////////////////
// Explicit template instantiations
////////////////////////////////////////////////////////////
template class sf::Vector2<float>;
template class sf::Vector2<double>;
template class sf::Vector2<long double>;

View File

@ -0,0 +1,62 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2022 Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#include <SFML/System/Vector3.hpp>
#include <type_traits>
#include <cassert>
#include <cmath>
namespace sf
{
////////////////////////////////////////////////////////////
template <typename T>
Vector3<T> Vector3<T>::normalized() const
{
static_assert(std::is_floating_point_v<T>, "Vector3::normalized() is only supported for floating point types");
assert(*this != Vector3<T>());
return (*this) / length();
}
////////////////////////////////////////////////////////////
template <typename T>
T Vector3<T>::length() const
{
static_assert(std::is_floating_point_v<T>, "Vector3::length() is only supported for floating point types");
return std::hypot(x, y, z);
}
}
////////////////////////////////////////////////////////////
// Explicit template instantiations
////////////////////////////////////////////////////////////
template class sf::Vector3<float>;
template class sf::Vector3<double>;
template class sf::Vector3<long double>;

View File

@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/Mouse.hpp>
#include <SFML/Window/InputImpl.hpp>
#include <SFML/Window/Window.hpp>
namespace sf

View File

@ -1,6 +1,7 @@
#include <SFML/System/Vector2.hpp>
#include "SystemUtil.hpp"
#include <type_traits>
#include <cmath>
#include <doctest.h>

View File

@ -10,6 +10,7 @@
#include <SFML/System/Vector3.hpp>
#include <iomanip>
#include <limits>
#include <ostream>
#include <sstream>
#include <string>