This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 06/22/2017 06:16 AM, Richard Sandiford wrote:
Aldy Hernandez <aldyh@redhat.com> writes:On 06/20/2017 10:59 AM, Martin Sebor wrote:On 06/20/2017 02:41 AM, Aldy Hernandez wrote:On 05/23/2017 03:26 PM, Martin Sebor wrote:On 05/23/2017 04:48 AM, Aldy Hernandez wrote:+ void Union (wide_int x, wide_int y); + bool Union (const irange &r); + bool Union (const irange &r1, const irange &r2); + + // THIS = THIS ^ [X,Y]. Return TRUE if result is non-empty. + bool Intersect (wide_int x, wide_int y, bool readonly = false); + // THIS = THIS ^ R. Return TRUE if result is non-empty. + // THIS = R1 ^ R2. Return TRUE if result is non-empty. + bool Intersect (const irange &r1, const irange &r2, bool readonly = false); + // Return TRUE if THIS ^ R will be non-empty. + bool Intersect_p (const irange &r) + { return Intersect (r, /*readonly=*/true); } I would suggest the following changes to Union, Intersect, and Not: 1) Define all three members without the readonly argument and returning irange& (i.e., *this). The return value can be used wherever irange& is expected, and the is_empty() member function can be called on it to obtain the same result. E.g., Intersect A with B, storing the result in A: irange A, B; if (A.Intersect (B).is_empty ()) { ... } 2) Add non-members like so: irange range_union (const irange &lhs, const irange &rhs) { return irange (lhs).Union (rhs); } and find out if the union of A or B is empty without modifying either argument: irange A, B; if (range_union (A, B).is_empty ()) { ... }Perhaps we could provide an implicit conversion from irange to bool such that we could write: if (range_union (A, B)) { ... } as well as being able to write: if (!range_union (A, B).is_empty ()) { ... } That is, have range_union() return an irange as suggested, but have a bool overload (or whatever the C++ nomenclature is) such that converting an irange to a bool is interpreted as ``nitems != 0''. Is this acceptable C++ practice?Implicit conversion to bool is a common way of testing validity but I don't think it would be too surprising to use it as a test for non-emptiness. An alternative to consider is to provide an implicit conversion to an unsigned integer (instead of num_ranges()(*)) and have it return the number of ranges. That will make it possible to do the same thing as above while also simplifying the API.I really like this. I have added an implicit conversion to unsigned that returns the number of sub-ranges. However, I have also left the empty_p() method for a cleaner interface within the class itself. It feels wrong to type "if (!*this)" to represent emptiness within the class.Conversions to bool and conversions to int both seem dangerous. E.g. people might try "range1 | range2" as a shorthand for taking the union of the ranges. It'll compile but instead give the bitwise OR of the two range counts.
Yes, that's a valid point and the reason why conversion to "bool" as a test for validity is sometimes implemented as a conversion to some unique pointer type, e.g., struct UniquePointerType; operator UniquePointerType* () const; To avoid the same problem with an implicit conversion to integer the bitwise operator overloads (and any others of concern) could either be deleted from the overload set, e.g., using some sort of an enable_if trick (or declared as private members), or defined with the expected meaning (that could also obviate the problem with the capitalization of Union() if the operators were the only way to achieve that). But I don't have a strong preference for any of these approaches. Martin
How about instead having helper functions like intersect_p, as for bitmaps? Thanks, Richard
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |