2222
2323#pragma once
2424
25- #include < mp-units/bits/module_macros.h>
2625#include < mp-units/bits/requires_hosted.h>
26+ #include < mp-units/bits/module_macros.h>
2727#include < mp-units/cartesian_vector.h>
2828#include < mp-units/framework/customization_points.h>
2929#include < mp-units/framework/representation_concepts.h>
@@ -56,6 +56,8 @@ class cartesian_tensor {
5656 static_assert (R >= 1 && R <= 3 && C >= 1 && C <= 3 , " cartesian_tensor supports sizes up to 3x3" );
5757
5858public:
59+ // NOTE: This type is intentionally an aggregate (like std::array).
60+ // All special member functions are implicitly defined.
5961 T _data_[R * C];
6062 using value_type = T;
6163 static constexpr std::size_t rows_v = R;
@@ -82,7 +84,7 @@ class cartesian_tensor {
8284};
8385
8486
85- template <typename T, typename U, std::size_t R, std::size_t K, std::size_t C>
87+ MP_UNITS_EXPORT template <typename T, typename U, std::size_t R, std::size_t K, std::size_t C>
8688[[nodiscard]] constexpr auto matmul (const cartesian_tensor<T, R, K>& A, const cartesian_tensor<U, K, C>& B)
8789{
8890 using CT = std::common_type_t <T, U>;
@@ -96,7 +98,7 @@ template<typename T, typename U, std::size_t R, std::size_t K, std::size_t C>
9698 return Rm;
9799}
98100
99- template <typename T, typename U>
101+ MP_UNITS_EXPORT template <typename T, typename U>
100102[[nodiscard]] constexpr auto matvec (const cartesian_tensor<T, 3 , 3 >& tensor, const cartesian_vector<U>& vector)
101103{
102104 using CT = std::common_type_t <T, U>;
@@ -109,7 +111,7 @@ template<typename T, typename U>
109111 return y;
110112}
111113
112- template <typename T, typename U, std::size_t R, std::size_t C>
114+ MP_UNITS_EXPORT template <typename T, typename U, std::size_t R, std::size_t C>
113115[[nodiscard]] constexpr auto double_contraction (const cartesian_tensor<T, R, C>& A, const cartesian_tensor<U, R, C>& B)
114116{
115117 using CT = std::common_type_t <T, U>;
@@ -119,7 +121,7 @@ template<typename T, typename U, std::size_t R, std::size_t C>
119121}
120122
121123
122- template <typename T, typename U>
124+ MP_UNITS_EXPORT template <typename T, typename U>
123125[[nodiscard]] constexpr auto outer_numeric (const cartesian_vector<T>& lhs, const cartesian_vector<U>& rhs)
124126{
125127 using CT = std::common_type_t <T, U>;
@@ -129,7 +131,7 @@ template<typename T, typename U>
129131 return Rm;
130132}
131133
132- template <typename T, typename U, std::size_t R, std::size_t C>
134+ MP_UNITS_EXPORT template <typename T, typename U, std::size_t R, std::size_t C>
133135 requires requires (const T& t, const U& u) { t + u; }
134136[[nodiscard]] constexpr auto operator +(const cartesian_tensor<T, R, C>& A, const cartesian_tensor<U, R, C>& B)
135137{
@@ -139,7 +141,7 @@ template<typename T, typename U, std::size_t R, std::size_t C>
139141 return Rm;
140142}
141143
142- template <typename T, typename U, std::size_t R, std::size_t C>
144+ MP_UNITS_EXPORT template <typename T, typename U, std::size_t R, std::size_t C>
143145 requires requires (const T& t, const U& u) { t - u; }
144146[[nodiscard]] constexpr auto operator -(const cartesian_tensor<T, R, C>& A, const cartesian_tensor<U, R, C>& B)
145147{
@@ -149,7 +151,7 @@ template<typename T, typename U, std::size_t R, std::size_t C>
149151 return Rm;
150152}
151153
152- template <typename T, typename U, std::size_t R, std::size_t C>
154+ MP_UNITS_EXPORT template <typename T, typename U, std::size_t R, std::size_t C>
153155 requires (!treat_as_floating_point<T> && !treat_as_floating_point<U> && requires (const T& t, const U& u) { t % u; })
154156[[nodiscard]] constexpr auto operator %(const cartesian_tensor<T, R, C>& A, const cartesian_tensor<U, R, C>& B)
155157{
@@ -159,7 +161,7 @@ template<typename T, typename U, std::size_t R, std::size_t C>
159161 return Rm;
160162}
161163
162- template <typename T, typename S, std::size_t R, std::size_t C>
164+ MP_UNITS_EXPORT template <typename T, typename S, std::size_t R, std::size_t C>
163165 requires requires (const T& t, const S& s) { t * s; }
164166[[nodiscard]] constexpr auto operator *(const cartesian_tensor<T, R, C>& tensor, const S& scalar)
165167{
@@ -169,14 +171,14 @@ template<typename T, typename S, std::size_t R, std::size_t C>
169171 return Rm;
170172}
171173
172- template <typename S, typename U, std::size_t R, std::size_t C>
174+ MP_UNITS_EXPORT template <typename S, typename U, std::size_t R, std::size_t C>
173175 requires requires (const S& s, const U& u) { s * u; }
174176[[nodiscard]] constexpr auto operator *(const S& scalar, const cartesian_tensor<U, R, C>& tensor)
175177{
176178 return tensor * scalar;
177179}
178180
179- template <typename T, typename S, std::size_t R, std::size_t C>
181+ MP_UNITS_EXPORT template <typename T, typename S, std::size_t R, std::size_t C>
180182 requires requires (const T& t, const S& s) { t / s; }
181183[[nodiscard]] constexpr auto operator /(const cartesian_tensor<T, R, C>& tensor, const S& scalar)
182184{
@@ -192,8 +194,8 @@ template<typename T, typename S, std::size_t R, std::size_t C>
192194template <typename T, std::size_t R, std::size_t C, typename Char>
193195struct MP_UNITS_STD_FMT ::formatter<mp_units::cartesian_tensor<T, R, C>, Char> :
194196 formatter<std::basic_string_view<Char>, Char> {
195- template <typename Ctx >
196- auto format (const mp_units::cartesian_tensor<T, R, C>& A, Ctx & ctx) const
197+ template <typename FormatContext >
198+ auto format (const mp_units::cartesian_tensor<T, R, C>& A, FormatContext & ctx) const
197199 {
198200 auto out = ctx.out ();
199201 for (std::size_t r = 0 ; r < R; ++r) {
@@ -207,4 +209,4 @@ struct MP_UNITS_STD_FMT::formatter<mp_units::cartesian_tensor<T, R, C>, Char> :
207209 return out;
208210 }
209211};
210- #endif
212+ #endif
0 commit comments