Re: [webkit-dev] How we enable template functions

2017-08-23 Thread Keith Miller


> On Aug 23, 2017, at 12:21 PM, Konstantin Tokarev  wrote:
> 
> 
> 
> 23.08.2017, 21:15, "Keith Miller"  >:
>> You can totally have the enable_if in the template list:
>> 
>> #define ENABLE_TEMPLATE_IF(condition) typename = typename 
>> std::enable_if::type
>> 
>> template::value))>
>> int foo() { return 0; }
>> 
>> template::value))>
>> double foo() { return 0; }
>> 
>> int myFunction()
>> {
>> return foo();
>> }
>> 
>> Compiles fine for me.
>> 
>> There is another downside to the macros though. Since they will probably 
>> have a comma in them C++ thinks that comma is meant to distinguish arguments 
>> to the macro... The only work around I know of is to wrap the argument in 
>> parens as I did above.
> 
> Actually, you need no parens:
> 
> #define ENABLE_TEMPLATE_IF(...) typename = typename 
> std::enable_if<__VA_ARGS__>::type
> 
> template::value)>
> int foo() { return 0; }
> 
> template::value)>
> double foo() { return 0; }
> 
> int myFunction()
> {
> return foo();
> }

Oh, clever! I didn’t think of that.

> 
> 
>> 
>> I think mark’s case doesn’t work with my proposal so that’s convinced me 
>> that the template argument is the way to go. Although, I still think we 
>> should use the macro.
>> 
>> Any objections?
>> 
>> Cheers,
>> Keith
>> 
>>>  On Aug 23, 2017, at 7:28 AM, Mark Lam  wrote:
>>> 
>>>  One application of enable_if I’ve needed in the past is where I want 
>>> specialization of a template function with the same argument signatures, 
>>> but returning a different type. The only way I know to make that happen is 
>>> to use enable_if in the return type, e.g.
>>> 
>>>  std::enable_if::type doStuff() { }
>>>  std::enable_if::type doStuff() { }
>>> 
>>>  This works around the problem of “duplicate function definitions” which 
>>> arises if the enable_if is not in the function signature itself. So, I’m 
>>> not sure your ENABLE_TEMPLATE_IF macro will give me a solution for this.
>>> 
>>>  Mark
>>> 
  On Aug 22, 2017, at 11:14 PM, Keith Miller  wrote:
 
>  On Aug 22, 2017, at 9:17 PM, JF Bastien  wrote:
> 
>  I'd suggest considering what it'll look like when we're migrating to 
> concepts in C++20.
> 
>  Here's an example for our bitwise_cast:
>  https://github.com/jfbastien/bit_cast/blob/master/bit_cast.h#L10
> 
>  Notice the 3 ways to enable. There's also the option of using enable_if 
> on the return value, or as a defaulted function parameter, but I'm not a 
> huge fan of either.
 
  I think the concepts approach is the cleanest. I’d avoid the macro if we 
 go that way.
 
  But C++20 is a long way away and I only expect this problem to get worse 
 over time. So I’d rather find a nearer term solution.
 
>  On Aug 22, 2017, at 9:13 PM, Chris Dumez  wrote:
> 
>  I personally prefer std::enable_if<>. For e.g.
> 
>  template int>::value>
>  Class Foo { }
 
  I just find this much harder to parse since I now have to:
 
  1) recognize that the last class is not a actually polymorphic parameter
  2) figure out exactly what the condition is given that it’s hidden inside 
 an enable_if*
 
  The plus side of using a static_assert based approach is that it doesn’t 
 impact the readability of function/class signature at a high level since 
 it’s nested inside the body. It’s also not hidden particularly hidden 
 since I would expect it to be the first line of the body
 
  Another downside of enable_if as a default template parameter is that 
 someone could make a mistake and pass an extra template value, e.g. 
 Foo, and it might pick the wrong template parameter. This 
 isn’t super likely but it’s still a hazard.
 
  Admittedly, we could make a macro like (totes not stolen from JF’s 
 GitHub):
 
  #define ENABLE_TEMPLATE_IF(condition) typename = typename 
 std::enable_if::type
 
  and implement Foo as:
 
  template::value)>
  class Foo { };
 
  I think this approach is pretty good, although, I think I care about the 
 enable_if condition rarely enough that I’d rather not see it in the 
 signature. Most of the time the code will look like:
 
  template::value)>
  class Foo {...};
 
  template::value)>
  class Foo {...};
 
  template::value)>
  class Foo {...};
 
  So when I know I want to use a Foo but I forgot the signature I now need 
 to look mentally skip the enable_if macro, which I’d rather avoid.
 
