compile-time mapping: a[1] --> a1 ?

I would like to do a compile-time mapping of an array accessor to a list of scalars as in the following class: class MyArray1 { public: double& operator[](int n) { ??? } private: double a0, a1, a2, a3 ; } ; int main() { MyArray1 x ; x[1] = 2. ; } I've left off all the extraneous stuff like constructors. I don't know how to write the MyArray1::operator[] so that it will evaluate to one of the data members at compile time; an if-test would correctly evaluate but might not be optimized away and run slowly. Is there some way to do the compile-time evaluation using the MPL? I looked thru the tutorial but did not find anything that looked like it would work. One possibility that I considered was the C preprocessor concatenation operator ##, #define PICKMEMBER(n) a##n double& operator[](int n) { PICKMEMBER(n) ; } Unfortunately, this will not work for expressions like x[i+1]. It probably has additional problems other than being quite distasteful. Obviously, this would all be easy if I just implemented the member data with an array, class MyArray2 { public: double& operator[](int n) { return data[n] ; } private: double data[4] ; } ; In fact, I did do so and everything works fine. The reason that I am trying to implement the list of scalars method is to see if there are any CPU timing differences for my application, which amounts to matrix-vector operations for small, dense vectors whose sizes are known at compile time. I have tried uBlas but was disappointed with the timing results (and yes, I did compile with -DNDEBUG). I've also looked at other packages such as tvmet (it did worse). I finally tried rolling my own vector and matrix classes with lazy evaluation of binary operators via Eckel's "Thinking in C++, Vol 2"; I also studied source for uBlas and tvmet. So far, I am able to beat uBlas on my choice of compilers/platforms, but I'm still not getting the consistent performance that I was hoping for. Why am I so interested in performance? Two reasons. First, if I can get consistently good performance (i.e. performance that is close to raw C or Fortran) for fairly straightforward operations, then I can be more confident that as I increase abstraction, performance will not deteriorate substantially. Second, I am evaluating C++ for applications that have been traditionally written in Fortran -- in my case, CFD codes for airflow simulation. Issues of modularity, extensibility, maintenance, and the fact that very few students are learning Fortran anymore may not be enough to convince my peers. I think I will also need to show that we will not experience a substantial performance hit with C++. Thanks in advance for any help. Steven Allmaras Boeing Commercial Airplanes

I would like to do a compile-time mapping of an array accessor to a list of scalars as in the following class:
class MyArray1 { public: double& operator[](int n) { ??? }
private: double a0, a1, a2, a3 ; } ;
Well, using an union would typically works correctly. And if you are using a compiler with some kind of property, this might be another solution. FInally, you could have functions that access the array. A final solution, would be to derive from a struct and do a reinterpret_cast. --- The first solution might look like : union { struct { double a0, a1, a2, a3 ; } scalar; double array[4]; }; but then you would need to qualify names. --- For the second solution, you will be able to have the desired syntax for the caller... but properties are not standard C++ and are not protable. --- For the third solution, it will be something like : class MyArray1 { public: double &a1() { return array[1]; } double const &a1() const { return array[1]; } private: double array[4]; }; --- The forth solution is something like : struct MyArray1Struct { double a0, a1, a2, a3; }; class MyArray1 : private MyArray1Struct { public: double& operator[](int n) { return reinterpret_cast<double(&)[4]>(static_cast<>(*this)); } double const & operator[](int n) const { return reinterpret_cast<double const(&)[4]>(static_cast<>(*this)); } };

"Steven Allmaras" <steven.r.allmaras@boeing.com> wrote
I would like to do a compile-time mapping of an array accessor to a list of scalars as in the following class:
class MyArray1 { public: double& operator[](int n) { ??? }
private: double a0, a1, a2, a3 ; } ;
int main() { MyArray1 x ;
x[1] = 2. ; }
How about something like this: #include <boost/preprocessor/repeat.hpp> #include <boost/preprocessor/enum_params.hpp> #include <boost/mpl/int.hpp> #include <iostream> using namespace std; #define DEFINE_FUNC(z, n, _)\ double& operator[](boost::mpl::int_<n>)\ {\ return a ## n;\ } #define DEFINE_ARRAY(Name, n)\ class Name\ {\ public:\ BOOST_PP_REPEAT(n, DEFINE_FUNC, ~)\ private:\ double BOOST_PP_ENUM_PARAMS(4, a);\ }; DEFINE_ARRAY(MyArray1, 4) int main() { MyArray1 x; x[boost::mpl::int_<0>()] = 2.; x[boost::mpl::int_<3>()] = 5.; // x[boost::mpl::int_<4>()] = 7.; // compile error cout << x[boost::mpl::int_<0>()] << endl; cout << x[boost::mpl::int_<3>()] << endl; } Regards, Arkadiy
participants (3)
-
Arkadiy Vertleyb
-
Philippe Mori
-
Steven Allmaras