
Boosters: I'm hoping someone here might be of help, and enlighten me with some more MPL trickery ... What I'm doing: Have a class MyArray derived from blitz::Array, and among other things, I'm trying to add the operator[] to slice through a multi-dim array ... pretty much have it, with one exception - once I get to applying [] on a 1-dimensional (linear) array, I of course expect a scalar, but therein lies the problem - the compiler also "sees" a 0-dimensional array (not good!), and that's where I run into problems... Brief snippets of code: Please ignore the return by value for the moment - I can clean that up later, not to mention the Boost PP extensions I can add. Below is a cut-down class definition, and method implementation follows. Class Declaration: ------------------ template <typename T, int Rank = 1> class MyArray : public blitz::Array<T, boost::mpl::int_<Rank>::value> { public: // ... methods }; (Partial Listing) Implementation: --------------------------------- template <typename T, int Rank> MyArray<T, Rank> :: Array(const blitz::Array<T, boost::mpl::int_<Rank>::value>& btz ) throw() : blitz::Array<T, boost::mpl::int_<Rank>::value> (const_cast<T *> (btz.data()) , btz.shape() , blitz::duplicateData ) { // Copy Ctor } template <typename T, int Rank> void MyArray<T, Rank> :: getParamList(blitz::TinyVector< boost::variant< blitz::Range , blitz::nilArraySection > , 2 >& plist ) { // Aides us in setting up the parameter list for slicing plist(boost::mpl::int_<0>::value) = blitz::Range::all(); plist(boost::mpl::int_<1>::value) = blitz::nilArraySection(); } /* 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> >::type MyArray<T, Rank> :: operator[] (const int& index) throw(); { // Slicing // this bit of indirection is useful blitz::TinyVector<boost::variant<blitz::Range, blitz::nilArraySection>, 2> plist; this->getParamList(plist); /* pseudocode: (kind of) **************** return // cast for return type static_cast< (Rank == 1 ? T : MyArray<T, Rank - 1>) > ( // cast _this_ ptr * static_cast<const blitz::Array<T, Rank> *> (this) // the blitz Array parameter list (index, //the param list *boost::get<blitz::Range *or* blitz::nilArraySection>(&plist(0 *or* 1), ... ) ) Sample usage: MyArray<float, 3> arr(btzArray); arr[10]; // gives MyArray<float, 2> out arr[10][2] // gives MyArray<float, 1> out arr[10][2][7] // expect a float to be output ********************/ return static_cast< typename boost::mpl::if_< typename boost::mpl::equal_to< boost::mpl::int_<Rank> , boost::mpl::int_<1> >::type , T , MyArray<T, boost::mpl::int_<Rank>::prior::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 Messages: --------------------------------- `boost::mpl::algo_::if_<boost::mpl::equal_to<boost::mpl::int_<Rank>, boost::mpl::int_<1> >::type, T, blitz::Array<T, typename boost::mpl::int_<Rank>::prior::value> >::type moe::Array<T, Rank>::operator[](const S&) [with S = int, T = int, int Rank = 1]': arr.cc:172: instantiated from here arr.cc:666: invalid static_cast from type `blitz::Array<int, 0>' to type `int' /usr/local/include/blitz/array/storage.h: In constructor `blitz::GeneralArrayStorage<N_rank>::GeneralArrayStorage() [with int N_rank = 0]': <snip ... more messages> /usr/local/include/blitz/array/storage.h:60: no match for call to `( blitz::TinyVector<int, 0>) (int&)' <snip ... more messages> ******************* So ... can anyone tell me if what I'm trying to do is possible ? Is there some MPL trickery to do it ? The above does work up until I apply the operator[] on a 1-d linear array. Help and ideas would be appreciated. Ah yes, using gcc 3.2.2, and Boost version 1.31 (maybe 1.32) .. downloaded in August 2004 (yes, I know that's ancient - but managment can be a real pain sometimes) P.S. tried to format this message as best I could, hope it's readable. With Thanks, -- Manfred Doudar MetOcean Engineers www.metoceanengineers.com