>  I don’t like that something inside the body of a class / function would 
> cause a template to be enabled or not.
 
  I believe there are cases where this already basically already 

Re: [webkit-dev] How we enable template functions

2017-08-23 Thread Keith Miller
You can totally have the enable_if in the template list:

#define ENABLE_TEMPLATE_IF(condition) typename = typename 
std::enable_if::type

template::value))>
int foo() { return 0; }

template::value))>
double foo() { return 0; } 

int myFunction()
{
return foo();
}

Compiles fine for me.

There is another downside to the macros though. Since they will probably have a 
comma in them C++ thinks that comma is meant to distinguish arguments to the 
macro... The only work around I know of is to wrap the argument in parens as I 
did above.

I think mark’s case doesn’t work with my proposal so that’s convinced me that 
the template argument is the way to go. Although, I still think we should use 
the macro.

Any objections?

Cheers,
Keith

> On Aug 23, 2017, at 7:28 AM, Mark Lam  wrote:
> 
> One application of enable_if I’ve needed in the past is where I want 
> specialization of a template function with the same argument signatures, but 
> returning a different type.  The only way I know to make that happen is to 
> use enable_if in the return type, e.g.
> 
> std::enable_if::type doStuff() { }
> std::enable_if::type doStuff() { }
> 
> This works around the problem of “duplicate function definitions” which 
> arises if the enable_if is not in the function signature itself.  So, I’m not 
> sure your ENABLE_TEMPLATE_IF macro will give me a solution for this.
> 
> Mark
> 
> 
>> On Aug 22, 2017, at 11:14 PM, Keith Miller  wrote:
>> 
>>> On Aug 22, 2017, at 9:17 PM, JF Bastien  wrote:
>>> 
>>> I'd suggest considering what it'll look like when we're migrating to 
>>> concepts in C++20.
>>> 
>>> Here's an example for our bitwise_cast:
>>> https://github.com/jfbastien/bit_cast/blob/master/bit_cast.h#L10
>>> 
>>> Notice the 3 ways to enable. There's also the option of using enable_if on 
>>> the return value, or as a defaulted function parameter, but I'm not a huge 
>>> fan of either.
>> 
>> I think the concepts approach is the cleanest. I’d avoid the macro if we go 
>> that way.
>> 
>> But C++20 is a long way away and I only expect this problem to get worse 
>> over time. So I’d rather find a nearer term solution.
>> 
>>> On Aug 22, 2017, at 9:13 PM, Chris Dumez  wrote:
>>> 
>>> I personally prefer std::enable_if<>. For e.g.
>>> 
>>> template>> int>::value>
>>> Class Foo { }
>> 
>> I just find this much harder to parse since I now have to:
>> 
>> 1) recognize that the last class is not a actually polymorphic parameter
>> 2) figure out exactly what the condition is given that it’s hidden inside an 
>> enable_if*
>> 
>> The plus side of using a static_assert based approach is that it doesn’t 
>> impact the readability of function/class signature at a high level since 
>> it’s nested inside the body. It’s also not hidden particularly hidden since 
>> I would expect it to be the first line of the body
>> 
>> Another downside of enable_if as a default template parameter is that 
>> someone could make a mistake and pass an extra template value, e.g. 
>> Foo, and it might pick the wrong template parameter. This isn’t 
>> super likely but it’s still a hazard.
>> 
>> Admittedly, we could make a macro like (totes not stolen from JF’s GitHub):
>> 
>> #define ENABLE_TEMPLATE_IF(condition) typename = typename 
>> std::enable_if::type
>> 
>> and implement Foo as:
>> 
>> template::value)>
>> class Foo { };
>> 
>> I think this approach is pretty good, although, I think I care about the 
>> enable_if condition rarely enough that I’d rather not see it in the 
>> signature. Most of the time the code will look like:
>> 
>> template::value)>
>> class Foo {...};
>> 
>> template::value)>
>> class Foo {...};
>> 
>> template::value)>
>> class Foo {...};
>> 
>> So when I know I want to use a Foo but I forgot the signature I now need to 
>> look mentally skip the enable_if macro, which I’d rather avoid.
>> 
>>> 
>>> I don’t like that something inside the body of a class / function would 
>>> cause a template to be enabled or not.
>> 
>> I believe there are cases where this already basically already happens e.g. 
>> bitwise_cast. Although, I think those cases could be fixed with a more 
>> standard approach.
>> 
>> Cheers,
>> Keith
>> 
>>> 
>>> --
>>>  Chris Dumez
>>> 
>>> 
>>> 
>>> 
 On Aug 22, 2017, at 8:34 PM, Keith Miller  wrote:
 
 Hello fellow WebKittens,
 
 I’ve noticed over time that we don’t have standard way that we enable 
 versions of template functions/classes (flasses?). For the most part it 
 seems that people use std::enable_if, although, it seems like it is 
 attached to every possible place in the function/class.
 
 I propose that we choose a standard way to conditionally enable a template.
 
 There are a ton of options; my personal favorite is to add the following 
 macro:
 
 #define 

