Another foreach idea.

Oskar Linde oskar.lindeREM at OVEgmail.com
Thu Jun 8 02:38:05 PDT 2006


Derek Parnell wrote:
> On Wed, 07 Jun 2006 22:56:50 -0700, Kirk McDonald wrote:
> 
>> Kirk McDonald wrote:
>  
>> Oh! I did some thinking and improved it a little. It's a struct now ...
> 
> Hope you don't mind but I turned your code into a templated version...
> 
> //------- file: ranger.d ----------------
> struct range_struct(T) {
> public:
>      T m_start, m_end, m_step;
> 
>      // Compares whether i has reached the end
>      private bool cmp(T i) {
>          if (m_step > 0 && i < m_end) return true;
>          else if (m_step < 0 && i > m_end) return true;
>          else return false;
>      }
> 
>      int opApply(int delegate(inout T) dg) {
>          int result = 0;
>          for (T i=m_start; this.cmp(i); i+=m_step) {
>              result = dg(i);
>              if (result) break;
>          }
>          return result;
>      }
>      int opApply(int delegate(inout int, inout T) dg) {
>          int result = 0;
>          int cnt;
>          for (T i=m_start; this.cmp(i); i+=m_step) {
>              result = dg(cnt, i);
>              if (result) break;
>              cnt++;
>          }
>          return result;
>      }
> }

<replace>
> template range_t(T)
> {
>     range_struct!(T) range(T start, T end, T step=1) {
>          range_struct!(T) r;
>          r.m_start = start;
>          r.m_end   = end;
>          r.m_step  = step;
>          return r;
>     }
> 
>     range_struct!(T) range(T end) {
>          return range(0, end, 1);
>     }
> }
> 
> alias range_t!(char).range range;
> alias range_t!(int).range range;
> alias range_t!(real).range range;
</replace>

Replacing the above code with the following (kind of ugly) code makes it 
work for any type that is comparable, implements += and (this is 
limiting but possibly workaroundable with some assumptions) assignable 
from 1 and 0.

template range(T,T2,T3=int) {
         static assert(is(T2:T), "range arg 2 must be convertible to T");
         static assert(is(T3:T), "range arg 3 must be convertible to T");
         range_struct!(T) range(T start, T2 end, T3 step=1) {
                 range_struct!(T) r;
                 r.m_start = start;
                 r.m_end   = end;
                 r.m_step  = step;
                 return r;
         }
}

template range(T) {
         range_struct!(T) range(T end) {
                 return .range!(T,T,T)(0,end,1);
         }
}

/Oskar



More information about the Digitalmars-d mailing list