Boost logo

Boost :

Subject: Re: [boost] [MultiArray] shape() return type
From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2009-06-26 11:21:04

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?

Version: GnuPG v1.4.9 (GNU/Linux)


Content-Type: text/x-c++hdr; charset="iso 8859-15"; name="rac_adapter.hpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;

// 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

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().


#include <boost/assert.hpp>
#include <iterator>

namespace EPG
        // random access collection adapter
        template<typename T, unsigned length>
        class rac_adapter
                // 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];
                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



Boost list run by bdawes at, gregod at, cpdaniel at, john at