On Sunday 14 November 2010 07:07:11 Philippe Sigaud wrote:
> On Sun, Nov 14, 2010 at 10:56, Jonathan M Davis <jmdavisp...@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&nothrow. 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

Reply via email to