Boost logo

Boost :

From: Rodrigo Philander (rodrigo.philander_at_[hidden])
Date: 2005-11-16 13:06:26


At this point I am not familiar with MPL, so my apologies if my
suggestion is naive...

You use template recursion to support an arbitrary number of
dimensions at compile-time, which is fine. The natural means of
handling the base case of N=1 is (as I see it) a partial
specialization of the MyArray class. Something like this:

#include <vector>

template < class T, int N >
class MyArray
{
public:
        MyArray<T, N-1> operator[]( unsigned int n ) { return m_arr[ n ]; }
private:
        std::vector< MyArray< T, N - 1 > > m_arr;
};

template < class T >
class MyArray<T,1>
{
public:
        T operator[]( unsigned int n ) { return m_arr[ n ]; }
private:
        std::vector< T > m_arr;
};

void foo()
{
        MyArray< int, 2 > twodim;
                // populate twodim with values...
        int val = twodim[ 2 ][ 1 ];
}

Hope this helps...

- Rod

On 11/16/05, Manfred Doudar <manfred.doudar_at_[hidden]> wrote:
> Martin Bonner wrote:
>
> >>Manfred Doudar wrote:
> >>
> >>
> >>
> >>>/* Now, how do I get T out when Rank == 1, ... compiler complains
> >>> about seeing a MyArray/blitz::Array of <T, Rank = 0>
> >>> (, which is not defined for blitz Arrays)
> >>>*/
> >>>template <typename T, int Rank>
> >>>typename boost::mpl::if_
> >>> < typename boost::mpl::equal_to
> >>> < boost::mpl::int_<Rank>
> >>> , boost::mpl::int_<1>
> >>> >::type
> >>> , T
> >>> , blitz::Array<T,
> >>>
> >>>boost::mpl::int_<Rank>::prior::value>
> >>>
> >>>
> >>>
> >>>
> >> ^
> >> Oops typo, should be:
> >> MyArray<T,
> >>
> >>boost::mpl::int_<Rank>::prior::value>
> >>
> >>... but nonetheless, the problem remains ...
> >>
> >>
> >>
> >>> >::type
> >>>MyArray<T, Rank> :: operator[] (const int& index) throw(); {
> >>> // Slicing
> >>>
> >>>
> >
> >How about a helper traits class?
> >
> >template <typename T, int Rank>
> >struct SliceType
> >{
> > typedef typename MyArray<T, Rank-1> type;
> >};
> >
> >template <typename T>
> >struct SliceType<T,1>
> >{
> > typedef T type;
> >};
> >
> >template <typename T, int Rank>
> >typename SliceType<T,Rank>::type
> > MyArray<T,Rank> :: operator[] (const int& index) throw();
> >
> >
> >
>
> Now I'm sure that ought to have worked (even after modifying
> as you've suggested) ... but the problem _still persists_ ,
> not per say on the definition of return type, but seemingly
> inside the _template body_, where the *static_cast* is done
> to map the final result accordingly ... please see below:
>
>
> Partial Code Listing:
> --------------------
>
> template <typename T, int Rank>
> typename SliceType<T, boost::mpl::int_<Rank>::value>::type
> MyArray<T, Rank> :: operator[] (const int& index) throw()
> {
> // Slicing
>
> blitz::TinyVector<boost::variant<blitz::Range,
> blitz::nilArraySection>, 2> plist;
> this->getParamList(plist);
>
>
> return
>
> // ***********************************************
> // ** Complier complains about this cast seeing
> // ** MyArray/blitz::Array <T, 0>
> // ** when Rank == 1
> // ** ... see partial compiler error msg below
> // ***********************************************
> static_cast< typename SliceType<T, // ** [ Line 697 ] **
> boost::mpl::int_<Rank>::value>::type
> > (
>
> ((* static_cast<const blitz::Array<T,
> boost::mpl::int_<Rank>::value> *> (this))
>
> /* the parameter list */
> (index,
> *boost::get<
> typename boost::mpl::if_<
> typename boost::mpl::less<
> boost::mpl::int_<1>
> , boost::mpl::int_<Rank>
> >::type
> , blitz::Range
> , blitz::nilArraySection
> >::type
> >
>
> (&plist(boost::mpl::if_<
> typename boost::mpl::less<
> boost::mpl::int_<1>
> , boost::mpl::int_<Rank>
> >::type
> , boost::mpl::int_<0>
> , boost::mpl::int_<1>
> >::type::value
> )
> )
>
> /*
> , ... we can extend the parameter list with Boost.PP
> */
> );
>
> }
>
>
> (Partial) Compiler Error Message:
> ---------------------------------
>
> In member function `SliceType<T,
> boost::mpl::int_<Rank>::value>::type MyArray<T, Rank>::operator[](const
> S&) [with S = int, T = float, int Rank = 1]':
> arr.cc:197: instantiated from here
> arr.cc:697: invalid static_cast from type `blitz::Array<float, 0>' to type `
> float'
>
> <snip .. more messages>
>
> /usr/local/include/blitz/array/storage.h:60: no match for call to `(
> blitz::TinyVector<int, 0>) (int&)'
>
> <snip .. more messages>
>
>
>
> Somewhere in main(..)
> ---------------------
>
> blitz::Array<float, 2> b2(2, 2); // 2D array (2 x 2)
>
> b2 = 1.1, -2.2,
> -9.9, 8.8;
>
> MyArray<float, 2> a2(b2);
>
> std::cout << a2[1] ; // this works
> std::cout << a2[1][1] ; // ** [Line 197] ** the problem is here
>
>
> Any and All help is Appreciated,
> I know it's got to be something simple, I just can't see it yet.
>
>
>
> With Thanks,
> --
> Manfred Doudar
> MetOcean Engineers
> www.metoceanengineers.com
>
>
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>

--
Rod Philander
rodrigo.philander_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk