LeviLamina
Loading...
Searching...
No Matches
CommutativeGroup.h
1#pragma once
2
3#include <concepts>
4#include <cstddef>
5
6#include "ll/api/base/Macro.h"
7
8#include "mc/math/vector/base/VectorBase.h"
9
10namespace ll::math {
12
13template <typename T>
14concept IsCommutativeGroup = std::is_base_of_v<CommutativeGroupTag, T>;
15
16template <typename T, typename... Components>
17struct LL_EBO CommutativeGroup : VectorBase<T, Components...>, CommutativeGroupTag {
18public:
19 using first_type = typename VectorBase<T, Components...>::first_type;
20
21 constexpr T& operator+=(T const& b) noexcept
23 {
24 CommutativeGroup::forEachComponent([&]<typename axis_type, size_t iter> {
25 static_cast<T*>(this)->template get<axis_type, iter>() += b.template get<axis_type, iter>();
26 });
27 return static_cast<T&>(*(static_cast<T*>(this)));
28 }
29
30 constexpr T& operator-=(T const& b) noexcept
32 {
33 CommutativeGroup::forEachComponent([&]<typename axis_type, size_t iter> {
34 static_cast<T*>(this)->template get<axis_type, iter>() -= b.template get<axis_type, iter>();
35 });
36 return static_cast<T&>(*(static_cast<T*>(this)));
37 }
38
39 [[nodiscard]] constexpr T operator+(T const& b) const noexcept
41 {
42 T tmp = *(static_cast<T const*>(this));
43 tmp += b;
44 return tmp;
45 }
46
47 [[nodiscard]] constexpr T operator-(T const& b) const noexcept
49 {
50 T tmp = *(static_cast<T const*>(this));
51 tmp -= b;
52 return tmp;
53 }
54 template <std::convertible_to<first_type> V>
55 constexpr T& operator+=(V const& b) noexcept {
56 CommutativeGroup::forEachComponent([&]<typename axis_type, size_t iter> {
57 static_cast<T*>(this)->template get<first_type, iter>() += static_cast<first_type>(b);
58 });
59 return static_cast<T&>(*(static_cast<T*>(this)));
60 }
61
62
63 template <std::convertible_to<first_type> V>
64 constexpr T& operator-=(V const& b) noexcept {
65 CommutativeGroup::forEachComponent([&]<typename axis_type, size_t iter> {
66 static_cast<T*>(this)->template get<first_type, iter>() -= static_cast<first_type>(b);
67 });
68 return static_cast<T&>(*(static_cast<T*>(this)));
69 }
70
71 template <std::convertible_to<first_type> V>
72 [[nodiscard]] constexpr T operator+(V const& b) const noexcept {
73 T tmp = *(static_cast<T const*>(this));
74 tmp += static_cast<first_type>(b);
75 return tmp;
76 }
77
78 template <std::convertible_to<first_type> V>
79 [[nodiscard]] constexpr T operator-(V const& b) const noexcept {
80 T tmp = *(static_cast<T const*>(this));
81 tmp -= static_cast<first_type>(b);
82 return tmp;
83 }
84
85 [[nodiscard]] constexpr T add(T const& b) const noexcept
87 {
88 return *(static_cast<T const*>(this)) + b;
89 }
90
91 [[nodiscard]] constexpr T sub(T const& b) const noexcept
93 {
94 return *(static_cast<T const*>(this)) - b;
95 }
96
97 template <std::convertible_to<first_type> V>
98 [[nodiscard]] constexpr T add(V const& b) const noexcept {
99 return *(static_cast<T const*>(this)) + static_cast<first_type>(b);
100 }
101
102 template <std::convertible_to<first_type> V>
103 [[nodiscard]] constexpr T sub(V const& b) const noexcept {
104 return *(static_cast<T const*>(this)) - static_cast<first_type>(b);
105 }
106};
107
108template <IsCommutativeGroup T, std::convertible_to<typename T::first_type> V>
109[[nodiscard]] constexpr auto operator+(V const& v, T const& t) noexcept {
110 return T{static_cast<typename T::first_type>(v)} + t;
111}
112
113template <IsCommutativeGroup T, std::convertible_to<typename T::first_type> V>
114[[nodiscard]] constexpr auto operator-(V const& v, T const& t) noexcept {
115 return T{static_cast<typename T::first_type>(v)} - t;
116}
117
118template <IsCommutativeGroup T>
119[[nodiscard]] constexpr T min(T const& a, T const& b) noexcept {
120 T tmp;
121 T::forEachComponent([&]<typename axis_type, size_t iter> {
122 if constexpr (std::is_base_of_v<CommutativeGroupTag, axis_type>) {
123 tmp.template get<axis_type, iter>() =
124 min<axis_type>(a.template get<axis_type, iter>(), b.template get<axis_type, iter>());
125 } else {
126 tmp.template get<axis_type, iter>() =
127 std::min<axis_type>(a.template get<axis_type, iter>(), b.template get<axis_type, iter>());
128 }
129 });
130 return tmp;
131}
132
133template <IsCommutativeGroup T>
134[[nodiscard]] constexpr T max(T const& a, T const& b) noexcept {
135 T tmp;
136 T::forEachComponent([&]<typename axis_type, size_t iter> {
137 if constexpr (std::is_base_of_v<CommutativeGroupTag, axis_type>) {
138 tmp.template get<axis_type, iter>() =
139 max<axis_type>(a.template get<axis_type, iter>(), b.template get<axis_type, iter>());
140 } else {
141 tmp.template get<axis_type, iter>() =
142 std::max<axis_type>(a.template get<axis_type, iter>(), b.template get<axis_type, iter>());
143 }
144 });
145 return tmp;
146}
147} // namespace ll::math
Definition CommutativeGroup.h:14
Definition CommutativeGroup.h:11
Definition CommutativeGroup.h:17
Definition VectorBase.h:51