Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
Library Documentation Index

Safe Numerics

PrevUpHomeNext

Pending Issues

safe_base Only Works for Scalar Types
Concepts are Defined but Not Enforced.
Safe values Can Be Uninitialized
Other Pending Issues

The library is under development. There are a number of issues still pending.

safe_base Only Works for Scalar Types

The following is paraphrased from an issue raised by Andrzej Krzemieński as a github issue. It touches upon fundamental ideas behind the library and how these ideas as the implementation of the library collided with reality.

In the current implementation safe<T> will only work with T being a C++ scalar type. Therefore making a general type requirements that say what operations are allowed is superfluous, and confusing (because it implies that safe<> is more generic.

When I started out, It became clear that I wanted "safe" types to look like "numeric" types. It also became clear pretty soon that there was going to be significant template meta-programming in the implementation. Normal type traits like std::is_integer are defined in the std namespace and one is discouraged from extending it. Also I needed some compile time "max" and "lowest" values. This lead me to base the design on std::numeric_limits. But std::numeric limits is inherently extensible to any "numeric" type. For example, money is a numeric type but not an intrinsic types. So it seemed that I needed to define a "numeric" concept which required that there be an implementation of std::numeric_limits for any type T - such as money in this case. When I'm doubt - I tend to think big.

For now though I'm not going to address it. For what it's worth, my preference would be to do something like:

template<typename T>
struct range {
    T m_lowest;
    T m_highest;
    // default implementation
    range(
        const & T t_min, 
        const & T t_max
    ) :
        m_lowest(std::numeric_limits<T>::lowest(t_min),
        m_highest(std::numeric_limits<T>::max(t_max)
    {}
};

Then redeclare safe_base, etc. accordingly.

Concepts are Defined but Not Enforced.

The following is paraphrased from an issue raised by Andrzej Krzemieński as a github issue.

You do not need a concept to constrain anything with it, in your library. Or is the purpose of the Type requirements to show in detail what it means that safe<T> is a 'drop-in replacement for T?

Right - currently I don't use the concept to constrain anything. They are currently a purely "conceptual" tool to keep the design from getting off track. This is common with other libraries such as the C++ standard library where the concepts are defined but not enforced by compile time predicates. Hopefully in future that might change - see below

If you want to extend safe<T> for other integer types, Type requirement still need to be fixed:

Hmmmm - I'm not quite sure that this is true. One thing that IS true is the the interface and implementation of the library will need to be enhanced to permit "safe" to be applied to user defined types. This is apparent now, but as my brain can only comprehend the library one piece at a time, this design feature was lost during the implementation. In implementing co-existence of floats with safe integers, I did refactor the implementation in a way which I believe my eventually permit the application to any user supplied T which implements all the required operations of Numeric types. So as it is now this is pending. If the library were to become widely used, there might be motivation to do this. Time will tell. So for now I'm leaving these in the documentation and code, even though they are not actually used.

Safe values Can Be Uninitialized

Currently the library permits a safe<int> value to be uninitialized. This supports the goal of "drop-in" replacement of C++/C built-in types with safe counter parts. On the other hand, this breaks the "always valid" guarantee. The recent improvements in the exception policy implementation will permit a user to specify how this is to be handled.

Other Pending Issues

  • The library is currently limited to integers. If there is interest, it could be extended to floats and possible to user defined types.

  • Although care has been taken to make the library portable, at least some parts of the implementation - particularly checked integer arithmetic - depend upon two's complement representation of integers. Hence the library is probably not currently portable to all other possible C++ architectures. These days, this is unlikely to be a limitation in practice.

  • std::common_type is used in a variety of generic libraries, including std::chrono. Without a specialization for safe<T>s one cannot use the safe wrappers e.g. as a representation for std::chrono::duration.

  • For many meta programming tasks, the library uses the classic Boost.MPL library as well as the more current Boost.MP11 library. In the interests of conserving brain surface area required to understand and maintain the library, the remaining instances of usage of Boost.MPL should be replaces with code based on Boost.MP11.

  • For testing the library, we rely on Boost.Preprocessor to generate test cases. In later tests, we've depended on boost mp11. Again, in order to diminish the dependencies, we plan to replace usages of Boost.Preprocessor with Boost.MP11.


PrevUpHomeNext