Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Somone's SO question: "Is there an existing library for dynamically-determined dimensional array in c++?"

44 views
Skip to first unread message

Alf P. Steinbach

unread,
Dec 9, 2013, 1:25:46 AM12/9/13
to
This question was closed as off-topic on Stack Overflow.
The OP was anonymous.

http://stackoverflow.com/questions/20463164/is-there-an-existing-library-for-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;
}
[/code]


Cheers & hth.,

- Alf

Larry Evans

unread,
Dec 9, 2013, 9:47:53 AM12/9/13
to
Hi Alf,

The following code:

http://svn.boost.org/svn/boost/sandbox/variadic_templates/sandbox/array_dyn/array_dyn.hpp

has comments that appear to satisfy that need.

-regards,
Larry


0 new messages