Re: [webkit-dev] How we enable template functions

2017-08-23 Thread Mark Lam
One application of enable_if I’ve needed in the past is where I want 
specialization of a template function with the same argument signatures, but 
returning a different type.  The only way I know to make that happen is to use 
enable_if in the return type, e.g.

std::enable_if::type doStuff() { }
std::enable_if::type doStuff() { }

This works around the problem of “duplicate function definitions” which arises 
if the enable_if is not in the function signature itself.  So, I’m not sure 
your ENABLE_TEMPLATE_IF macro will give me a solution for this.

Mark


> On Aug 22, 2017, at 11:14 PM, Keith Miller  wrote:
> 
>> On Aug 22, 2017, at 9:17 PM, JF Bastien > > wrote:
>> 
>> I'd suggest considering what it'll look like when we're migrating to 
>> concepts in C++20.
>> 
>> Here's an example for our bitwise_cast:
>> https://github.com/jfbastien/bit_cast/blob/master/bit_cast.h#L10 
>> 
>> 
>> Notice the 3 ways to enable. There's also the option of using enable_if on 
>> the return value, or as a defaulted function parameter, but I'm not a huge 
>> fan of either.
> 
> I think the concepts approach is the cleanest. I’d avoid the macro if we go 
> that way.
> 
> But C++20 is a long way away and I only expect this problem to get worse over 
> time. So I’d rather find a nearer term solution.
> 
>> On Aug 22, 2017, at 9:13 PM, Chris Dumez > > wrote:
>> 
>> I personally prefer std::enable_if<>. For e.g.
>> 
>> template> int>::value>
>> Class Foo { }
> 
> I just find this much harder to parse since I now have to:
> 
> 1) recognize that the last class is not a actually polymorphic parameter
> 2) figure out exactly what the condition is given that it’s hidden inside an 
> enable_if*
> 
> The plus side of using a static_assert based approach is that it doesn’t 
> impact the readability of function/class signature at a high level since it’s 
> nested inside the body. It’s also not hidden particularly hidden since I 
> would expect it to be the first line of the body
> 
> Another downside of enable_if as a default template parameter is that someone 
> could make a mistake and pass an extra template value, e.g. Foo, 
> and it might pick the wrong template parameter. This isn’t super likely but 
> it’s still a hazard.
> 
> Admittedly, we could make a macro like (totes not stolen from JF’s GitHub):
> 
> #define ENABLE_TEMPLATE_IF(condition) typename = typename 
> std::enable_if::type
> 
> and implement Foo as:
> 
> template::value)>
> class Foo { };
> 
> I think this approach is pretty good, although, I think I care about the 
> enable_if condition rarely enough that I’d rather not see it in the 
> signature. Most of the time the code will look like:
> 
> template::value)>
> class Foo {...};
> 
> template::value)>
> class Foo {...};
> 
> template::value)>
> class Foo {...};
> 
> So when I know I want to use a Foo but I forgot the signature I now need to 
> look mentally skip the enable_if macro, which I’d rather avoid.
> 
>> 
>> I don’t like that something inside the body of a class / function would 
>> cause a template to be enabled or not.
> 
> I believe there are cases where this already basically already happens e.g. 
> bitwise_cast. Although, I think those cases could be fixed with a more 
> standard approach.
> 
> Cheers,
> Keith
> 
>> 
>> --
>>  Chris Dumez
>> 
>> 
>> 
>> 
>>> On Aug 22, 2017, at 8:34 PM, Keith Miller >> > wrote:
>>> 
>>> Hello fellow WebKittens,
>>> 
>>> I’ve noticed over time that we don’t have standard way that we enable 
>>> versions of template functions/classes (flasses?). For the most part it 
>>> seems that people use std::enable_if, although, it seems like it is 
>>> attached to every possible place in the function/class.
>>> 
>>> I propose that we choose a standard way to conditionally enable a template.
>>> 
>>> There are a ton of options; my personal favorite is to add the following 
>>> macro:
>>> 
>>> #define ENABLE_TEMPLATE_IF(condition) static_assert(condition, “template 
>>> disabled”)
>>> 
>>> Then have every function do:
>>> 
>>> template
>>> void foo(…)
>>> {
>>>ENABLE_TEMPLATE_IF(std::is_same::value);
>>>…
>>> }
>>> 
>>> And classes:
>>> 
>>> template
>>> class Foo {
>>>ENABLE_TEMPLATE_IF(std::is_same::value);
>>> };
>>> 
>>> I like this proposal because it doesn’t obstruct the signature/declaration 
>>> of the function/class but it’s still obvious when the class is enabled. 
>>> Obviously, I think we should require that this macro is the first line of 
>>> the function or class for visibility. Does anyone else have thoughts or 
>>> ideas?
>>> 
>>> Cheers,
>>> Keith
>>> 
>>> P.S. in case you are wondering why this macro works (ugh C++), it’s because 
>>> if 

