Re: tests/utilities/20.meta.help.cpp
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
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
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
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
> -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
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. >