
Daryle Walker wrote:
I haven't yet read the Usenet article you mentioned in your reply because I want to get out my initial response without influence. [I read it after writing the following. I think my post here is more useful.]
----------------------------------------
From: Robert Ramey Date: Sun, 29 Jan 2012 15:01:10 -0800
I'm very confused about a number of things related to C++ standard and boost libraries dealing with numeric types. Here are a few things that I'm not getting.
a) The standard says in section 18.3.2.1
"Specializations shall be provided for each arithmetic type, both floating point and integer, including bool. The member is_specialized shall be true for all such specializations of numeric_limits." ... "Non-arithmetic standard types, such as complex<T> (26.4.2), shall not have specializations."
and it section 18.3.2.4 numeric_limits members
static constexpr bool is_bounded;
"True if the set of values representable by the type is finite. [ Note: All built-in types are bounded. This member would be false for arbitrary precision types.-end note ]"
So the question is: if one makes a "numeric type" like std::complex (or safe integer which I'm interested in right now). Should one define a specialization for this new type?
In my opinion, the qualifier is if the numeric concept is a (sub)set of the real numbers. If so, then they should have a std::numeric_limits specialization.
It seemed to me that any type which "acts like a number" should have such a specialization. I had interpreted the quote from the standard as an admonition that one should not specialize std::numeric_limits for one's own types. I had overlooked the phrase "non-arithimetic standard types". In my case my types IS arithmetic and it's NOT standard so the above wouldn't apply. So I concluded that my concerns were a false alarm. So, I've implemented a specialization of std::numeric_limits for my special kind of integer - which is OK by me. BUT, now I wonder about the idea if placing my own code into the std namespace which I would guess might raise other issues.
Built-in floating-point: YES Built-in integers (signed or unsigned): YES Built-in characters or Boolean: Logically, NO. Actuality, YES, due to the C++ language defining them as integer types. (And they're usable as such.) UDT arbitrary integer: YES UDT arbitrary floating/real: YES UDT rational: YES UDT arbitrary continued-fraction rational/real: YES
Complex: NO Modulo: NO Polynominals: NO (Math) Vectors: NO Matrices: NO Geometry: NO
I would say modular integer or float: definitely yes. decimal floats: definitely yes. polynomials: maybe if the are used to render numbers. Heck any radix based numbers numbers rendered as rational numbers: yes big/unbounded integers: definitely yes arbitray precision numbers: definitely yes. geometry, matrices, vectors, etc.: not likely e.g.rational numbers rendered as a quotient of two integers bounded = true e.g.rational numbers rendered as a quotient of two arbitray length integers bounded = false etc. ...
The working is pretty specific, but then I can't see why "is_bounded" is in there since all built-in arithmetic types are bounded. Oh I see this now: Required by LIA-1.
Is-bounded wouldn't apply to arbitrary length/precision types.
I would say it applies and that it's value should be false.
b) boost/type_traits/is_integral.hpp
numeric_limits is for the type's math properties.
Actually, it's not at all clear to me what the intended purpose is.
is_integral is for the type's properties with respect to the C++ type system. It can be used for template meta-programming.
I was surprised to find that is_integral, is is_signed, etc are not implemented in terms of numeric_limits but rather are implemented for just the built in types. This leads to the current situation: I create a new type of integer:safe_integer, modular_integer or .... which is intended to be used anyware an int or unsigned int can be used. This intention is frustrated when I use is_signed< modular_integer > ... /compile error but is_isigned<int> is OK The current situation is "don't do that" - OK - but it means that I can't implement anything that "works like an int" except for int itself. This seems to be to violate what I would have expected the intention of numeric_limits to be. If it can't do this - what was it intended to be used for? if type_traits for built in types don't use it - then why create it in the first place. I'm not advocating for changing anything. I'm just trying to figure out what this thing is good for.
The "modular integer<modulus>" is the only one of these that should NOT get a specialization for numeric_limits.
100 % disagree with this. It seems to me that this is the ideal use case for numeric_limits. Note that there a number of small but annoying ambiguities here. e.g. unsigned int acts like a modular integer - it rolls over without problem. But compilers may emit warnings when overflow might occur. I haven't looked at the is_modulo value for unsigned int. I'm guessing that numeric_limits isn't used to the extent that it was originally intended.
All of the others conceptually represent real-number values, and therefore should. None of these types are built-ins, and therefore NEVER should get a is_integral specialization.
This distinction between built-ins add-ins is the source of my consternation. In principle, I would like to replace/extend any built-in type with my own special variant. Which I can do. What's not clear is what should be done with regards to numeric_limits for this new type. Ideally, by specializing numeric_limits for my new type I should be able to get "free" benefits from programs which use numeric_limits to affect their behavior. Robert Ramey