Re: tests/utilities/20.meta.help.cpp

2008-06-24 Thread Martin Sebor

Martin Sebor wrote:

Travis Vitek wrote:
 

[...]

IMO, the class should have an explicit requirement on the first
template argument. If there isn't one I would propose adding
paragraph 2 with the text:

  -2- The template parameter T shall have an integral type (3.9.1).
  integral_constant::value shall be a integral constant
  expression (5.19).

With concepts, we would change the definition of the class like
this (I think):

   template 


Actually, I don't think this is quite sufficient. T is more
constrained than that. If there were an OR in Concepts it
would be:

  template 
  requires IntegralType || EnumerationType
  struct integral_constant;

I've written up an issue/proposal to fix this without using
concepts that I plan to send to the list shortly unless you
see a better way of dealing with it. Here's the proposal:

Add a new paragraph to [meta.help] with the following
requirement:

  -2- The template parameter T shall have an integral type
  (3.9.1) or be an enumeration (3.9.2).
  integral_constant::value shall be an integral
  constant expression (5.19).

In addition, declare the value data member of the template
constexpr:

template 
struct integral_constant {
typedef T value_type;
typedef integral_constant type;
static constexpr value_type value = v;
};


   struct integral_constant {
   // ...
   };

Strangely, this isn't in N2625:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2625.pdf

Incidentally, it also seems to me that value should be declared
constexpr (both in our implementation and in the spec).



Travis






Re: tests/utilities/20.meta.help.cpp

2008-06-23 Thread Martin Sebor

Travis Vitek wrote:
 


Martin Sebor wrote:

Travis Vitek wrote:
 
Eric Lemings wrote:
Just a brief side note.  I was just reviewing this test and 
noticed that
pointers are not tested though they are valid scalar types 

suitable for
use as integral_constant parameters.  I think references 

may be valid

parameters also.


I'm not sure.

The first thing that jumps to mind is that a pointer is not of
'integral' type. An enumeration isn't really an integral type either,
but they are implicitly convertible to one. Pointers aren't 

convertible

to integral type without a cast.

According to temp.arg.nontype, a non-type, non-template template
parameter must be one of

  -- an integral constant expression
  -- the name of a non-type template-parameter
  -- the address of an object or function with external linkage...
  -- a constant expression that evaluates to a null pointer value
  -- a constant expression that evaluates to a null member 

pointer value

  -- a pointer to member

So, yes, it is legal to use a pointer as a non-type template 

parameter.

The issue I have is that the integral_constant is supposed to
define an integral constant of type T with value V. Section 

expr.const
says that a constant expression is an integral constant 

expression if it
is of integral or enumeration type. An integral constant 

expression can

be used as an array bound, a case expression, a bit field length,
enumeration initializer, static member initializer and as integral or
enumeration non-type template arguments.

I'm pretty sure you can't use a pointer value as an array bound, case
expression, bit field length or enumeration initializer, so 

they aren't

really integral constants.

So I am sure you can instantiate std::integral_constant(class_t::*)(), &class::method>, but I'm not sure if it 

something that

should be tested.

If there's an implementation technique that would make the
instantiation ill-formed then I think it should be tested.


According to class.mem (p4) and class.static.data (p4) you aren't
allowed to initialize static members using a constant-initializer (i.e.
in the member declaration) if they are not of const integral or const
enumeration type. So the above instantiation on member pointer should be
prevented by the compiler. A quick test with msvc-8.0 and gcc-4.3 show
that this is the case.


Good point!



The following would be legal, but I'm already testing integral constants
for all integral types and an enum type, so I think I'm covered.


More important, though, the standard should specify the
requirements on the template arguments. If there are no
such requirements for something as fundamental as
integral_const, either in the latest working draft or
in one of the concepts papers (such as N2622), we should
at least bring it up on the list and/or open an issue to
have the spec clarified.


