After one-day hard work, I finished a Random Access Iterator in C++ and made ”sort” work well with it
class DifferentStepsException {};
#include <iterator>
template < class T>
struct StepIter :
public iterator<std::random_access_iterator_tag, T, int> {
private:
T * p;
int step;
public:
explicit StepIter(T * Ip=NULL, int Istep=0): p(Ip), step(Istep) {};
StepIter<T>& operator= (T *Ip) {p = Ip; return *this;}
StepIter<T> operator+ (int n) {
StepIter<T> tmp=*this; tmp.p += n*step; return tmp;}
StepIter<T>& operator+= (int n) {p += n*step; return *this;}
StepIter<T> operator- (int n) {
StepIter<T> tmp=*this; tmp.p -= n*step; return tmp;}
StepIter<T>& operator-= (int n) {p -= n*step; return *this;}
int operator- (const StepIter<T> & rhs ) {
if(step==rhs.step) return (p-rhs.p)/step;
else throw DifferentStepsException();
}
T& operator[] (int n) {return p[n*step];}
T& operator* () {return *p;}
StepIter<T>& operator--() {p -= step; return *this; }
StepIter<T>& operator++() {p += step; return *this; }
StepIter<T> operator++(int) {
StepIter<T> tmp = *this; ++(*this); return tmp; }
StepIter<T> operator--(int) {
StepIter<T> tmp = *this; --(*this); return tmp; }
bool operator< (const StepIter<T> & rhs) const { return (p-rhs.p)/step < 0;}
bool operator > (const StepIter<T> & rhs) const { return (rhs< *this);}
bool operator <= (const StepIter<T> & rhs) const { return !(rhs < *this);}
bool operator >= (const StepIter<T> & rhs) const { return rhs <= *this;}
bool operator== (const StepIter<T> & rhs) const {
return p == rhs.p && step==rhs.step;}
bool operator != (const StepIter<T> & rhs) const { return !(*this == rhs); }
};
Then you can use it as following (Since it’s a part of a long source code, just paste the relevant part. All code can see in google code
)
double Data[12] = {2, 3, 4, 5, 1,
6, 9, 11, 8, 7,
12, 10};
StepIter<double> Sp1(Data,2), Sp2, Sp3(Data,3);
Sp2 = Sp1+1;
cerr << "Sp1[0]: " << Sp1[0] << endl;
cerr << "Sp2: " << Sp2[0] << endl;
cerr << "Sp2+1: " << *(Sp2+1) << endl;
try {
cerr << Sp3-Sp2;
} catch(DifferentStepsException) {
cerr << "Different Steps Expected!" << endl;
}
Sp2 += 1;
cerr << "Sp2:" << *Sp2 << endl;
cerr << "Sp2-Sp1 " << Sp2-Sp1 << endl;
Sp2 -=1;
cerr << "Sp2:" << *Sp2 << endl;
cerr << "Sp2-Sp1 " << Sp2-Sp1 << endl;
Sp3 = Sp2-1;
cerr << "Sp3:" << *Sp3 << endl;
cerr << "Sp3-Sp2 " << Sp3-Sp2 << endl;
cerr << "Sp2<Sp3 ? :" << (Sp2<Sp3) << endl;
cerr << "Sp2>Sp3 ? :" << (Sp2>Sp3) << endl;
cerr << "Sp3<Sp1 ? :" << (Sp3<Sp1) << endl;
cerr << "Sp3<Sp1 ? :" << (Sp3<=Sp1) << endl;
cerr << "*(Sp3++) :" << *(Sp3++) << endl;
cerr << "*Sp3 :" << *Sp3 << endl;
Sp1 = Data+1;
cerr << "Sp1=Data+1 : " << *Sp1 << endl;
#define PRT_DATA do { \
for(int i=0; i<12; i++) \
cerr << Data[i] << " "; \
cerr << endl; \
} while(false)
PRT_DATA;
StepIter<double> Sp_4(Data, 4);
sort(Sp_4, Sp_4+3);
PRT_DATA;
StepIter<double> Sp_3(Data, 3);
sort(Sp_3, Sp_3+4);
PRT_DATA;
StepIter<double> Sp_2(Data, 2);
sort(Sp_2, Sp_2+6);
PRT_DATA;
StepIter<double> Sp_1(Data, 1);
sort(Sp_1, Sp_1+12);
PRT_DATA;
StepIter<double> Sp_r(Data+11, -1); // Even can be used to reverse the order
sort(Sp_r, Sp_r+12);
PRT_DATA;
Then the results are:
Sp1[0]: 2 Sp2: 4 Sp2+1: 1 Different Steps Expected! Sp2:1 Sp2-Sp1 2 Sp2:4 Sp2-Sp1 1 Sp3:2 Sp3-Sp2 -1 Sp2Sp3 ? :1 Sp3<Sp1 ? :0 Sp3<Sp1 ? :1 *(Sp3++) :2 *Sp3 :4 Sp1=Data+1 : 3 2 3 4 5 1 6 9 11 8 7 12 10 1 3 4 5 2 6 9 11 8 7 12 10 1 3 4 5 2 6 7 11 8 9 12 10 1 3 2 5 4 6 7 11 8 9 12 10 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1
Next, I have to say C++ is too complicate, but still too weak. The point is that it’s missing too much features a modern language should have.
We may expect C++0x, but it’s just a plan!
The major problem is “functional”. Two day before, I’m trying to create a function dynamically which depends on some parameter determines in runtime. But it’s seems impossible. There do have some tools called “mem_fun” and “bind” can do partially by highly tricky technicals. But my function have two arguments! STL can not deal with it, since only “mem_fun”(for member functions with no argument) and “mem_fun1″ (for member functions with one argument). By learning this tricks from STL, I do realize such “function” (In fact, it’s a class). However, when I want to pass this “function” to a “C” library, the codes cannot pass the compiling. It seems no easy way to do this, then I give up. Anyone know how to deal with this problem?