A
Alf P. Steinbach
This question was closed as off-topic on Stack Overflow.
The OP was anonymous.
http://stackoverflow.com/questions/...dynamically-determined-dimensional-array-in-c
I don't know of any such library, and I wouldn't advice using such a
class since it incurs some overhead and opens the door for bugs, but
here is a working sketch of how you can do it yourself:
Cheers & hth.,
- Alf
The OP was anonymous.
http://stackoverflow.com/questions/...dynamically-determined-dimensional-array-in-c
I am looking for a good existing library for dynamically-determined dimensional
array in c++. Blitz++ and other similars provide array with fixed dimensionality,
like the following
int m = 2, n = 3; p = 4;
blitz::Array<double, 3> a(m, n, p); // A 3D array
What I am looking for is
int d = 3;
Array<double> a(d, m, n, p); // An array of 3D
where the array's dimensionality d and size of all the dimensions (here m, n, p)
are all determined dynamically.
I don't know of any such library, and I wouldn't advice using such a
class since it incurs some overhead and opens the door for bugs, but
here is a working sketch of how you can do it yourself:
Code:
#include <assert.h> // assert
#include <vector> // std::vector
#include <initializer_list> // std::initializer_list
#include <stddef.h> // ptrdiff_t
#include <iterator> // std::begin, std::end
namespace my{
using std::vector;
using std::initializer_list;
typedef ptrdiff_t Size;
typedef Size Index;
template< class Item >
auto item( Index const i, initializer_list<Item> const& items )
-> Item const
{ return *(items.begin() + i); }
// Needs to be more elaborate for general implementation.
template< class Container >
auto size( Container const& c )
-> Size
{ return end( c ) - begin( c ); }
typedef double Item;
class Array
{
private:
vector<Size> extents_;
vector<Item> items_;
auto n_items() const
-> Size
{
Size result = 1;
for( auto const n : extents_ ) { result *= n; }
return result;
}
auto index_for( initializer_list<int> const& indices ) const
-> Index
{
assert( indices.size() == extents_.size() );
Size sub_array_size = 1;
Index result = 0;
for( Index i = 0; i < size( indices ); ++i )
{
result += item( i, indices )*sub_array_size;
sub_array_size *= extents_[i];
}
return result;
}
public:
auto n_dimensions() const
-> int
{ return extents_.size(); }
auto extent( Index const i ) const
-> Size
{ return extents_[i]; }
template< class... Int >
auto operator()( Int const... indices )
-> double&
{ return items_[ index_for({indices...}) ]; }
template< class... Int >
auto operator()( Int const... indices ) const
-> double const&
{ return items_[ index_for({indices...}) ]; }
template< class... Int >
Array( Int const... extents )
: extents_( { extents... } )
{ items_.resize( n_items() ); }
};
} // namespace my
#include <iostream>
#include <iomanip>
using namespace std;
auto main() -> int
{
my::Array a( 3, 3, 3 );
cout << a.n_dimensions() << " dimensions" << endl;
a( 1, 2, 1) = 3.14;
a( 2, 2, 1) = 3.15;
for( int z = 0; z < 3; ++z )
{
for( int y = 0; y < 3; ++y )
{
for( int x = 0; x < 3; ++x )
{
cout << setw( 5 ) << a( x, y, z );
}
cout << endl;
}
cout << endl;
}
cout << a( 1, 2, 1) << endl;
}
Cheers & hth.,
- Alf