#include <limits>
#include <iostream>
#include <cassert>

#define NDIM 1

template<class OP, class T>
struct Range
{
    Range(OP &op): min(numeric_limits<T>::max()),
                   max(-numeric_limits<T>::max()), f(op)
    {}
    
    template<class IDX>
    inline void operator()(const IDX &v) 
    { 
        if (f(v)<min) min = f(v);
        if (f(v)>max) max = f(v);
    }
    
    T min, max;
protected:
    OP &f;
};

class myidx
{
public:
    myidx(const int &i) : idx(i) {}
    myidx() : idx(0) {} 
    const int operator[](int i) const { assert(i==0); return idx; }
    int &operator[](int i) { assert(i==0); return idx; }
protected:
    int idx;
};

struct myop
{
    myop(double *p) { arr = p; }
    double operator()(const myidx &i) { return arr[i[0]]; }
protected:
    double *arr;
}; 

template<class IDX, class OP>
static inline void for_each(const IDX b, const IDX e, OP &op)
{
  ForEach<NDIM,IDX,OP> fe(b,e,op);
  fe();
}
  
template<int N, class IDX, class OP> struct ForEach;

template<class IDX, class OP>
struct ForEach<1,IDX,OP>
{
  ForEach(const IDX &begin, const IDX &end, OP &op):
    b(begin[0]),
    e(end[0]),
    fop(op)
  {}

  inline void operator()()
  {
     for(v[0]=b; v[0]<e; ++v[0]) fop(v);
  }
    
  protected:
     const int           b,e;
     OP                  &fop;
  public:
     IDX                 v;
};
  

template<class IDX, class OP, class T>
static inline void range(const IDX begin, const IDX end, OP op,
                         T &min, T &max)
{
    Range<OP,T> range_op(op);
    for_each(begin, end, range_op);
    min = range_op.min;
    max = range_op.max;
}

template <class T>
inline const T& PTmax(const T& a, const T& b)
{
  return (a > b) ? a : b;
}

template <class T>
inline T PTabs(const T& a)
{
  return (a < 0? -a:a);
}

int main(void)
{
   double array[]={2.2,1.1,3.3,7.7};
   static myop myop1(array);
   double v_div,min,max;
   
   range<myidx, myop, double>(myidx(0),myidx(4),myop1,min,max);

   // If you add the following line, the code will work with -O4 as
   // well. If you do not add the followign line, the code will fail
   // with -O4 
 
   // clog << max << endl;

   v_div = max = PTmax(PTabs(min),max);

   clog << max << endl;
}

