|
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