Re: [webkit-dev] How we enable template functions

2017-08-23 Thread Keith Miller
> On Aug 22, 2017, at 9:17 PM, JF Bastien  wrote:
> 
> I'd suggest considering what it'll look like when we're migrating to concepts 
> in C++20.
> 
> Here's an example for our bitwise_cast:
> https://github.com/jfbastien/bit_cast/blob/master/bit_cast.h#L10 
> 
> 
> Notice the 3 ways to enable. There's also the option of using enable_if on 
> the return value, or as a defaulted function parameter, but I'm not a huge 
> fan of either.

I think the concepts approach is the cleanest. I’d avoid the macro if we go 
that way.

But C++20 is a long way away and I only expect this problem to get worse over 
time. So I’d rather find a nearer term solution.

> On Aug 22, 2017, at 9:13 PM, Chris Dumez  wrote:
> 
> I personally prefer std::enable_if<>. For e.g.
> 
> template int>::value>
> Class Foo { }

I just find this much harder to parse since I now have to:

1) recognize that the last class is not a actually polymorphic parameter
2) figure out exactly what the condition is given that it’s hidden inside an 
enable_if*

The plus side of using a static_assert based approach is that it doesn’t impact 
the readability of function/class signature at a high level since it’s nested 
inside the body. It’s also not hidden particularly hidden since I would expect 
it to be the first line of the body

Another downside of enable_if as a default template parameter is that someone 
could make a mistake and pass an extra template value, e.g. Foo, 
and it might pick the wrong template parameter. This isn’t super likely but 
it’s still a hazard.

