C++ 2003, §17.4.3.1/1: "A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined name of external linkage and unless the specialization meets the standard library requirements for the original template."
As such, you're allowed to specialize a library template, and put your specialization in namespace std
, as long as it depends on a user defined type and meets the requirements of the original template.
The code you have in your edited question seems to be a specialization for a user-defined name that (presumably) has external linkage, so you shouldn't have any problem with that part of things.
That leaves only the requirement that your specialization meet the requirements of the original template. For your type, most of this will probably border on trivial. The only part I can see that might not be obvious is that you do seem to have to provide a specialization for the whole template, not just numeric_limits::max()
. I.e., you'll have to do something like (example should be in the ballpark for a 128-bit unsigned integer type):
namespace std {
template <>
class numeric_limits<my_integer> {
public:
static const bool is_specialized = true;
static T min() throw() { return 0;
static T max() throw() { return /* 2^128-1 */; } // ***
static const int digits = 128;
static const int digits10 = 38;
static const bool is_signed = false;
static const bool is_integer = true;
static const bool is_exact = true;
static const int radix = 2;
static T epsilon() throw() { return 0; }
static T round_error() throw() { return 0; }
static const int min_exponent = 0;
static const int min_exponent10 = 0;
static const int max_exponent = 0;
static const int max_exponent10 = 0;
static const bool has_infinity = false;
static const bool has_quiet_NaN = false;
static const bool has_signaling_NaN = false;
static const float_denorm_style has_denorm = denorm_absent;
static const bool has_denorm_loss = false;
static T infinity() throw() { return 0; }
static T quiet_NaN() throw() { return 0; }
static T signaling_NaN() throw() { return 0; }
static T denorm_min() throw() { return 0; }
static const bool is_iec559 = false;
static const bool is_bounded = true;
static const bool is_modulo = true;
static const bool traps = false;
static const bool tinyness_before = false;
static const float_round_style round_style = round_toward_zero;
};
}
Quite a few of those are really for FP types, and aren't required to be meaningful for an integer type; I believe they still need to be implemented.