mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 14:32:46 +00:00 
			
		
		
		
	 5e1499d104
			
		
	
	
		5e1499d104
		
	
	
	
	
		
			
			This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).
This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
		
	
			
		
			
				
	
	
		
			302 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			302 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org>
 | |
|  * Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
 | |
|  * Copyright (c) 2022, the SerenityOS developers.
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <AK/Array.h>
 | |
| #include <AK/ByteString.h>
 | |
| #include <AK/Error.h>
 | |
| #include <AK/Math.h>
 | |
| #include <AK/StdLibExtras.h>
 | |
| #include <AK/StringView.h>
 | |
| 
 | |
| #define LOOP_UNROLL_N 4
 | |
| 
 | |
| #define STRINGIFY_HELPER(x) #x
 | |
| #define STRINGIFY(x) STRINGIFY_HELPER(x)
 | |
| 
 | |
| #if defined(AK_COMPILER_CLANG)
 | |
| #    define UNROLL_LOOP _Pragma(STRINGIFY(unroll))
 | |
| #else
 | |
| #    define UNROLL_LOOP _Pragma(STRINGIFY(GCC unroll(LOOP_UNROLL_N)))
 | |
| #endif
 | |
| 
 | |
| namespace Gfx {
 | |
| 
 | |
| template<size_t N, typename T>
 | |
| requires(N >= 2 && N <= 4) class VectorN final {
 | |
|     static_assert(LOOP_UNROLL_N >= N, "Unroll the entire loop for performance.");
 | |
| 
 | |
| public:
 | |
|     [[nodiscard]] constexpr VectorN() = default;
 | |
|     [[nodiscard]] constexpr VectorN(T x, T y)
 | |
|     requires(N == 2)
 | |
|         : m_data { x, y }
 | |
|     {
 | |
|     }
 | |
|     [[nodiscard]] constexpr VectorN(T x, T y, T z)
 | |
|     requires(N == 3)
 | |
|         : m_data { x, y, z }
 | |
|     {
 | |
|     }
 | |
|     [[nodiscard]] constexpr VectorN(T x, T y, T z, T w)
 | |
|     requires(N == 4)
 | |
|         : m_data { x, y, z, w }
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr T x() const { return m_data[0]; }
 | |
|     [[nodiscard]] constexpr T y() const { return m_data[1]; }
 | |
|     [[nodiscard]] constexpr T z() const
 | |
|     requires(N >= 3)
 | |
|     {
 | |
|         return m_data[2];
 | |
|     }
 | |
|     [[nodiscard]] constexpr T w() const
 | |
|     requires(N >= 4)
 | |
|     {
 | |
|         return m_data[3];
 | |
|     }
 | |
| 
 | |
|     constexpr void set_x(T value) { m_data[0] = value; }
 | |
|     constexpr void set_y(T value) { m_data[1] = value; }
 | |
|     constexpr void set_z(T value)
 | |
|     requires(N >= 3)
 | |
|     {
 | |
|         m_data[2] = value;
 | |
|     }
 | |
|     constexpr void set_w(T value)
 | |
|     requires(N >= 4)
 | |
|     {
 | |
|         m_data[3] = value;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr T const& operator[](size_t index) const
 | |
|     {
 | |
|         VERIFY(index < N);
 | |
|         return m_data[index];
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr T& operator[](size_t index)
 | |
|     {
 | |
|         VERIFY(index < N);
 | |
|         return m_data[index];
 | |
|     }
 | |
| 
 | |
|     constexpr VectorN& operator+=(VectorN const& other)
 | |
|     {
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             m_data[i] += other.data()[i];
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     constexpr VectorN& operator-=(VectorN const& other)
 | |
|     {
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             m_data[i] -= other.data()[i];
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     constexpr VectorN& operator*=(T const& t)
 | |
|     {
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             m_data[i] *= t;
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN operator+(VectorN const& other) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] + other.data()[i];
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN operator-(VectorN const& other) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] - other.data()[i];
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN operator*(VectorN const& other) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] * other.data()[i];
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN operator-() const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = -m_data[i];
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN operator/(VectorN const& other) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] / other.data()[i];
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     template<typename U>
 | |
|     [[nodiscard]] constexpr VectorN operator+(U f) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] + f;
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     template<typename U>
 | |
|     [[nodiscard]] constexpr VectorN operator-(U f) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] - f;
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     template<typename U>
 | |
|     [[nodiscard]] constexpr VectorN operator*(U f) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] * f;
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     template<typename U>
 | |
