1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
#include <iomanip>
#include <iostream>
#include <vector>
#define EXPAND0(X) X ## 1
#define EXPAND(X) EXPAND0(X)
// --- >8 snip -----------------------------------------
// A 1D to 2D view
// Missing useful stuff like iterators, etc.
template <typename Container, std::size_t Rows, std::size_t Columns>
struct view_1D_to_2D_type
{
Container& container;
view_1D_to_2D_type( Container& container ): container(container) { }
typedef decltype(container[0]) value_type;
std::size_t index( std::size_t row, std::size_t column ) const
{
return row * Columns + column;
}
std::size_t rows() const { return Rows; }
std::size_t columns() const { return Columns; }
value_type& operator () ( std::size_t row, std::size_t column ) const { return container [ index( row, column ) ]; }
value_type& at ( std::size_t row, std::size_t column ) const { return container.at( index( row, column ) ); }
};
template <std::size_t Rows, std::size_t Columns, typename Container>
view_1D_to_2D_type <Container, Rows, Columns>
view_1D_to_2D( Container& container )
{
return view_1D_to_2D_type <Container, Rows, Columns> ( container );
}
// --- snip 8< -----------------------------------------
// Here you can play with the const-ness of the source structures and
// the reference type acceptable by the function.
#define CONST //const
template <typename Container>
#if 0
void test( Container& container )
#elif 0
void test( const Container& container )
#elif 1
void test( Container&& container )
#else
void test( const Container&& container )
#endif
{
for (auto r = 0U; r < container.rows(); r++)
{
for (auto c = 0U; c < container.columns(); c++)
std::cout << " " << std::setw(2) << std::left << container( r, c );
std::cout << "\n";
}
std::cout << "\n";
}
int main()
{
{ std::cout << "test an array\n";
CONST int xs[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
test( view_1D_to_2D <3, 4> ( xs ) );
test( view_1D_to_2D <2, 6> ( xs ) );
#if EXPAND(CONST)
std::cout << "swapping (1,1) and (2,1):\n";
auto vs = view_1D_to_2D <4, 3> ( xs );
std::swap( vs( 1, 1 ), vs( 2, 1 ) );
test( vs );
test( view_1D_to_2D <3, 4> ( xs ) );
test( view_1D_to_2D <2, 6> ( xs ) );
#endif
}
{ std::cout << "test a vector\n";
CONST std::vector <int> xs { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
test( view_1D_to_2D <3, 4> ( xs ) );
test( view_1D_to_2D <2, 6> ( xs ) );
#if EXPAND(CONST)
std::cout << "swapping (1,1) and (2,1):\n";
auto vs = view_1D_to_2D <4, 3> ( xs );
std::swap( vs( 1, 1 ), vs( 2, 1 ) );
test( vs );
test( view_1D_to_2D <3, 4> ( xs ) );
test( view_1D_to_2D <2, 6> ( xs ) );
#endif
}
}
|