Boost logo

Boost :

From: Manfred Doudar (manfred.doudar_at_[hidden])
Date: 2005-11-16 06:56:51


I'm Re-posting ... sorry for the noise, but this seemingly,
earlier went against the unit lib thread ..
(don't quite know how).

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
                        , MyArray<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

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