LCOV - code coverage report
Current view: top level - usr/include/boost/random/detail - signed_unsigned_tools.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 2 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* boost random/detail/signed_unsigned_tools.hpp header file
       2             :  *
       3             :  * Copyright Jens Maurer 2006
       4             :  * Distributed under the Boost Software License, Version 1.0. (See
       5             :  * accompanying file LICENSE_1_0.txt or copy at
       6             :  * http://www.boost.org/LICENSE_1_0.txt)
       7             :  *
       8             :  * See http://www.boost.org for most recent version including documentation.
       9             :  */
      10             : 
      11             : #ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
      12             : #define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
      13             : 
      14             : #include <boost/limits.hpp>
      15             : #include <boost/config.hpp>
      16             : #include <boost/random/traits.hpp>
      17             : 
      18             : namespace boost {
      19             : namespace random {
      20             : namespace detail {
      21             : 
      22             : 
      23             : /*
      24             :  * Compute x - y, we know that x >= y, return an unsigned value.
      25             :  */
      26             : 
      27             : template<class T, bool sgn = std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_bounded>
      28             : struct subtract { };
      29             : 
      30             : template<class T>
      31             : struct subtract<T, /* signed */ false>
      32             : {
      33             :   typedef T result_type;
      34           0 :   result_type operator()(T x, T y) { return x - y; }
      35             : };
      36             : 
      37             : template<class T>
      38             : struct subtract<T, /* signed */ true>
      39             : {
      40             :   typedef typename boost::random::traits::make_unsigned_or_unbounded<T>::type result_type;
      41             :   result_type operator()(T x, T y)
      42             :   {
      43             :     if (y >= 0)   // because x >= y, it follows that x >= 0, too
      44             :       return result_type(x) - result_type(y);
      45             :     if (x >= 0)   // y < 0
      46             :       // avoid the nasty two's complement case for y == min()
      47             :       return result_type(x) + result_type(-(y+1)) + 1;
      48             :     // both x and y are negative: no signed overflow
      49             :     return result_type(x - y);
      50             :   }
      51             : };
      52             : 
      53             : /*
      54             :  * Compute x + y, x is unsigned, result fits in type of "y".
      55             :  */
      56             : 
      57             : template<class T1, class T2, bool sgn = (std::numeric_limits<T2>::is_signed && (std::numeric_limits<T1>::digits >= std::numeric_limits<T2>::digits))>
      58             : struct add { };
      59             : 
      60             : template<class T1, class T2>
      61             : struct add<T1, T2, /* signed or else T2 has more digits than T1 so the cast always works - needed when T2 is a multiprecision type and T1 is a native integer */ false>
      62             : {
      63             :   typedef T2 result_type;
      64           0 :   result_type operator()(T1 x, T2 y) { return T2(x) + y; }
      65             : };
      66             : 
      67             : template<class T1, class T2>
      68             : struct add<T1, T2, /* signed */ true>
      69             : {
      70             :   typedef T2 result_type;
      71             :   result_type operator()(T1 x, T2 y)
      72             :   {
      73             :     if (y >= 0)
      74             :       return T2(x) + y;
      75             :     // y < 0
      76             :     if (x > T1(-(y+1)))  // result >= 0 after subtraction
      77             :       // avoid the nasty two's complement edge case for y == min()
      78             :       return T2(x - T1(-(y+1)) - 1);
      79             :     // abs(x) < abs(y), thus T2 able to represent x
      80             :     return T2(x) + y;
      81             :   }
      82             : };
      83             : 
      84             : } // namespace detail
      85             : } // namespace random
      86             : } // namespace boost
      87             : 
      88             : #endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
      89             : 

Generated by: LCOV version 1.14