Search code examples
c++11c++14atomicstdatomicnumeric-limits

numeric_limits of atomic types


Suppose someAtomic is an std::atomic with an integral underlying type, such as atomic_uint16_t. I don't want to assume WHICH integral type, however, in particular code, so I want something to accomplish the following, which right now doesn't compile:

if (newVal > numeric_limits<decltype(someAtomic)>::max()) throw "newVal too large";
else someAtomic.store(newVal, memory_order_release);

It looks like at least in VC++2015 there are no numeric_limits specializations for atomic types even if their underlying types do have such specializations. What's the best way to deal with this?


Solution

  • template<class T>
    struct my_numeric_limits : std::numeric_limits<T>{};
    
    template<class T>
    struct my_numeric_limits<std::atomic<T>> : my_numeric_limits<T>{};
    

    Then you can use my_numeric_limits<SomeAtomic>::max().

    This is less likely to violate (vague) parts of the standard than adding a specialization to std::numeric_limits that does not depend on a user-provided type. In C++11, there were requirements that you specialize over "user defined types", and I am uncertain if this has been resolved if std::atomic<int> is user-defined or not. I saw a fix proposal, but am uncertain if it went anywhere.

    Regardless, this follows the principle of least surprise, and is just as efficient. Messing around with things in the std namespace should only be done when the alternatives are impractical.

    Get something wrong, and your code suddenly becomes ill-formed, no diagnostic required. People checking your code are rightly scared. People modifying your code have to not screw up. my_numeric_limits is robust, safe, and resists error.