Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bslmt_saturatedtimeconversionimputil
[Package bslmt]

Provide special narrowing conversions for time types. More...

Namespaces

namespace  bslmt

Detailed Description

Outline
Purpose:
Provide special narrowing conversions for time types.
Classes:
bslmt::SaturatedTimeConversionImpUtil saturating time conversions.
See also:
Description:
This component defines a namespace containing static functions that perform narrowing conversions on time-related types, bslmt::SaturatedTimeConversionImpUtil. The provided conversions "saturate", meaning that for input values outside the representable range of the destination variable, the destination variable will be set to its maximum or minimum value (whichever is closer to the input value). Such saturating conversions are typically used to implement functions with a time-out (e.g., bslmt::Condition::timedWait) where a user-supplied time-out must be converted to a different time type before calling a system-library function. In such situations it is often simpler, safer, and within contract to perform a saturating conversion, rather than either return an error status or define complex undefined behavior for the function.
Conversion to Milliseconds:
This component defines an overloaded function named toMillisec. In addition to the saturating behavior defined above, toMillisec may also involve a loss of precision but without a concomitant loss of value. In particular, the converted value will be the smallest representable value greater than or equal to the original value.
For example, when bsls::TimeInterval(0, 1234567) is converted to an unsigned int using toMillisec, the result is 2 since 1234567 nanoseconds includes a fractional millisecond.
Usage:
Suppose we need to assign a value held in a bsls::TimeInterval to an unsigned int, where the unsigned int is to contain an equivalent time interval expressed in milliseconds. A bsls::TimeInterval is able to represent intervals that are outside the range of intervals that can be represented by an unsigned int number of milliseconds (e.g., any negative time interval). bslmt::SaturatedTimeConversionImpUtil handles values outside the representable range of the destination type by "saturating", that is values outside the representable range of the destination type will be assigned the maximum or minimum representable value of the destination type (whichever is closer to the source value).
First, we define variables of our source (bsls::TimeInterval) and destination (unsigned int) types:
  unsigned int destinationInterval;
  bsls::TimeInterval sourceInterval;
Then, we try a value that does not require saturation and observe that toMillisec converts it without modification (beyond loss of precision):
  sourceInterval.setInterval(4, 321000000);
  bslmt::SaturatedTimeConversionImpUtil::toMillisec(
                                       &destinationInterval, sourceInterval);
  assert(4321 == destinationInterval);
Next, we calculate the maximum value that can be represented in an unsigned int number of milliseconds, and verify that converting an equivalent bsls::TimeInterval does not modify the value:
  const unsigned int maxDestinationInterval =
                                    bsl::numeric_limits<unsigned int>::max();
  bsls::TimeInterval maximumTimeInterval(
                              maxDestinationInterval / 1000,
                              (maxDestinationInterval % 1000) * 1000 * 1000);
  bslmt::SaturatedTimeConversionImpUtil::toMillisec(
                                 &destinationInterval, maximumTimeInterval);
  assert(maxDestinationInterval == destinationInterval);
Now, we attempt to convert a value greater than the maximum representable in an unsigned int milliseconds and verify that the resulting value is the maximum representable unsigned int value:
  bsls::TimeInterval aboveMaxInterval = maximumTimeInterval +
                                          bsls::TimeInterval(0, 1000 * 1000);
  bslmt::SaturatedTimeConversionImpUtil::toMillisec(
                                     &destinationInterval, aboveMaxInterval);
  assert(maxDestinationInterval == destinationInterval);
Next, we try a value less than 0 and observe the result of the saturated conversion is 0 (the minimum representable value):
  bsls::TimeInterval belowMinimumInterval(-1, 0);
  bslmt::SaturatedTimeConversionImpUtil::toMillisec(
                                 &destinationInterval, belowMinimumInterval);
  assert(0 == destinationInterval);
Finally, when we convert a bsls::TimeInterval containing a fractional millisecond using toMillisec, the converted value is greater than the input value:
  bsls::TimeInterval piMSec(0, 3141593);  // 'pi' millseconds
  unsigned int       mSec;
  bslmt::SaturatedTimeConversionImpUtil::toMillisec(&mSec, piMSec);
  assert(4 == mSec);