#include #include #include #include #include using namespace origin; using namespace std; typedef std::size_t size_type; template void test_square_dynarray() { { square_dynarray a(3); assert(a.empty() == false); assert(a.order() == 3); assert(a.size() == 3 * 3); assert(*(a.data()) == a[0]); } { square_dynarray b(4, T()); assert(b.order() == 4); assert(b.size() == 4 * 4); assert(*(b.data()) == T()); } } void test_triangular_array() { typedef triangular_dynarray tri_array; unsigned int array_order = 4; tri_array a(array_order); assert(a.empty() == false); assert(a.order() == array_order); assert(a.size() == array_order * (array_order + 1) / 2); assert(*(a.data()) == a[0]); // Assert row iterators { tri_array::row_iterator row_i = a.begin_row(0), finish = a.end_row(0); unsigned int row_count = 0; for(auto i = 0u; i < a.size(); ++i) { assert(a[i] == *row_i); ++row_i; if(row_i == finish) { ++row_count; row_i = a.begin_row(row_count); finish = a.end_row(row_count); } } } // Assert column iterators // FIXME This is a mess. Redo. { tri_array::column_iterator col_iter = a.begin_column(0); col_iter; /*for(auto column_count = 0u; column_count < a.order(); ++ column_count) { col_iter = a.begin_column(column_count); for(auto row = column_count; ; ++row) { assert(a(row, column_count) == *col_iter); ++col_iter; if(col_iter == a.end_column(column_count)) break; } }*/ } } /*void visual_test_symmetric_square_dynarray() { cout << "Printing the array of data:\n"; square_dynarray a(9); for(unsigned int i = 0; i < a.order() * (a.order() + 1) / 2; ++i) { *(a.data_ + i) = i; cout << std::setw(3) << i; } cout << '\n'; cout << "Printing symmetric square array using (i,j) accessor:\n"; for(unsigned int i = 0; i < a.order(); ++i) { for(unsigned int j = 0; j < a.order(); ++j) { cout << std::setw(3) << a(i,j); } cout << '\n'; } cout << "Printing symmetric square array using single dimension index:\n"; for(unsigned int i = 0; i < a.size(); ++i) { cout << std::setw(3) << a[i]; if(((i + 1) % a.order()) == 0) cout << "\n"; } cout << "Printing a row using the remove_edges(v) algorithm:\n"; // FIXME Doesn't work! Use a matrix of order 10 or greater to see. // The error comes after incrementing past the threshold... kinda. const size_type v = 3; const size_type start = v * (v + 1) / 2; for(size_type i = start; i <= v + start; ++i) { unsigned int& edge = *(a.data_ + i); cout << std::setw(3) << edge; } // Note: We can cut a few instructions by taking i from the former for loop for(size_type i = v + v + start + 1, j = v + 1; i < a.order() * (a.order() + 1) / 2; i += j, ++i) { unsigned int& edge = *(a.data_ + i); cout << std::setw(3) << edge; } cout << '\n'; } void iterator_test() { // this doesn't work??? square_dynarray a(4,0); for(unsigned int i = 0; i < (a.order() * (a.order() + 1) / 2); ++i) { *(a.data_ + i) = i; } for(unsigned int i = 0; i < a.order(); ++i) { cout << "row " << a.row_begin(i).row_ << ": "; //cout << std::setw(3) << *a.row_begin(i); for(auto row_i = a.row_begin(i); row_i != a.row_end(i); ++row_i) { cout << std::setw(3) << *row_i; } cout << '\n'; } }*/ /** Hacky row iterator. Consider later. template struct row_iter { // typedef std::uint8_t size_type; typedef std::size_t size_type; typedef T* pointer; union step_type { step_type(size_type r) { fields.row = r; fields.step = fields.dir = 1; } struct field_type { size_type row : 16; size_type step : 15; size_type dir : 1; } fields; size_type value; }; // Fun with bits. If the high order bit is on, then we're doing row iteration, // and if it's off, then we're doing column iteration. static size_type const bits = sizeof(size_type) * 8; static size_type const high_bit = 1 << (bits - 1); static size_type const low_bits = size_type(-1u) >> bits * 4; row_iter(pointer p, size_type r) : ptr(p), step(r) { } row_iter& operator++() { // Actually update the pointer first... ptr += step; // Prepare to go to // size_type mask = step.fields.dir; // mask = (mask - mask - mask); // size_type next = step.fields.step + (step.fields.step & ~mask); if(step.fields.dir) { step.fields.step += 1; if(step.fields.step == step.fields.row) { step.fields.step = step.fields.row + 1; } } return *this; } // size_type get_step() { // return step & low_bits; // } pointer ptr; step_type step; }; void hacky_row_iterator_test() { size_t const N = 4; size_t const Order = N * (N + 1) / 2; int data[Order]; row_iter i(data, 0); cout << sizeof(i) << "\n"; ++i; ++i; ++i; ++i; } */ int main() { test_square_dynarray(); test_triangular_array(); //visual_test_symmetric_square_dynarray(); //iterator_test(); return 0; }