BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmt_saturatedtimeconversionimputil.h
Go to the documentation of this file.
1/// @file bslmt_saturatedtimeconversionimputil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_saturatedtimeconversionimputil.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_SATURATEDTIMECONVERSIONIMPUTIL
9#define INCLUDED_BSLMT_SATURATEDTIMECONVERSIONIMPUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_saturatedtimeconversionimputil bslmt_saturatedtimeconversionimputil
15/// @brief Provide special narrowing conversions for time types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_saturatedtimeconversionimputil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_saturatedtimeconversionimputil-purpose"> Purpose</a>
25/// * <a href="#bslmt_saturatedtimeconversionimputil-classes"> Classes </a>
26/// * <a href="#bslmt_saturatedtimeconversionimputil-description"> Description </a>
27/// * <a href="#bslmt_saturatedtimeconversionimputil-conversion-to-milliseconds"> Conversion to Milliseconds </a>
28/// * <a href="#bslmt_saturatedtimeconversionimputil-usage"> Usage </a>
29/// * <a href="#bslmt_saturatedtimeconversionimputil-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#bslmt_saturatedtimeconversionimputil-purpose}
32/// Provide special narrowing conversions for time types.
33///
34/// # Classes {#bslmt_saturatedtimeconversionimputil-classes}
35///
36/// - bslmt::SaturatedTimeConversionImpUtil: saturating time conversions.
37///
38/// @see
39///
40/// # Description {#bslmt_saturatedtimeconversionimputil-description}
41/// This component defines a namespace containing static functions
42/// that perform narrowing conversions on time-related types,
43/// `bslmt::SaturatedTimeConversionImpUtil`. The provided conversions
44/// "saturate", meaning that for input values outside the representable range of
45/// the destination variable, the destination variable will be set to its
46/// maximum or minimum value (whichever is closer to the input value). Such
47/// saturating conversions are typically used to implement functions with a
48/// time-out (e.g., `bslmt::Condition::timedWait`) where a user-supplied
49/// time-out must be converted to a different time type before calling a
50/// system-library function. In such situations it is often simpler, safer, and
51/// within contract to perform a saturating conversion, rather than either
52/// return an error status or define complex undefined behavior for the
53/// function.
54///
55/// ## Conversion to Milliseconds {#bslmt_saturatedtimeconversionimputil-conversion-to-milliseconds}
56///
57///
58/// This component defines an overloaded function named `toMillisec`. In
59/// addition to the saturating behavior defined above, `toMillisec` may also
60/// involve a loss of precision but without a concomitant loss of value. In
61/// particular, the converted value will be the smallest representable value
62/// greater than or equal to the original value.
63///
64/// For example, when `bsls::TimeInterval(0, 1234567)` is converted to an
65/// `unsigned int` using `toMillisec`, the result is 2 since 1234567 nanoseconds
66/// includes a fractional millisecond.
67///
68/// ## Usage {#bslmt_saturatedtimeconversionimputil-usage}
69///
70///
71/// This section illustrates intended use of this component.
72///
73/// ### Example 1: Basic Usage {#bslmt_saturatedtimeconversionimputil-example-1-basic-usage}
74///
75///
76/// Suppose we need to assign a value held in a `bsls::TimeInterval` to an
77/// `unsigned int`, where the `unsigned int` is to contain an equivalent time
78/// interval expressed in milliseconds. A `bsls::TimeInterval` is able to
79/// represent intervals that are outside the range of intervals that can be
80/// represented by an `unsigned int` number of milliseconds (e.g., any negative
81/// time interval). `bslmt::SaturatedTimeConversionImpUtil` handles values
82/// outside the representable range of the destination type by "saturating",
83/// that is values outside the representable range of the destination type will
84/// be assigned the maximum or minimum representable value of the destination
85/// type (whichever is closer to the source value).
86///
87/// First, we define variables of our source (`bsls::TimeInterval`) and
88/// destination (`unsigned int`) types:
89/// @code
90/// unsigned int destinationInterval;
91/// bsls::TimeInterval sourceInterval;
92/// @endcode
93/// Then, we try a value that does not require saturation and observe that
94/// `toMillisec` converts it without modification (beyond loss of precision):
95/// @code
96/// sourceInterval.setInterval(4, 321000000);
97/// bslmt::SaturatedTimeConversionImpUtil::toMillisec(
98/// &destinationInterval, sourceInterval);
99/// assert(4321 == destinationInterval);
100/// @endcode
101/// Next, we calculate the maximum value that can be represented in an
102/// `unsigned int` number of milliseconds, and verify that converting an
103/// equivalent `bsls::TimeInterval` does not modify the value:
104/// @code
105/// const unsigned int maxDestinationInterval =
106/// bsl::numeric_limits<unsigned int>::max();
107/// bsls::TimeInterval maximumTimeInterval(
108/// maxDestinationInterval / 1000,
109/// (maxDestinationInterval % 1000) * 1000 * 1000);
110/// bslmt::SaturatedTimeConversionImpUtil::toMillisec(
111/// &destinationInterval, maximumTimeInterval);
112/// assert(maxDestinationInterval == destinationInterval);
113/// @endcode
114/// Now, we attempt to convert a value greater than the maximum representable in
115/// an `unsigned int` milliseconds and verify that the resulting value is the
116/// maximum representable `unsigned int` value:
117/// @code
118/// bsls::TimeInterval aboveMaxInterval = maximumTimeInterval +
119/// bsls::TimeInterval(0, 1000 * 1000);
120/// bslmt::SaturatedTimeConversionImpUtil::toMillisec(
121/// &destinationInterval, aboveMaxInterval);
122/// assert(maxDestinationInterval == destinationInterval);
123/// @endcode
124/// Next, we try a value less than 0 and observe the result of the saturated
125/// conversion is 0 (the minimum representable value):
126/// @code
127/// bsls::TimeInterval belowMinimumInterval(-1, 0);
128/// bslmt::SaturatedTimeConversionImpUtil::toMillisec(
129/// &destinationInterval, belowMinimumInterval);
130/// assert(0 == destinationInterval);
131/// @endcode
132/// Finally, when we convert a `bsls::TimeInterval` containing a fractional
133/// millisecond using `toMillisec`, the converted value is greater than the
134/// input value:
135/// @code
136/// bsls::TimeInterval piMSec(0, 3141593); // 'pi' millseconds
137/// unsigned int mSec;
138/// bslmt::SaturatedTimeConversionImpUtil::toMillisec(&mSec, piMSec);
139/// assert(4 == mSec);
140/// @endcode
141/// @}
142/** @} */
143/** @} */
144
145/** @addtogroup bsl
146 * @{
147 */
148/** @addtogroup bslmt
149 * @{
150 */
151/** @addtogroup bslmt_saturatedtimeconversionimputil
152 * @{
153 */
154
155#include <bslscm_version.h>
156
157#include <bslmt_platform.h>
158
159#include <bslmf_assert.h>
160#include <bslmf_issame.h>
161
162#include <bsls_platform.h>
163#include <bsls_timeinterval.h>
164#include <bsls_types.h>
165
166#include <bsl_limits.h>
167#include <bsl_ctime.h>
168
169#include <time.h> // POSIX timespec
170
171#ifdef BSLS_PLATFORM_OS_DARWIN
172#include <mach/clock_types.h> // for 'mach_timespec_t'
173#endif
174
175
176namespace bslmt {
177
178 // ====================================
179 // class SaturatedTimeConversionImpUtil
180 // ====================================
181
182/// This `struct` provides a namespace for utility functions that convert
183/// time values between different time representations, and "saturate" when
184/// values are outside the range of values that may be represented in the
185/// destination type (meaning that values above the maximum representable
186/// value of the result type are set to the maximum value of the result
187/// type, and values below the minimum representable value of the result
188/// type are set to the minimum value for the result type).
190
191 // TYPES
192
193 // Here we define type 'TimeSpec' -- an alias to 'timespec' on Unix, but
194 // defined as a struct on Windows, to guarantee that 'TimeSpec' exists on
195 // all platforms.
196
197 /// Provide type for Windows platform
198#ifdef BSLMT_PLATFORM_POSIX_THREADS
199 typedef timespec TimeSpec;
200#else
206#endif
207
208 // CLASS METHODS
209
210#if BSLS_PLATFORM_OS_DARWIN
211 static void toTimeSpec(mach_timespec_t *dst,
212 const bsls::TimeInterval& src);
213#endif
214
215 /// Assign to the specified `dst` the value of the specified `src`, and
216 /// if `src` is less than the lowest representable value of `*dst`, set
217 /// `*dst` to the minimum value it can represent, and if `src` is
218 /// greater than the highest representable value of `*dst`, set `*dst`
219 /// to the maximum value that it can represent.
220 static void toTimeSpec(TimeSpec *dst, const bsls::TimeInterval& src);
221
222 /// Assign to the specified `dst` the value of the specified `src`, and
223 /// if `src` is less than the lowest representable `time_t` value, set
224 /// `dst` to the minimum `time_t` value, and if `src` is greater than
225 /// the highest representable `time_t` value, set `dst` to the maximum
226 /// `time_t` value.
227 static void toTimeT(bsl::time_t *dst, const bsls::Types::Int64 src);
228
229 static void toMillisec(unsigned int *dst,
230 const bsls::TimeInterval& src);
231 static void toMillisec(unsigned long *dst,
232 const bsls::TimeInterval& src);
233 /// Assign to the specified `dst` the value of the specified `src`
234 /// converted to milliseconds, and if that value is a negative time
235 /// interval, set `dst` to 0, and if that value is greater than the
236 /// maximum representable value of `dst` set `dst` to its maximum
237 /// representable value. See {Conversion to Milliseconds}.
239 const bsls::TimeInterval& src);
240};
241
242} // close package namespace
243
244
245#endif
246
247// ----------------------------------------------------------------------------
248// Copyright 2015 Bloomberg Finance L.P.
249//
250// Licensed under the Apache License, Version 2.0 (the "License");
251// you may not use this file except in compliance with the License.
252// You may obtain a copy of the License at
253//
254// http://www.apache.org/licenses/LICENSE-2.0
255//
256// Unless required by applicable law or agreed to in writing, software
257// distributed under the License is distributed on an "AS IS" BASIS,
258// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
259// See the License for the specific language governing permissions and
260// limitations under the License.
261// ----------------------------- END-OF-FILE ----------------------------------
262
263/** @} */
264/** @} */
265/** @} */
Definition bsls_timeinterval.h:301
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslmt_barrier.h:344
Provide type for Windows platform.
Definition bslmt_saturatedtimeconversionimputil.h:201
bsls::Types::Int64 tv_sec
Definition bslmt_saturatedtimeconversionimputil.h:203
int tv_nsec
Definition bslmt_saturatedtimeconversionimputil.h:204
Definition bslmt_saturatedtimeconversionimputil.h:189
static void toTimeSpec(TimeSpec *dst, const bsls::TimeInterval &src)
static void toMillisec(bsls::Types::Uint64 *dst, const bsls::TimeInterval &src)
static void toMillisec(unsigned long *dst, const bsls::TimeInterval &src)
static void toMillisec(unsigned int *dst, const bsls::TimeInterval &src)
static void toTimeT(bsl::time_t *dst, const bsls::Types::Int64 src)
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132