Added EXT_quaternion_relational and EXT_quaternion_geometric extensions
This commit is contained in:
@@ -180,7 +180,7 @@ namespace detail
|
||||
{
|
||||
return detail::compute_cross<T, Q, detail::is_aligned<Q>::value>::call(x, y);
|
||||
}
|
||||
|
||||
/*
|
||||
// normalize
|
||||
template<typename genType>
|
||||
GLM_FUNC_QUALIFIER genType normalize(genType const& x)
|
||||
@@ -189,7 +189,7 @@ namespace detail
|
||||
|
||||
return x < genType(0) ? genType(-1) : genType(1);
|
||||
}
|
||||
|
||||
*/
|
||||
template<length_t L, typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<L, T, Q> normalize(vec<L, T, Q> const& x)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "../detail/type_vec3.hpp"
|
||||
#include "../detail/type_vec4.hpp"
|
||||
#include "../ext/vector_relational.hpp"
|
||||
#include "../ext/quaternion_relational.hpp"
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../gtc/matrix_transform.hpp"
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/// @ref gtc_quaternion
|
||||
|
||||
#include "../trigonometric.hpp"
|
||||
#include "../geometric.hpp"
|
||||
#include "../exponential.hpp"
|
||||
#include "../ext/quaternion_geometric.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace glm{
|
||||
@@ -170,7 +168,7 @@ namespace detail
|
||||
t = cross(u, v);
|
||||
}
|
||||
|
||||
*this = normalize(qua<T, Q>(real_part, t.x, t.y, t.z));
|
||||
*this = normalize(qua<T, Q>(real_part, t.x, t.y, t.z));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
|
||||
71
glm/ext/quaternion_geometric.hpp
Normal file
71
glm/ext/quaternion_geometric.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/// @ref ext_quaternion_geometric
|
||||
/// @file glm/ext/quaternion_geometric.hpp
|
||||
///
|
||||
/// @see core (dependence)
|
||||
///
|
||||
/// @defgroup ext_quaternion_geometric GLM_EXT_quaternion_geometric
|
||||
/// @ingroup gtx
|
||||
///
|
||||
/// Include <glm/ext/quaternion_geometric.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines a templated quaternion type and several quaternion operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../gtc/constants.hpp"
|
||||
#include "../gtc/matrix_transform.hpp"
|
||||
#include "../ext/vector_relational.hpp"
|
||||
#include "../ext/quaternion_float.hpp"
|
||||
#include "../ext/quaternion_float_precision.hpp"
|
||||
#include "../ext/quaternion_double.hpp"
|
||||
#include "../ext/quaternion_double_precision.hpp"
|
||||
#include "../ext/quaternion_relational.hpp"
|
||||
#include "../detail/type_mat3x3.hpp"
|
||||
#include "../detail/type_mat4x4.hpp"
|
||||
#include "../detail/type_vec3.hpp"
|
||||
#include "../detail/type_vec4.hpp"
|
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_GTC_quaternion extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup ext_quaternion_geometric
|
||||
/// @{
|
||||
|
||||
/// Returns the length of the quaternion.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T length(qua<T, Q> const& q);
|
||||
|
||||
/// Returns the normalized quaternion.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL qua<T, Q> normalize(qua<T, Q> const& q);
|
||||
|
||||
/// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
|
||||
///
|
||||
/// @tparam T Floating-point scalar types.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL T dot(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Compute a cross product between a quaternion and a vector.
|
||||
///
|
||||
/// @see ext_quaternion_geometric
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "quaternion_geometric.inl"
|
||||
42
glm/ext/quaternion_geometric.inl
Normal file
42
glm/ext/quaternion_geometric.inl
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "../geometric.hpp"
|
||||
#include "../exponential.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace glm
|
||||
{
|
||||
// -- Operations --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T dot(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
|
||||
return detail::compute_dot<qua<T, Q>, T, detail::is_aligned<Q>::value>::call(x, y);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T length(qua<T, Q> const& q)
|
||||
{
|
||||
return glm::sqrt(dot(q, q));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> normalize(qua<T, Q> const& q)
|
||||
{
|
||||
T len = length(q);
|
||||
if(len <= static_cast<T>(0)) // Problem
|
||||
return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
|
||||
T oneOverLen = T(1) / len;
|
||||
return qua<T, Q>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2)
|
||||
{
|
||||
return qua<T, Q>(
|
||||
q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
|
||||
q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
|
||||
q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z,
|
||||
q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x);
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
100
glm/ext/quaternion_relational.hpp
Normal file
100
glm/ext/quaternion_relational.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/// @ref ext_quaternion_relational
|
||||
/// @file glm/ext/quaternion_relational.hpp
|
||||
///
|
||||
/// @defgroup ext_quaternion_relational GLM_EXT_quaternion_relational
|
||||
/// @ingroup gtc
|
||||
///
|
||||
/// Include <glm/ext/quaternion_relational.hpp> to use the features of this extension.
|
||||
///
|
||||
/// Defines a templated quaternion type and several quaternion operations.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Dependency:
|
||||
#include "../detail/qualifier.hpp"
|
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
# pragma message("GLM: GLM_EXT_quaternion_relational extension included")
|
||||
#endif
|
||||
|
||||
namespace glm
|
||||
{
|
||||
/// @addtogroup ext_quaternion_relational
|
||||
/// @{
|
||||
|
||||
/// Returns the component-wise comparison result of x < y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Returns the component-wise comparison of result x <= y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Returns the component-wise comparison of result x > y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Returns the component-wise comparison of result x >= y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Returns the component-wise comparison of result x == y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Returns the component-wise comparison of |x - y| < epsilon.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon);
|
||||
|
||||
/// Returns the component-wise comparison of result x != y.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y);
|
||||
|
||||
/// Returns the component-wise comparison of |x - y| >= epsilon.
|
||||
///
|
||||
/// @tparam T Floating-point scalar types
|
||||
/// @tparam Q Value from qualifier enum
|
||||
///
|
||||
/// @see ext_quaternion_relational
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon);
|
||||
|
||||
/// @}
|
||||
} //namespace glm
|
||||
|
||||
#include "quaternion_relational.inl"
|
||||
71
glm/ext/quaternion_relational.inl
Normal file
71
glm/ext/quaternion_relational.inl
Normal file
@@ -0,0 +1,71 @@
|
||||
namespace glm
|
||||
{
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] < y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] <= y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] > y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] >= y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon)
|
||||
{
|
||||
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
|
||||
return lessThan(abs(v), vec<4, T, Q>(epsilon));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = !detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon)
|
||||
{
|
||||
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
|
||||
return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon));
|
||||
}
|
||||
}//namespace glm
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#pragma once
|
||||
|
||||
// Dependencies
|
||||
#include "../detail/setup.hpp"
|
||||
#include "../detail/qualifier.hpp"
|
||||
|
||||
#if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "../ext/quaternion_float_precision.hpp"
|
||||
#include "../ext/quaternion_double.hpp"
|
||||
#include "../ext/quaternion_double_precision.hpp"
|
||||
#include "../ext/quaternion_relational.hpp"
|
||||
#include "../ext/quaternion_geometric.hpp"
|
||||
#include "../detail/type_mat3x3.hpp"
|
||||
#include "../detail/type_mat4x4.hpp"
|
||||
#include "../detail/type_vec3.hpp"
|
||||
@@ -35,14 +37,6 @@ namespace glm
|
||||
/// @addtogroup gtc_quaternion
|
||||
/// @{
|
||||
|
||||
// -- Boolean operators --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator==(qua<T, Q> const& q1, qua<T, Q> const& q2);
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR bool operator!=(qua<T, Q> const& q1, qua<T, Q> const& q2);
|
||||
|
||||
/// Builds an identity quaternion.
|
||||
template<typename genType>
|
||||
GLM_FUNC_DECL GLM_CONSTEXPR genType identity();
|
||||
|
||||
@@ -9,39 +9,6 @@
|
||||
namespace glm
|
||||
{
|
||||
// -- Operations --
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T dot(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' accepts only floating-point inputs");
|
||||
return detail::compute_dot<qua<T, Q>, T, detail::is_aligned<Q>::value>::call(x, y);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER T length(qua<T, Q> const& q)
|
||||
{
|
||||
return glm::sqrt(dot(q, q));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> normalize(qua<T, Q> const& q)
|
||||
{
|
||||
T len = length(q);
|
||||
if(len <= T(0)) // Problem
|
||||
return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
|
||||
T oneOverLen = T(1) / len;
|
||||
return qua<T, Q>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER qua<T, Q> cross(qua<T, Q> const& q1, qua<T, Q> const& q2)
|
||||
{
|
||||
return qua<T, Q>(
|
||||
q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
|
||||
q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
|
||||
q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z,
|
||||
q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x);
|
||||
}
|
||||
/*
|
||||
// (x * sin(1 - a) * angle / sin(angle)) + (y * sin(a) * angle / sin(angle))
|
||||
template<typename T, qualifier Q>
|
||||
@@ -354,74 +321,6 @@ namespace glm
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThan(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] < y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> lessThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] <= y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThan(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] > y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> greaterThanEqual(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = x[i] >= y[i];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> equal(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon)
|
||||
{
|
||||
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
|
||||
return lessThan(abs(v), vec<4, T, Q>(epsilon));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y)
|
||||
{
|
||||
vec<4, bool, Q> Result;
|
||||
for(length_t i = 0; i < x.length(); ++i)
|
||||
Result[i] = !detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> notEqual(qua<T, Q> const& x, qua<T, Q> const& y, T epsilon)
|
||||
{
|
||||
vec<4, T, Q> v(x.x - y.x, x.y - y.y, x.z - y.z, x.w - y.w);
|
||||
return greaterThanEqual(abs(v), vec<4, T, Q>(epsilon));
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER vec<4, bool, Q> isnan(qua<T, Q> const& q)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user