We need a way to make functions pure and/or nothrow based on the purity and/or nothrowability of the functions that they call
Jonathan M Davis
jmdavisProg at gmx.com
Sun Nov 14 15:59:17 PST 2010
On Sunday 14 November 2010 07:07:11 Philippe Sigaud wrote:
> On Sun, Nov 14, 2010 at 10:56, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> > Does anyone have some good suggestions on how to solve this issue?
>
> IIRC, I posted something related to this 2-3 months ago, though I
> don't know if that was a real solution. That was for pure only, but
> that could be extended to pure¬hrow. The idea was to try to
> instantiate a pure/nothrow test function in the template constraints.
> I'm not sure it's much cleaner than your code...
>
> Let see, something like this:
>
> static if (__traits(compiles, {
> void test(...) pure { /* fun
> body here */}; // can we do a pure fun with this body?
> }))
> retType myFunc( whatever ) pure { /* fun body here */ };
> else
> retType myFunc (whatever ) { /* fun body here */ };
>
>
> That is, you do not need to know the functions called inside myFunc.
> You try to instantiate a pure version. If that does not compile, let
> myFunc be impure...
>
> Of course, that means repeating the body three times. A partial
> solution is to provide myFunc code as a string:
>
> enum funCode = "retType myFunc (whatever ) %p %n {... };";
>
> then have a template replace %p by "" or "pure" and %n by "" or
> "nothrow" and generate four strings.
> Then let it try to instantiate the four combinations, beginning with
> pure nothrow. When one version compiles, static-if-y it into
> existence.
> IIRC pure and nothrow can be put at the beginning of the signature? If
> that's the case, you do not even need the %n, %p trick. Just prepend
> "pure " and such.
>
> the global template would be:
>
> mixin(Instantiate!("@property bool empty() { return innerRange.empty;
> }", Pure.yes, Nothrow.yes));
>
> Ok, I typed this rapidly, so feel free to point any mistake in it :-)
>
> Philippe
You end up with 4 different versions. pure nothrow, pure, nothrow, and impure
non-nothrow. If you have template function, it would go in the template
constraints. In my example, you're dealing with the constructor in a templated
type, so you end up with static ifs instead of using template constraints, but
you're still dealing with at template. I don't see any way around declaring 4
different versions in situtations where you could have any combination of pure
and nothrow. Your idea of just trying to compile the function instead of
checking for purity or throwability is a potentially good one, though for better
or for worse, other compile errors for such a function would cause it to
ultimately try and compile the impure throwable version - which would mean that
if the mistake was in the signature with either pure or nothrow (like spelling
it pur or nothrw), then you'd keep ending up with the wrong version. If an
appropriate template were used in the constructing though, that problem would
only have to be fixed once.
Regardless, you're stuck turning every template function whose purity and
throwability depends on other template functions into string mixins, and that is
definitely less than ideal.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list