Boost logo

Boost :

From: joel de guzman (isis-tech_at_[hidden])
Date: 2001-05-28 17:55:46


From: "Gregory Seidman" :

> } I'm a bit over-paranoid when it comes to syntax that will compile but
run in
> } an unexpected manner. By allowing the first three mentioned above, it's
> } _really_ easy for a user to forget the "until" and write a[0, 15]
instead of
> } a[0, until(15)] - and the two are totally different. Some compilers warn
> } about this, but it could perhaps be considered an "embarrassment", akin
to
> } "vector<list<int>>" but without any compile-time error.
>
> To make it a compile error, we do the following:
>
> class from {
> public:
> from(int min);
> };
>
> class until {
> public:
> until(int max);
> };
>
> until more(-1); //define "infinity"
>
> class range {
> public:
> range(const from &min, const until &max);
> explicit range(int minmax);
> };
>
> range operator,(const from &min, const until &max)
> { return range(min, max); }
>
> class IforgetNow {
> public:
> operator[](const range &range);
> };
>
> Now there is no implicit conversion from an int to a range, and a range is
> the only type the class providing [] can take in the brackets. If you try
> to use a[0, 15] then it will tell you that no method matches
> operator[](int). If you want to do a[15] you can do a[range(15)]
> explicitly. Also, if you feel like writing pedantic code, you can use
> a[range(0, 15)] to make it clear that it's a range.
>
> } Doug
> --Greg
>

Almost. My experimental implementation has 3 overloaded [].
There are 3 return types. The 'more' is a distinct type.
some pseudo code:

struct Parser {

   FixedIter operator[] (Exact n) const;
   FiniteIter operator[] (FixedRange r) const;
   InfiniteIter operator[] (InfiniteRange i) const;
};

   struct Exact{

       explicit Exact(uint n);
    };

    void operator,(Exact, Exact) { should not be done.. report some error }
    void operator,(int, Exact) { should not be done.. report some error }
    void operator,(Exact, int) { should not be done.. report some error }

Now the first is obvious:

  p[Exact(8)]; // returns a fixed iterator (exactly 8)

Now:

   struct InfiniteRange {

       explicit InfRange(uint n);
    };

    InfiniteRange operator,(uint min, More_t);
    More_t more;

Thus:

    a[0, more]; // 0..inf

Or:

   a[InfRange(0)];

Finally:

   struct FiniteRange {

     FiniteRange(uint from, uint until);
  };

    FiniteRange operator,(uint from, Until_t until);
    FiniteRange operator,(From_t from, uint until);
    FiniteRange operator,(From_t from, Until_t until);

 And so:

   a[8, until(20];
   a[from(9), until(20)]
   a[from(0), 20];

Or:

   a[FiniteRange(0, 20)];

Compile Error:

  a[0, 20]; // no way highway.

When the comma is used,
If the left operand is an int, the right operand must be a Until_t or a
More_t.
If the right operand is an int, the left operand must be a From_t.

Cheers,
Joel de Guzman

PS> Is this all worth it? I mean, in the quest to make [] work
(to distinguish iterator from grouping), we do all this tricks?

KISS:

   a.Repeat(8);
   a.Repeat(0, 20);
   a.Repeat(0, more);

   a(8);
   a(0, 20);
   a(0, more);

Nonetheless, I keep an open mind....


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