|
Boost : |
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-04-13 14:26:17
On 4/13/07, Neal Becker <ndbecker2_at_[hidden]> wrote:
> I just posted something on ublas, but I think it may be of more general
> interest.
>
> I have been using boost::range heavily, and find it useful for generic
> interfaces. I think it is also useful to have a multi-dimensional
> extension to range. In particular, a 2-d extension would help in creating
> algorithms that can accept a variety of 2-d structures.
>
> For example, range has size, begin, end.
>
> range2d would have size1, size2, begin1, begin2.
I think this is an interesting idea, and I've been looking into a
little while. You could make this multi-dimensional not just 2d. How
about something like ..
// get the number of lines in the plane at index 0 of a 3d space
plane_type& space_2d = span(space_3d, 0);
range_size<
plane_type
>::type n_2d = size(space_2d);
I'm not sure if span is the right name for it, and this has got to be
encroaching on UBLAS' domain. But it's doable for ranges. I just tried
the following, which I believe will work for arbitrary dimensions.
#include <boost/preprocessor.hpp>
#include <boost/range.hpp>
#include <boost/utility.hpp>
using namespace boost;
#define RANGE_SPAN_RETURN_TYPE_OPEN(z, n, _) \
typename range_value< \
/**/
#define RANGE_SPAN_RETURN_TYPE_CLOSE(z, n, _) \
>::type \
/**/
#define RANGE_SPAN_GET_OPEN(z, n, _) \
*next(begin( \
/**/
#define RANGE_SPAN_GET_CLOSE(z, n, _) \
), BOOST_PP_CAT(i, n)) \
/**/
// RANGE_SPAN expands to something like ...
// template<typename Range>
// typename range_value<
// typename range_value< Range >::type
// >::type &
// span(Range& range , const int i0 , const int i1)
// {
// return *next(begin( *next(begin( range ), i0) ), i1) ;
// }
#define RANGE_SPAN(z, n, _) \
template<typename Range> \
BOOST_PP_REPEAT(n, RANGE_SPAN_RETURN_TYPE_OPEN, _) \
Range \
BOOST_PP_REPEAT(n, RANGE_SPAN_RETURN_TYPE_CLOSE, _) \
& \
span(Range& range BOOST_PP_ENUM_TRAILING_PARAMS(n, const int i)) \
{ \
return \
BOOST_PP_REPEAT(n, RANGE_SPAN_GET_OPEN, _) \
range \
BOOST_PP_REPEAT(n, RANGE_SPAN_GET_CLOSE, _) \
; \
} \
/**/
// Overloads could be generated for larger dimensions than 3.
BOOST_PP_REPEAT(3, RANGE_SPAN, _)
int main()
{
typedef int volume_type[1][1][1];
typedef int plane_type[1][1];
typedef int line_type[1];
volume_type space_3d;
plane_type& space_2d = span(space_3d, 0);
range_size<
plane_type
>::type n_2d = size(space_2d);
line_type& space_1d = span(space_3d, 0, 0);
range_size<
line_type
>::type n_1d = size(space_1d);
}
Daniel
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk