You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by Eric Lemings <Er...@roguewave.com> on 2008/06/20 20:32:22 UTC

tests/utilities/20.meta.help.cpp

 
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.
 
Brad.

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

Posted by Martin Sebor <se...@roguewave.com>.
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<T>::value shall be a integral constant
>       expression (5.19).
> 
> With concepts, we would change the definition of the class like
> this (I think):
> 
>    template <IntegralConstantExpressionType T, T v>

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 <IntegralConstantExpressionType T, T v>
   requires IntegralType<T> || EnumerationType<T>
   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<T>::value shall be an integral
       constant expression (5.19).

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

     template <class T, T v>
     struct integral_constant {
         typedef T value_type;
         typedef integral_constant<value_type, v> 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

Posted by Martin Sebor <se...@roguewave.com>.
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<T,V> 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<void
>>> (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<T>::value shall be a integral constant
       expression (5.19).

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

    template <IntegralConstantExpressionType T, T 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

Posted by Travis Vitek <Tr...@roguewave.com>.
 

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<T,V> 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<void
>> (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

Posted by Martin Sebor <se...@roguewave.com>.
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<T,V> 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<void
> (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.

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

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Travis Vitek [mailto:Travis.Vitek@roguewave.com] 
> 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<void
> (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

Posted by Travis Vitek <Tr...@roguewave.com>.
 

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<T,V> 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<void
(class_t::*)(), &class::method>, but I'm not sure if it something that
should be tested.

>Brad.
>