|     [[nodiscard]] constexpr VectorN operator/(U f) const
 | |
|     {
 | |
|         VectorN result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.m_data[i] = m_data[i] / f;
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr T dot(VectorN const& other) const
 | |
|     {
 | |
|         T result {};
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result += m_data[i] * other.data()[i];
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN cross(VectorN const& other) const
 | |
|     requires(N == 3)
 | |
|     {
 | |
|         return VectorN(
 | |
|             y() * other.z() - z() * other.y(),
 | |
|             z() * other.x() - x() * other.z(),
 | |
|             x() * other.y() - y() * other.x());
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN normalized() const
 | |
|     {
 | |
|         VectorN copy { *this };
 | |
|         copy.normalize();
 | |
|         return copy;
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN clamped(T m, T x) const
 | |
|     {
 | |
|         VectorN copy { *this };
 | |
|         copy.clamp(m, x);
 | |
|         return copy;
 | |
|     }
 | |
| 
 | |
|     constexpr void clamp(T min_value, T max_value)
 | |
|     {
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i) {
 | |
|             m_data[i] = max(min_value, m_data[i]);
 | |
|             m_data[i] = min(max_value, m_data[i]);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     constexpr void normalize()
 | |
|     {
 | |
|         T const inv_length = 1 / length();
 | |
|         operator*=(inv_length);
 | |
|     }
 | |
| 
 | |
|     template<typename O = T>
 | |
|     [[nodiscard]] constexpr O length() const
 | |
|     {
 | |
|         return AK::sqrt<O>(dot(*this));
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN<2, T> xy() const
 | |
|     requires(N >= 3)
 | |
|     {
 | |
|         return VectorN<2, T>(x(), y());
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] constexpr VectorN<3, T> xyz() const
 | |
|     requires(N >= 4)
 | |
|     {
 | |
|         return VectorN<3, T>(x(), y(), z());
 | |
|     }
 | |
| 
 | |
|     [[nodiscard]] ByteString to_byte_string() const
 | |
|     {
 | |
|         if constexpr (N == 2)
 | |
|             return ByteString::formatted("[{},{}]", x(), y());
 | |
|         else if constexpr (N == 3)
 | |
|             return ByteString::formatted("[{},{},{}]", x(), y(), z());
 | |
|         else
 | |
|             return ByteString::formatted("[{},{},{},{}]", x(), y(), z(), w());
 | |
|     }
 | |
| 
 | |
|     template<typename U>
 | |
|     [[nodiscard]] VectorN<N, U> to_type() const
 | |
|     {
 | |
|         VectorN<N, U> result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.data()[i] = static_cast<U>(m_data[i]);
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     template<typename U>
 | |
|     [[nodiscard]] VectorN<N, U> to_rounded() const
 | |
|     {
 | |
|         VectorN<N, U> result;
 | |
|         UNROLL_LOOP
 | |
|         for (auto i = 0u; i < N; ++i)
 | |
|             result.data()[i] = round_to<U>(m_data[i]);
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     constexpr auto& data() { return m_data; }
 | |
|     constexpr auto const& data() const { return m_data; }
 | |
| 
 | |
| private:
 | |
|     Array<T, N> m_data;
 | |
| };
 | |
| 
 | |
| }
 |