@@ -45,24 +45,26 @@ export namespace CppUtils::Container
4545 return self;
4646 }
4747
48- inline constexpr auto operator+=(const Vec3<T>& rhs) noexcept -> decltype(auto)
48+ template<class U>
49+ inline constexpr auto operator+=(this auto&& self, const Vec3<U>& rhs) noexcept -> decltype(self)
4950 {
50- return apply([this, rhs ](std::size_t axis) { m_values[axis] += rhs[axis]; });
51+ return self. apply([& ](std::size_t axis) { self. m_values[axis] += static_cast<T>( rhs[axis]) ; });
5152 }
5253
53- inline constexpr auto operator-=(const Vec3<T>& rhs) noexcept -> decltype(auto)
54+ template<class U>
55+ inline constexpr auto operator-=(this auto&& self, const Vec3<U>& rhs) noexcept -> decltype(self)
5456 {
55- return apply([this, rhs ](std::size_t axis) { m_values[axis] -= rhs[axis]; });
57+ return self. apply([& ](std::size_t axis) { self. m_values[axis] -= static_cast<T>( rhs[axis]) ; });
5658 }
5759
58- inline constexpr auto operator*=(T value) noexcept -> decltype(auto )
60+ inline constexpr auto operator*=(this auto&& self, auto value) noexcept -> decltype(self )
5961 {
60- return apply([this, value ](std::size_t axis) { m_values[axis] *= value; });
62+ return self. apply([& ](std::size_t axis) { self. m_values[axis] = static_cast<T>(self.m_values[axis] * value) ; });
6163 }
6264
63- inline constexpr auto operator/=(T value) noexcept -> decltype(auto )
65+ inline constexpr auto operator/=(this auto&& self, auto value) noexcept -> decltype(self )
6466 {
65- return apply([this, value ](std::size_t axis) { m_values[axis] /= value; });
67+ return self. apply([& ](std::size_t axis) { self. m_values[axis] = static_cast<T>(self.m_values[axis] / value) ; });
6668 }
6769
6870 std::array<T, 3> m_values;
@@ -71,33 +73,82 @@ export namespace CppUtils::Container
7173 template<class T>
7274 Vec3(T, T, T) -> Vec3<T>;
7375
74- template<class T>
75- [[nodiscard]] inline constexpr auto operator+(const Vec3<T>& lhs, const Vec3<T >& rhs) noexcept -> Vec3<T>
76+ template<class T, class U >
77+ [[nodiscard]] inline constexpr auto operator+(const Vec3<T>& lhs, const Vec3<U >& rhs) noexcept
7678 {
77- return auto{lhs} += rhs;
79+ using Common = std::common_type_t<T, U>;
80+ return Vec3<Common>{
81+ static_cast<Common>(lhs.x()) + static_cast<Common>(rhs.x()),
82+ static_cast<Common>(lhs.y()) + static_cast<Common>(rhs.y()),
83+ static_cast<Common>(lhs.z()) + static_cast<Common>(rhs.z())};
7884 }
7985
80- template<class T>
81- [[nodiscard]] inline constexpr auto operator-(const Vec3<T>& lhs, const Vec3<T >& rhs) noexcept -> Vec3<T>
86+ template<class T, class U >
87+ [[nodiscard]] inline constexpr auto operator-(const Vec3<T>& lhs, const Vec3<U >& rhs) noexcept
8288 {
83- return auto{lhs} -= rhs;
89+ using Common = std::common_type_t<T, U>;
90+ return Vec3<Common>{
91+ static_cast<Common>(lhs.x()) - static_cast<Common>(rhs.x()),
92+ static_cast<Common>(lhs.y()) - static_cast<Common>(rhs.y()),
93+ static_cast<Common>(lhs.z()) - static_cast<Common>(rhs.z())};
8494 }
8595
8696 template<class T>
87- [[nodiscard]] inline constexpr auto operator*(const Vec3<T>& lhs, T value) noexcept -> Vec3<T>
97+ [[nodiscard]] inline constexpr auto operator*(const Vec3<T>& lhs, auto value) noexcept
8898 {
89- return auto{lhs} *= value;
99+ using Common = std::common_type_t<T, decltype(value)>;
100+ return Vec3<Common>{
101+ static_cast<Common>(lhs.x()) * static_cast<Common>(value),
102+ static_cast<Common>(lhs.y()) * static_cast<Common>(value),
103+ static_cast<Common>(lhs.z()) * static_cast<Common>(value)};
90104 }
91105
92106 template<class T>
93- [[nodiscard]] inline constexpr auto operator*(T value, const Vec3<T>& rhs) noexcept -> Vec3<T>
107+ [[nodiscard]] inline constexpr auto operator*(auto value, const Vec3<T>& rhs) noexcept
94108 {
95- return auto{rhs} *= value;
109+ using Common = std::common_type_t<T, decltype(value)>;
110+ return Vec3<Common>{
111+ static_cast<Common>(value) * static_cast<Common>(rhs.x()),
112+ static_cast<Common>(value) * static_cast<Common>(rhs.y()),
113+ static_cast<Common>(value) * static_cast<Common>(rhs.z())};
96114 }
97115
98116 template<class T>
99- [[nodiscard]] inline constexpr auto operator/(const Vec3<T>& lhs, T value) noexcept -> Vec3<T>
117+ [[nodiscard]] inline constexpr auto operator/(const Vec3<T>& lhs, auto value) noexcept
100118 {
101- return auto{lhs} /= value;
119+ using Common = std::common_type_t<T, decltype(value)>;
120+ return Vec3<Common>{
121+ static_cast<Common>(lhs.x()) / static_cast<Common>(value),
122+ static_cast<Common>(lhs.y()) / static_cast<Common>(value),
123+ static_cast<Common>(lhs.z()) / static_cast<Common>(value)};
102124 }
103125}
126+
127+ export namespace std
128+ {
129+ template<class T, class CharT>
130+ struct formatter<CppUtils::Container::Vec3<T>, CharT>
131+ {
132+ formatter<T, CharT> m_formatter;
133+
134+ inline constexpr auto parse(auto& context)
135+ {
136+ return m_formatter.parse(context);
137+ }
138+
139+ inline auto format(const CppUtils::Container::Vec3<T>& vec, auto& context) const
140+ {
141+ auto out = context.out();
142+ out = std::format_to(out, "(");
143+ context.advance_to(out);
144+ out = m_formatter.format(vec.x(), context);
145+ out = std::format_to(out, ", ");
146+ context.advance_to(out);
147+ out = m_formatter.format(vec.y(), context);
148+ out = std::format_to(out, ", ");
149+ context.advance_to(out);
150+ out = m_formatter.format(vec.z(), context);
151+ return std::format_to(out, ")");
152+ }
153+ };
154+ }
0 commit comments