|
Boost : |
Subject: Re: [boost] [MultiArray] shape() return type
From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2009-06-26 11:21:04
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Thursday 25 June 2009, Frank Mori Hess wrote:
> Has there ever been any thought to making multi_array::shape() return
> something that models the Collection concept (RandomAccessCollection in
> particular I suppose) rather than a raw pointer? This would allow the
> return value from shape() to be passed directly to multi_array::reshape()
> or multi_array::resize(), for added convenience. It would also allow a
> debug assertion to be added to make sure you don't try to access beyond the
> end of the array returned by shape().
Attached is some code to lay out what I have in mind for a
RandomAccessCollection-returning shape() for multi_array. It includes an
adapter which allows a C array to be accessed as a RandomAccessCollection,
plus some free functions which I use to modify the return value from
multi_array::shape() to be what I wish shape() returned in the first place.
For backwards compatibility, maybe a RandomAccessCollection-returning shape()
could be added to multi_array with a different name and shape() deprecated?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAkpE52MACgkQ5vihyNWuA4XElQCfYlyZFGrD+XBvwoWxj6w4Rgqo
a8EAoLGKQP9oOo2SS4vaushdJ3cOEZom
=z0Gn
-----END PGP SIGNATURE-----
--Boundary-00=_jdORK4ez2Tpxc2U
Content-Type: text/x-c++hdr; charset="iso 8859-15"; name="rac_adapter.hpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="rac_adapter.hpp"
// Copyright (c) 2009 Frank Mori Hess
// Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
/*
Adapter for accessing a C array as a RandomAccessCollection. One use
is for adapting the pointer returned by boost::multi_array::shape() to the input
of boost::multi_array::resize() or boost::multi_array::reshape().
*/
#ifndef EPG_RAC_ADAPTER_HPP
#define EPG_RAC_ADAPTER_HPP
#include <boost/assert.hpp>
#include <iterator>
namespace EPG
{
// random access collection adapter
template<typename T, unsigned length>
class rac_adapter
{
public:
// Collection requirements
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
rac_adapter(T *p): p_(p)
{}
iterator begin() {return p_;}
const_iterator begin() const {return p_;}
iterator end() {return p_ + length;}
const_iterator end() const {return p_ + length;}
size_t size() const {return length;}
bool empty() const {return length == 0;}
void swap(rac_adapter &other)
{
using std::swap;
swap(p_, other.p_);
}
// ForwardCollection requirements
reference front() {return *p_;}
const_reference front() const {return *p_;}
// ReversibleCollection requirements
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
iterator rbegin() {return reverse_iterator(begin());}
const_iterator rbegin() const {return reverse_iterator(begin());}
iterator rend() {return reverse_iterator(end());}
const_iterator rend() const {return reverse_iterator(end());}
// RandomAccessCollection requirements
T& operator[](size_type n)
{
BOOST_ASSERT(n < length);
return p_[n];
}
const T& operator[](size_type n) const
{
BOOST_ASSERT(n < length);
return p_[n];
}
private:
T *p_;
};
template<typename T, unsigned length>
void swap(rac_adapter<T, length> &a, rac_adapter<T, length> &b)
{
return a.swap(b);
}
template<typename T, unsigned n>
rac_adapter<const typename boost::const_multi_array_ref<T, n>::size_type, n>
shape(const boost::const_multi_array_ref<T, n> &ma)
{
return rac_adapter<const typename boost::const_multi_array_ref<T, n>::size_type, n>(ma.shape());
}
template<typename T, unsigned n>
rac_adapter<const typename boost::multi_array_ref<T, n>::size_type, n>
shape(const boost::multi_array_ref<T, n> &ma)
{
return rac_adapter<const typename boost::multi_array_ref<T, n>::size_type, n>(ma.shape());
}
template<typename T, unsigned n, typename Allocator>
rac_adapter<const typename boost::multi_array<T, n, Allocator>::size_type, n>
shape(const boost::multi_array<T, n, Allocator> &ma)
{
return rac_adapter<const typename boost::multi_array<T, n, Allocator>::size_type, n>(ma.shape());
}
} // namespace EPG
#endif // EPG_RAC_ADAPTER_HPP
--Boundary-00=_jdORK4ez2Tpxc2U--
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk