Skip to content

Commit

Permalink
test a simple case
Browse files Browse the repository at this point in the history
  • Loading branch information
chriselrod committed Feb 17, 2024
1 parent c228abb commit c030e96
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 12 deletions.
45 changes: 36 additions & 9 deletions include/Math/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,18 @@ static_assert(Dimension<DenseDims<3, 1>>);
static_assert(VectorDimension<StridedRange>);
static_assert(VectorDimension<DenseDims<3, 1>>);
static_assert(!MatrixDimension<DenseDims<3, 1>>);
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
template <typename T>
using DefaultAlloc = std::allocator<utils::compressed_t<T>>;
#else
template <typename T>
using DefaultAlloc = alloc::Mallocator<utils::compressed_t<T>>;
#endif

template <class T, Dimension S,
ptrdiff_t N =
containers::PreAllocStorage<utils::compressed_t<T>, S>(),
class A = alloc::Mallocator<utils::compressed_t<T>>>
class A = DefaultAlloc<T>>
struct ManagedArray;

template <std::integral T> static constexpr auto maxPow10() -> size_t {
Expand Down Expand Up @@ -969,9 +976,10 @@ struct POLY_MATH_GSL_POINTER ResizeableView : MutArray<T, S> {
this->sz = nz;
if constexpr (std::integral<S>) {
invariant(U(nz) <= capacity);
if (nz > oz) std::fill(this->data() + oz, this->data() + nz, T{});
if constexpr (!std::is_trivially_destructible_v<T>)
if constexpr (!std::is_trivially_destructible_v<T>) {
for (ptrdiff_t i = nz; i < oz; ++i) this->data()[i].~T();
for (ptrdiff_t i = oz; i < nz; ++i) new (this->data() + i) T();
} else if (nz > oz) std::fill(this->data() + oz, this->data() + nz, T{});
} else {
static_assert(std::is_trivially_destructible_v<T>,
"Resizing matrices holding non-is_trivially_destructible_v "
Expand Down Expand Up @@ -1043,11 +1051,13 @@ struct POLY_MATH_GSL_POINTER ResizeableView : MutArray<T, S> {
}
}
constexpr void resizeForOverwrite(S M) {
static_assert(
std::is_trivially_destructible_v<T>,
"resizeForOverwrite for arrays holding non-is_trivially_destructible_v "
"objects is not yet supported.");
invariant(U(M) <= U(this->sz));
if constexpr (!std::is_trivially_destructible_v<T>) {
ptrdiff_t nz = U(M), oz = U(this->sz);
for (ptrdiff_t i = nz; i < oz; ++i) this->data()[i].~T();
// we set invariant smaller
// for (ptrdiff_t i = oz; i < nz; ++i) new (this->data() + i) T();
}
this->sz = M;
}
constexpr void resizeForOverwrite(Row<> r) {
Expand Down Expand Up @@ -1185,8 +1195,16 @@ struct POLY_MATH_GSL_POINTER ReallocView : ResizeableView<T, S> {
maybeDeallocate(newPtr, newCap);
invariant(newCapacity > oz);
}
std::fill(this->data() + oz, this->data() + nz, T{});
if constexpr (!std::is_trivially_destructible_v<T>) {
for (ptrdiff_t i = nz; i < oz; ++i) this->data()[i].~T();
// new T() direct-initializes
// https://en.cppreference.com/w/cpp/language/direct_initialization
for (ptrdiff_t i = oz; i < nz; ++i) new (this->data() + i) T();
} else if (nz > oz) std::fill(this->data() + oz, this->data() + nz, T{});
} else {
static_assert(std::is_trivially_destructible_v<T>,
"Resizing matrices holding non-is_trivially_destructible_v "
"objects is not yet supported.");
static_assert(MatrixDimension<S>, "Can only resize 1 or 2d containers.");
U len = U(nz);
if (len == 0) return;
Expand Down Expand Up @@ -1265,6 +1283,13 @@ struct POLY_MATH_GSL_POINTER ReallocView : ResizeableView<T, S> {
constexpr void resizeForOverwrite(S M) {
U L = U(M);
if (L > U(this->sz)) growUndef(L);
if constexpr (!std::is_trivially_destructible_v<T>) {
ptrdiff_t nz = U(M), oz = U(this->sz);
for (ptrdiff_t i = nz; i < oz; ++i) this->data()[i].~T();
// new T default-initializes
// https://en.cppreference.com/w/cpp/language/default_initialization
for (ptrdiff_t i = oz; i < nz; ++i) new (this->data() + i) T;
}
this->sz = M;
}
constexpr void resizeForOverwrite(Row<> r) {
Expand Down Expand Up @@ -1379,6 +1404,8 @@ struct POLY_MATH_GSL_POINTER ReallocView : ResizeableView<T, S> {
// this method should only be called from the destructor
// (and the implementation taking the new ptr and capacity)
void maybeDeallocate() noexcept {
if constexpr (!std::is_trivially_destructible_v<T>)
for (ptrdiff_t i = 0; i < U(this->sz); ++i) this->data()[i].~T();
if (wasAllocated()) allocator.deallocate(this->data(), this->capacity);
}
// this method should be called whenever the buffer lives
Expand Down Expand Up @@ -1420,7 +1447,7 @@ concept AbstractSimilar =
/// stack memory.
template <class T, Dimension S, ptrdiff_t N, class A>
struct POLY_MATH_GSL_OWNER ManagedArray : ReallocView<T, S, A> {
static_assert(std::is_trivially_destructible_v<T>);
// static_assert(std::is_trivially_destructible_v<T>);
using BaseT = ReallocView<T, S, A>;
using U = containers::default_capacity_type_t<S>;
using storage_type = typename BaseT::storage_type;
Expand Down
4 changes: 2 additions & 2 deletions include/Math/LinearAlgebra.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ template <ptrdiff_t L>
Row M = B.numRow();
SquareMatrix<Rational, L> A{B};
// auto ipiv = Vector<unsigned>{.s = unsigned(M)};
auto ipiv{vector(alloc::Mallocator<unsigned>{}, ptrdiff_t(M))};
auto ipiv{vector(math::DefaultAlloc<unsigned>{}, ptrdiff_t(M))};
// Vector<unsigned> ipiv{.s = unsigned(M)};
invariant(ptrdiff_t(ipiv.size()), ptrdiff_t(M));
for (ptrdiff_t k = 0;; ++k) {
Expand Down Expand Up @@ -197,7 +197,7 @@ template <ptrdiff_t L>
template <typename S> constexpr auto factImpl(MutSquarePtrMatrix<S> A) {
using V = decltype(value(S{}));
Row M = A.numRow();
auto ipiv{vector(alloc::Mallocator<unsigned>{}, ptrdiff_t(M))};
auto ipiv{vector(math::DefaultAlloc<unsigned>{}, ptrdiff_t(M))};
invariant(ptrdiff_t(ipiv.size()), ptrdiff_t(M));
for (ptrdiff_t k = 0;; ++k) {
containers::Pair<ptrdiff_t, V> mi{-1, {}};
Expand Down
2 changes: 1 addition & 1 deletion include/Math/NormalForm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ constexpr auto orthogonalizeBang(MutDensePtrMatrix<int64_t> &A)
// we try to orthogonalize with respect to as many rows of `A` as we can
// prioritizing earlier rows.
auto [M, N] = shape(A);
SquareMatrix<int64_t> K{identity(alloc::Mallocator<int64_t>{}, unsigned(M))};
SquareMatrix<int64_t> K{identity(math::DefaultAlloc<int64_t>{}, unsigned(M))};
Vector<unsigned> included;
included.reserve(std::min(ptrdiff_t(M), ptrdiff_t(N)));
for (ptrdiff_t i = 0, j = 0; i < std::min(ptrdiff_t(M), ptrdiff_t(N)); ++j) {
Expand Down
12 changes: 12 additions & 0 deletions test/matrix_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,15 @@ TEST(TinyVectorTest, BasicAssertions) {
for (auto x : v) s += x;
EXPECT_EQ(s, 28);
}

TEST(NonTriviallyDestructible, BasicAssertions) {
Vector<int64_t> y{std::array<int64_t, 3>{204, 205, 206}};
Vector<Vector<int64_t, 0>, 0> x;
x.emplace_back(std::array<int64_t, 3>{2, 3, 4});
x.emplace_back(std::array<int64_t, 3>{4, 5, 6});
for (ptrdiff_t i = 0; i < 100; ++i)
x.emplace_back(std::array<int64_t, 3>{6 + 2 * i, 7 + 2 * i, 8 + 2 * i});
for (ptrdiff_t i = 0; i < x.size(); ++i)
for (ptrdiff_t j = 0; j < 3; ++j) EXPECT_EQ(x[i][j], 2 * (i + 1) + j);
EXPECT_EQ(x.pop_back_val(), y);
}

0 comments on commit c030e96

Please sign in to comment.