Admittedly, we could make a macro like (totes not stolen from JF’s GitHub):

#define ENABLE_TEMPLATE_IF(condition) typename = typename 
std::enable_if::type

and implement Foo as:

template::value)>
class Foo { };

I think this approach is pretty good, although, I think I care about the 
enable_if condition rarely enough that I’d rather not see it in the signature. 
Most of the time the code will look like:

template::value)>
class Foo {...};

template::value)>
class Foo {...};

template::value)>
class Foo {...};

So when I know I want to use a Foo but I forgot the signature I now need to 
look mentally skip the enable_if macro, which I’d rather avoid.

> 
> I don’t like that something inside the body of a class / function would cause 
> a template to be enabled or not.

I believe there are cases where this already basically already happens e.g. 
bitwise_cast. Although, I think those cases could be fixed with a more standard 
approach.

Cheers,
Keith

> 
> --
>  Chris Dumez
> 
> 
> 
> 
>> On Aug 22, 2017, at 8:34 PM, Keith Miller > > wrote:
>> 
>> Hello fellow WebKittens,
>> 
>> I’ve noticed over time that we don’t have standard way that we enable 
>> versions of template functions/classes (flasses?). For the most part it 
>> seems that people use std::enable_if, although, it seems like it is attached 
>> to every possible place in the function/class.
>> 
>> I propose that we choose a standard way to conditionally enable a template.
>> 
>> There are a ton of options; my personal favorite is to add the following 
>> macro:
>> 
>> #define ENABLE_TEMPLATE_IF(condition) static_assert(condition, “template 
>> disabled”)
>> 
>> Then have every function do:
>> 
>> template
>> void foo(…)
>> {
>>ENABLE_TEMPLATE_IF(std::is_same::value);
>>…
>> }
>> 
>> And classes:
>> 
>> template
>> class Foo {
>>ENABLE_TEMPLATE_IF(std::is_same::value);
>> };
>> 
>> I like this proposal because it doesn’t obstruct the signature/declaration 
>> of the function/class but it’s still obvious when the class is enabled. 
>> Obviously, I think we should require that this macro is the first line of 
>> the function or class for visibility. Does anyone else have thoughts or 
>> ideas?
>> 
>> Cheers,
>> Keith
>> 
>> P.S. in case you are wondering why this macro works (ugh C++), it’s because 
>> if there is any compile time error in a template it cannot be selected as 
>> the final candidate. In my examples, if you provided a type other than int 
>> foo/Foo could not be selected because the static_assert condition would be 
>> false, which is a compile error.
>> ___
>> webkit-dev mailing list
>> webkit-dev@lists.webkit.org 
>> https://lists.webkit.org/mailman/listinfo/webkit-dev
> 

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] How we enable template functions

2017-08-22 Thread JF Bastien
I'd suggest considering what it'll look like when we're migrating to
concepts in C++20.

Here's an example for our bitwise_cast:
https://github.com/jfbastien/bit_cast/blob/master/bit_cast.h#L10

Notice the 3 ways to enable. There's also the option of using enable_if on
the return value, or as a defaulted function parameter, but I'm not a huge
fan of either.

On Tue, Aug 22, 2017 at 9:13 PM, Chris Dumez  wrote:

