38template <
typename A,
typename... ARGS>
50template <
typename T,
size_t D0 = 1,
size_t... DIMS>
54 constexpr static size_t num_dims = 1 +
sizeof...(DIMS);
72 (
sizeof...(U) == D0) && std::conjunction_v<std::is_convertible<value_type, U>...>,
98template <
typename T,
size_t D0,
size_t... DIMS>
155#define MOCHI_DETAILS_UNROLL_D0(BODY) \
156 if constexpr (D0 <= 4) { \
157 if constexpr (D0 > 0) { \
158 constexpr size_t i = 0; \
161 if constexpr (D0 > 1) { \
162 constexpr size_t i = 1; \
165 if constexpr (D0 > 2) { \
166 constexpr size_t i = 2; \
169 if constexpr (D0 > 3) { \
170 constexpr size_t i = 3; \
174 for (size_t i = 0; i < D0; ++i) { \
183template <
typename T,
size_t D0,
size_t... DIMS>
185 NdArray<T, D0, DIMS...> result{};
190template <
typename T,
size_t D0,
size_t... DIMS>
194 bool isEqual = (lhs[0] == rhs[0]);
195 if constexpr (D0 > 1) {
196 isEqual &= (lhs[1] == rhs[1]);
198 if constexpr (D0 > 2) {
199 isEqual &= (lhs[2] == rhs[2]);
201 if constexpr (D0 > 3) {
202 isEqual &= (lhs[3] == rhs[3]);
204 if constexpr (D0 > 4) {
205 for (
size_t i = 4; i < D0; ++i) {
206 isEqual &= (lhs[i] == rhs[i]);
212template <
typename T,
size_t D0,
size_t... DIMS>
219template <
typename T,
size_t D0,
size_t... DIMS>
226template <
typename T,
size_t D0,
size_t... DIMS>
230 return !(lhs == rhs);
237#define MOCHI_DETAILS_NDARRAY_MEMBERWISE_OP(OP_EQ, OP) \
239 template <typename T, size_t D0, size_t... DIMS> \
240 MOCHI_FORCE_INLINE constexpr NdArray<T, D0, DIMS...>& operator OP_EQ( \
241 NdArray<T, D0, DIMS...>& lhs, NdArray<T, D0, DIMS...> const& rhs) { \
242 MOCHI_DETAILS_UNROLL_D0(lhs[i] OP_EQ rhs[i]); \
246 template <typename T, size_t D0, size_t... DIMS> \
247 MOCHI_FORCE_INLINE constexpr NdArray<T, D0, DIMS...>& operator OP_EQ( \
248 NdArray<T, D0, DIMS...>& lhs, T rhs) { \
249 MOCHI_DETAILS_UNROLL_D0(lhs[i] OP_EQ rhs); \
253 template <typename T, size_t D0, size_t... DIMS, typename AnyRHS> \
254 MOCHI_FORCE_INLINE constexpr NdArray<T, D0, DIMS...>& operator OP_EQ( \
255 NdArray<T, D0, DIMS...>& lhs, AnyRHS const& rhs) { \
256 MOCHI_DETAILS_UNROLL_D0(lhs[i] OP_EQ rhs); \
260 template <typename T, size_t D0, size_t... DIMS> \
261 MOCHI_FORCE_INLINE constexpr NdArray<T, D0, DIMS...> operator OP( \
262 NdArray<T, D0, DIMS...> const& lhs, NdArray<T, D0, DIMS...> const& rhs) { \
263 NdArray<T, D0, DIMS...> result{}; \
264 MOCHI_DETAILS_UNROLL_D0(result[i] = lhs[i] OP rhs[i]); \
268 template <typename T, size_t D0, size_t... DIMS> \
269 MOCHI_FORCE_INLINE constexpr NdArray<T, D0, DIMS...> operator OP( \
270 NdArray<T, D0, DIMS...> const& lhs, T rhs) { \
271 NdArray<T, D0, DIMS...> result{}; \
272 MOCHI_DETAILS_UNROLL_D0(result[i] = lhs[i] OP rhs); \
276 template <typename T, size_t D0, size_t... DIMS> \
277 MOCHI_FORCE_INLINE constexpr NdArray<T, D0, DIMS...> operator OP( \
278 T lhs, NdArray<T, D0, DIMS...> const& rhs) { \
279 NdArray<T, D0, DIMS...> result{}; \
280 MOCHI_DETAILS_UNROLL_D0(result[i] = lhs OP rhs[i]); \
289#undef MOCHI_DETAILS_NDARRAY_MEMBERWISE_OP
290#undef MOCHI_DETAILS_UNROLL_D0
295 return std::hash<uint64_t>()(
static_cast<uint64_t
>(x[0]) | (
static_cast<uint64_t
>(x[1]) << 32));
300 return (a[0] < b[0]) || (a[0] == b[0] && a[1] < b[1]);
305 Int3 xSorted = xUnsorted;
306 std::sort(xSorted.
begin(), xSorted.
end());
307 return Int2Hash{}({xSorted[0], xSorted[1]}) ^ std::hash<uint64_t>()(xSorted[2]);
312 Int3 aSorted = aUnsorted;
313 std::sort(aSorted.
begin(), aSorted.
end());
314 Int3 bSorted = bUnsorted;
315 std::sort(bSorted.
begin(), bSorted.
end());
316 return aSorted == bSorted;
324#if MOCHI_USE_EXTERN_TEMPLATE
325extern template class NdArray<int, 2>;
326extern template class NdArray<int, 3>;
327extern template class NdArray<int, 4>;
328extern template class NdArray<real, 2>;
329extern template class NdArray<real, 3>;
330extern template class NdArray<real, 4>;
331extern template class NdArray<real, 2, 2>;
332extern template class NdArray<real, 2, 3>;
333extern template class NdArray<real, 3, 2>;
334extern template class NdArray<real, 3, 3>;
335extern template class NdArray<real, 4, 3>;
340template <
class T,
size_t D0,
size_t... DIMS>
341struct ScalarTypeDef<NdArray<T, D0, DIMS...>, void> {
342 using type = ScalarType<T>;
354#if MOCHI_USE_REFLECTION
355template <
typename T,
size_t D0,
size_t... DIMS>
356struct SReflectTypeTraits<
superdex::NdArray<T, D0, DIMS...>> {
357 static constexpr SReflect::CoreType coreType = SReflect::CoreType::CT_array;
358 static SReflect::ArrayTypeInfo
const& GetTypeInfo() {
359 static auto const* s_typeInfo = []() {
360 using MyType = superdex::NdArray<T, D0, DIMS...>;
361 using InnerType =
typename MyType::value_type;
364 for (
size_t i = 0, offset = 0; i < MyType::num_dims; ++i) {
365 offset += snprintf(dimsStr + offset,
sizeof(dimsStr) - offset,
",%zu", MyType::dims[i]);
367 char const* tName = SReflect::GetTypeInfo<T>()._nameWithNamespace;
368 char const* myName = SReflect::detail::MakeTypeName(
"superdex::NdArray<", tName, dimsStr,
">");
369 static constexpr bool kFormatAsTemplate =
false;
370 return SReflect::MakeFixedArrayTypeInfo<MyType, InnerType, D0>(myName, kFormatAsTemplate);
constexpr value_type * data()
constexpr auto begin() const
constexpr NdArray()=default
constexpr value_type const * data() const
static constexpr size_t num_dims
typename std::conditional_t< num_dims==1, T, NdArray< T, DIMS... > > value_type
static constexpr size_t dims[num_dims]
constexpr value_type & operator[](size_t i)
constexpr value_type const & operator[](size_t i) const
static constexpr int size()
constexpr NdArray(U const &... p)
constexpr auto end() const
static constexpr size_t flattened_size
#define MOCHI_ASSERT_VERBOSE(condition_without_side_effects,...)
constexpr bool operator==(NdArray< T, D0, DIMS... > const &lhs, NdArray< T, D0, DIMS... > const &rhs)
NdArray< real, 2, 3 > Matrix2x3r
NdArray< float, 3, 2 > Matrix3x2f
NdArray< float, 4, 4 > Matrix4x4f
NdArray< real, 3, 2 > Matrix3x2r
NdArray< float, 4 > Float4
NdArray< real, 4, 3 > Matrix4x3r
NdArray< float, 3, 3, 3 > Tensor3x3x3f
NdArray< float, 4, 3 > Matrix4x3f
NdArray< real, 3, 3, 3, 3 > Tensor3x3x3x3r
constexpr A MultiplyConstexpr(A a)
NdArray< real, 2, 2 > Matrix2x2r
NdArray< real, 4, 4 > Matrix4x4r
NdArray< float, 2, 3 > Matrix2x3f
NdArray< float, 2, 2 > Matrix2x2f
NdArray< double, 2 > Double2
NdArray< float, 3, 3 > Matrix3x3f
NdArray< double, 3 > Double3
NdArray< double, 4 > Double4
NdArray< real, 3, 3, 3 > Tensor3x3x3r
NdArray< real, 3, 3 > Matrix3x3r
constexpr bool operator!=(NdArray< T, D0, DIMS... > const &lhs, NdArray< T, D0, DIMS... > const &rhs)
constexpr NdArray< T, D0, DIMS... > operator-(NdArray< T, D0, DIMS... > const &a)
static constexpr bool kIsNdArray
NdArray< float, 3 > Float3
NdArray< float, 3, 3, 3, 3 > Tensor3x3x3x3f
NdArray< float, 2 > Float2
#define MOCHI_DETAILS_NDARRAY_MEMBERWISE_OP(OP_EQ, OP)
#define MOCHI_DETAILS_UNROLL_D0(BODY)
size_t operator()(Int2 const &x) const
bool operator()(Int2 const &a, Int2 const &b) const
bool operator()(Int3 const &aUnsorted, Int3 const &bUnsorted) const
size_t operator()(Int3 const &xUnsorted) const