On Wed, 11 Nov 2009 10:30:24 -0600, Andrei Alexandrescu <seewebsiteforem...@erdani.org> wrote:
> >Then different isXxxRange are used by higher-order ranges in defining >refined interfaces depending on the interfaces offered by their inputs. >I fail to see how that's terrible. It is not terrible. It just doesn't give any clue about what exactly is wrong with the entity for which interface validation has failed. I tend to put the code that defines the interface in a separate template to be able to find out the exact error. And because neither _traits(compiles) nor is(typeof) can be currently used to test template instantiations, the code goes to a mixed-in string and the whole affair gets messy. This is the result: private enum inputRangeConcept = q{{ R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }}; template InputRangeConcept(R) { mixin ("void _()" ~ inputRangeConcept); } template isInputRange(R) { enum isInputRange = is(typeof(mixin(inputRangeConcept))); } So, for example: alias InputRangeConcept!(int) check; will yield test.d(20): Error: no property 'empty' for type 'int' test.d(21): Error: no property 'popFront' for type 'int' test.d(22): Error: no property 'front' for type 'int' which gives exact information about what is wrong with int candidate for input range position (line numbers are incorrect, though).