The standard does specify the requirements of the template arguments,
but only through association (to be an integral constant member, it has
to be a const static that is initialized with a constant-initializer,


Is this specified anywhere else besides the definition of the
class in [meta.help]? If not, I'm not sure that every detail
of a class definition shown in the spec qualifies as a normative
requirement.


and a constant initializer only works for enum and integral types). Is
this significant enough to warrant bringing up an issue?


IMO, the class should have an explicit requirement on the first
template argument. If there isn't one I would propose adding
paragraph 2 with the text:

  -2- The template parameter T shall have an integral type (3.9.1).
  integral_constant::value shall be a integral constant
  expression (5.19).

With concepts, we would change the definition of the class like
this (I think):

   template 
   struct integral_constant {
   // ...
   };

Strangely, this isn't in N2625:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2625.pdf

Incidentally, it also seems to me that value should be declared
constexpr (both in our implementation and in the spec).



Travis




RE: tests/utilities/20.meta.help.cpp

2008-06-23 Thread Travis Vitek
 

Martin Sebor wrote:
>
>Travis Vitek wrote:
>>  
>> Eric Lemings wrote:
>>>
>>> Just a brief side note.  I was just reviewing this test and 
>>> noticed that
>>> pointers are not tested though they are valid scalar types 
>suitable for
>>> use as integral_constant parameters.  I think references 
>may be valid
>>> parameters also.
>>>
>> 
>> I'm not sure.
>> 
>> The first thing that jumps to mind is that a pointer is not of
>> 'integral' type. An enumeration isn't really an integral type either,
>> but they are implicitly convertible to one. Pointers aren't 
>convertible
>> to integral type without a cast.
>> 
>> According to temp.arg.nontype, a non-type, non-template template
>> parameter must be one of
>> 
>>   -- an integral constant expression
>>   -- the name of a non-type template-parameter
>>   -- the address of an object or function with external linkage...
>>   -- a constant expression that evaluates to a null pointer value
>>   -- a constant expression that evaluates to a null member 
>pointer value
>>   -- a pointer to member
>> 
>> So, yes, it is legal to use a pointer as a non-type template 
>parameter.
>> 
>> The issue I have is that the integral_constant is supposed to
>> define an integral constant of type T with value V. Section 
>expr.const
>> says that a constant expression is an integral constant 
>expression if it
>> is of integral or enumeration type. An integral constant 
>expression can
>> be used as an array bound, a case expression, a bit field length,
>> enumeration initializer, static member initializer and as integral or
>> enumeration non-type template arguments.
>> 
>> I'm pretty sure you can't use a pointer value as an array bound, case
>> expression, bit field length or enumeration initializer, so 
>they aren't
>> really integral constants.
>> 
>> So I am sure you can instantiate std::integral_constant> (class_t::*)(), &class::method>, but I'm not sure if it 
>something that
>> should be tested.
>
>If there's an implementation technique that would make the
>instantiation ill-formed then I think it should be tested.

According to class.mem (p4) and class.static.data (p4) you aren't
allowed to initialize static members using a constant-initializer (i.e.
in the member declaration) if they are not of const integral or const
enumeration type. So the above instantiation on member pointer should be
prevented by the compiler. A quick test with msvc-8.0 and gcc-4.3 show
that this is the case.

The following would be legal, but I'm already testing integral constants
for all integral types and an enum type, so I think I'm covered.

>
>More important, though, the standard should specify the
>requirements on the template arguments. If there are no
>such requirements for something as fundamental as
>integral_const, either in the latest working draft or
>in one of the concepts papers (such as N2622), we should
>at least bring it up on the list and/or open an issue to
>have the spec clarified.

The standard does specify the requirements of the template arguments,
but only through association (to be an integral constant member, it has
to be a const static that is initialized with a constant-initializer,
and a constant initializer only works for enum and integral types). Is
this significant enough to warrant bringing up an issue?

Travis


Re: tests/utilities/20.meta.help.cpp

2008-06-23 Thread Martin Sebor

Travis Vitek wrote:
 


Eric Lemings wrote:


Just a brief side note.  I was just reviewing this test and 
noticed that

pointers are not tested though they are valid scalar types suitable for
use as integral_constant parameters.  I think references may be valid
parameters also.



I'm not sure.

The first thing that jumps to mind is that a pointer is not of
'integral' type. An enumeration isn't really an integral type either,
but they are implicitly convertible to one. Pointers aren't convertible
to integral type without a cast.

According to temp.arg.nontype, a non-type, non-template template
parameter must be one of

  -- an integral constant expression
  -- the name of a non-type template-parameter
  -- the address of an object or function with external linkage...
  -- a constant expression that evaluates to a null pointer value
  -- a constant expression that evaluates to a null member pointer value
  -- a pointer to member

So, yes, it is legal to use a pointer as a non-type template parameter.

The issue I have is that the integral_constant is supposed to
define an integral constant of type T with value V. Section expr.const
says that a constant expression is an integral constant expression if it
is of integral or enumeration type. An integral constant expression can
be used as an array bound, a case expression, a bit field length,
enumeration initializer, static member initializer and as integral or
enumeration non-type template arguments.

I'm pretty sure you can't use a pointer value as an array bound, case
expression, bit field length or enumeration initializer, so they aren't
really integral constants.

So I am sure you can instantiate std::integral_constant, but I'm not sure if it something that
should be tested.


If there's an implementation technique that would make the
instantiation ill-formed then I think it should be tested.

More important, though, the standard should specify the
requirements on the template arguments. If there are no
such requirements for something as fundamental as
integral_const, either in the latest working draft or
in one of the concepts papers (such as N2622), we should
at least bring it up on the list and/or open an issue to
have the spec clarified.

Martin




Brad.





RE: tests/utilities/20.meta.help.cpp

2008-06-20 Thread Eric Lemings
 

> -Original Message-
> From: Travis Vitek [mailto:[EMAIL PROTECTED] 
> Sent: Friday, June 20, 2008 12:59 PM
> To: dev@stdcxx.apache.org
> Subject: RE: tests/utilities/20.meta.help.cpp
> 
>  
...
> 
> So I am sure you can instantiate std::integral_constant (class_t::*)(), &class::method>, but I'm not sure if it something that
> should be tested.

Almost sounds like a rudimentary function object, doesn't it?  :)

template <
template < class PtrType, PtrType Ptr> class FuncPtr,
class ReturnType, class... ParamTypes
> struct FuncObj;

Brad.


RE: tests/utilities/20.meta.help.cpp

2008-06-20 Thread Travis Vitek
 

Eric Lemings wrote:
>
> 
>Just a brief side note.  I was just reviewing this test and 
>noticed that
>pointers are not tested though they are valid scalar types suitable for
>use as integral_constant parameters.  I think references may be valid
>parameters also.
> 

I'm not sure.

The first thing that jumps to mind is that a pointer is not of
'integral' type. An enumeration isn't really an integral type either,
but they are implicitly convertible to one. Pointers aren't convertible
to integral type without a cast.

According to temp.arg.nontype, a non-type, non-template template
parameter must be one of

  -- an integral constant expression
  -- the name of a non-type template-parameter
  -- the address of an object or function with external linkage...
  -- a constant expression that evaluates to a null pointer value
  -- a constant expression that evaluates to a null member pointer value
  -- a pointer to member

So, yes, it is legal to use a pointer as a non-type template parameter.

The issue I have is that the integral_constant is supposed to
define an integral constant of type T with value V. Section expr.const
says that a constant expression is an integral constant expression if it
is of integral or enumeration type. An integral constant expression can
be used as an array bound, a case expression, a bit field length,
enumeration initializer, static member initializer and as integral or
enumeration non-type template arguments.

I'm pretty sure you can't use a pointer value as an array bound, case
expression, bit field length or enumeration initializer, so they aren't
really integral constants.

So I am sure you can instantiate std::integral_constant, but I'm not sure if it something that
should be tested.

>Brad.
>