> I personally prefer std::enable_if<>. For e.g.
>
> template int>::value>
> Class Foo { }
>
> I don’t like that something inside the body of a class / function would
> cause a template to be enabled or not.
>
> --
>  Chris Dumez
>
>
>
>
> On Aug 22, 2017, at 8:34 PM, Keith Miller  wrote:
>
> Hello fellow WebKittens,
>
> I’ve noticed over time that we don’t have standard way that we enable
> versions of template functions/classes (flasses?). For the most part it
> seems that people use std::enable_if, although, it seems like it is
> attached to every possible place in the function/class.
>
> I propose that we choose a standard way to conditionally enable a template.
>
> There are a ton of options; my personal favorite is to add the following
> macro:
>
> #define ENABLE_TEMPLATE_IF(condition) static_assert(condition, “template
> disabled”)
>
> Then have every function do:
>
> template
> void foo(…)
> {
>ENABLE_TEMPLATE_IF(std::is_same::value);
>…
> }
>
> And classes:
>
> template
> class Foo {
>ENABLE_TEMPLATE_IF(std::is_same::value);
> };
>
> I like this proposal because it doesn’t obstruct the signature/declaration
> of the function/class but it’s still obvious when the class is enabled.
> Obviously, I think we should require that this macro is the first line of
> the function or class for visibility. Does anyone else have thoughts or
> ideas?
>
> Cheers,
> Keith
>
> P.S. in case you are wondering why this macro works (ugh C++), it’s
> because if there is any compile time error in a template it cannot be
> selected as the final candidate. In my examples, if you provided a type
> other than int foo/Foo could not be selected because the static_assert
> condition would be false, which is a compile error.
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-dev
>
>
>
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-dev
>
>
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] How we enable template functions

2017-08-22 Thread Chris Dumez
I personally prefer std::enable_if<>. For e.g.

template::value>
Class Foo { }

I don’t like that something inside the body of a class / function would cause a 
template to be enabled or not.

--
 Chris Dumez




> On Aug 22, 2017, at 8:34 PM, Keith Miller  wrote:
> 
> Hello fellow WebKittens,
> 
> I’ve noticed over time that we don’t have standard way that we enable 
> versions of template functions/classes (flasses?). For the most part it seems 
> that people use std::enable_if, although, it seems like it is attached to 
> every possible place in the function/class.
> 
> I propose that we choose a standard way to conditionally enable a template.
> 
> There are a ton of options; my personal favorite is to add the following 
> macro:
> 
> #define ENABLE_TEMPLATE_IF(condition) static_assert(condition, “template 
> disabled”)
> 
> Then have every function do:
> 
> template
> void foo(…)
> {
>ENABLE_TEMPLATE_IF(std::is_same::value);
>…
> }
> 
> And classes:
> 
> template
> class Foo {
>ENABLE_TEMPLATE_IF(std::is_same::value);
> };
> 
> I like this proposal because it doesn’t obstruct the signature/declaration of 
> the function/class but it’s still obvious when the class is enabled. 
> Obviously, I think we should require that this macro is the first line of the 
> function or class for visibility. Does anyone else have thoughts or ideas?
> 
> Cheers,
> Keith
> 
> P.S. in case you are wondering why this macro works (ugh C++), it’s because 
> if there is any compile time error in a template it cannot be selected as the 
> final candidate. In my examples, if you provided a type other than int 
> foo/Foo could not be selected because the static_assert condition would be 
> false, which is a compile error.
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-dev

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


[webkit-dev] How we enable template functions

2017-08-22 Thread Keith Miller
Hello fellow WebKittens,

I’ve noticed over time that we don’t have standard way that we enable versions 
of template functions/classes (flasses?). For the most part it seems that 
people use std::enable_if, although, it seems like it is attached to every 
possible place in the function/class.

I propose that we choose a standard way to conditionally enable a template.

There are a ton of options; my personal favorite is to add the following macro:

#define ENABLE_TEMPLATE_IF(condition) static_assert(condition, “template 
disabled”)

Then have every function do:

template
void foo(…)
{
ENABLE_TEMPLATE_IF(std::is_same::value);
…
}

And classes:

template
class Foo {
ENABLE_TEMPLATE_IF(std::is_same::value);
};

I like this proposal because it doesn’t obstruct the signature/declaration of 
the function/class but it’s still obvious when the class is enabled. Obviously, 
I think we should require that this macro is the first line of the function or 
class for visibility. Does anyone else have thoughts or ideas?

Cheers,
Keith

P.S. in case you are wondering why this macro works (ugh C++), it’s because if 
there is any compile time error in a template it cannot be selected as the 
final candidate. In my examples, if you provided a type other than int foo/Foo 
could not be selected because the static_assert condition would be false, which 
is a compile error.
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev