Mbed OS Reference
Loading...
Searching...
No Matches
Duration.h
1/* mbed Microcontroller Library
2 * Copyright (c) 2006-2020 ARM Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#ifndef BLE_COMMON_DURATION_H_
20#define BLE_COMMON_DURATION_H_
21
22#include <cstdint>
23#include <cstddef>
24#include "platform/mbed_assert.h"
25#include "platform/mbed_chrono.h"
26
27namespace ble {
28
29#if !defined(DOXYGEN_ONLY)
30
31/**
32 * Define a compile time range.
33 * @tparam Min left-bound
34 * @tparam Max right-bound
35 */
36template<uint32_t Min, uint32_t Max, uint32_t Default = Min>
37struct Range {
38 static const uint32_t MIN = Min;
39 static const uint32_t MAX = Max;
40 static const uint32_t DEFAULT = Default;
41};
42
43/**
44 * Deduce default range for C++ basic integer types.
45 *
46 *
47 * @tparam Rep The C++ integer type.
48 */
49template<typename Rep>
50struct DefaultRange;
51
52/**
53 * DefaultRange specialization for uint8_t.
54 */
55template<>
56struct DefaultRange<uint8_t> {
57 typedef Range<0, 0xFF> type;
58};
59
60/**
61 * DefaultRange specialization for uint16_t.
62 */
63template<>
64struct DefaultRange<uint16_t > {
65 typedef Range<0, 0xFFFF> type;
66};
67
68/**
69 * DefaultRange specialization for uint32_t
70 */
71template<>
72struct DefaultRange<uint32_t> {
73 typedef Range<0, 0xFFFFFFFF> type;
74};
75
76/**
77 * Represent an integral compile time value that can be used in Duration.
78 *
79 * @tparam T Type of the integral value.
80 * @tparam V The integer value representing a never ending duration.
81 */
82template<typename T, T V>
83struct Value {
84 static const T VALUE = V;
85};
86
87#endif
88
89/**
90 * Model BLE durations.
91 *
92 * @tparam Rep The representation type of the duration.
93 * @tparam TB The time base in micro seconds.
94 * @tparam Range Closed interval of the duration
95 * @tparam Forever The special value (if applicable) that represents a forever
96 * duration.
97 */
98template<
99 typename Rep,
100 uint32_t TB,
101 typename Range = typename DefaultRange<Rep>::type,
102 typename Forever = void*
103>
104struct Duration {
105 /**
106 * Type of the actual representation.
107 */
108 typedef Rep representation_t;
109
110 /**
111 * Construct a default Duration.
112 *
113 * It is initialized with the minimum value acceptable.
114 */
115 Duration() : duration(Range::DEFAULT)
116 {
117 }
118
119 /**
120 * Construct a Duration from an integer value.
121 *
122 * @param v The value of the duration in TIME_BASE units.
123 */
124 explicit Duration(Rep v) : duration(clamp(v))
125 {
126 }
127
128 /**
129 * Construct a Duration from another Duration.
130 *
131 * @note The operation fail at compile time if there is a loss of precision.
132 *
133 * @tparam OtherRep The type used to represent the other Duration.
134 * @tparam OtherTB The time base in micro seconds of the other Duration.
135 * @tparam OtherRange The range of the other Duration.
136 * @tparam OtherF The forever value of the other type.
137 *
138 * @param other The Duration used to construct this object.
139 */
140 template<typename OtherRep, uint32_t OtherTB, typename OtherRange, typename OtherF>
142 duration(clamp(other.value() * (OtherTB / TB)))
143 {
144 static_assert(OtherTB >= TB && (OtherTB % TB) == 0, "Incompatible units");
145 }
146
147 /**
148 * Construct a new Duration from a Duration in milliseconds.
149 *
150 * @note The result of the conversion is rounded up.
151 *
152 * @tparam OtherRep The representation type used by other_ms.
153 * @tparam OtherRange The range used by other_ms.
154 * @tparam OtherF The forever value used by other_ms.
155 *
156 * @param other_ms The Duration in millisecond to convert.
157 */
158 template<typename OtherRep, typename OtherRange, typename OtherF>
159 explicit Duration(Duration<OtherRep, 1000, OtherRange, OtherF> other_ms, void* = nullptr) :
160 duration(clamp(((other_ms.value() * 1000) + TB - 1) / TB))
161 {
162 }
163
164 /**
165 * Return the duration in TB units.
166 *
167 * @return The duration in TB units.
168 */
169 Rep value() const
170 {
171 return duration;
172 }
173
174 /**
175 * Return the duration in milliseconds.
176 *
177 * @return The duration in milliseconds.
178 */
179 uint32_t valueInMs() const
180 {
181 return ((uint32_t)duration * TB) / 1000;
182 }
183
184 /**
185 * The time base.
186 */
187 static const uint32_t TIME_BASE = TB;
188
189 /**
190 * Left-bound of the duration range.
191 */
192 static const Rep MIN = Range::MIN;
193
194 /**
195 * Right bound of the duration range.
196 */
197 static const Rep MAX = Range::MAX;
198
199 /**
200 * Return the minimum duration.
201 *
202 * @return The minimum duration.
203 */
204 static Duration min()
205 {
206 return Duration(MIN);
207 }
208
209 /**
210 * Return the maximum duration.
211 *
212 * @return The maximum duration.
213 */
214 static Duration max()
215 {
216 return Duration(MAX);
217 }
218
219 /**
220 * Return a pointer to the value of the duration.
221 *
222 * @return a pointer to the value of the duration.
223 */
224 const Rep* storage() const
225 {
226 return &duration;
227 }
228
229 /**
230 * Return the Duration value meaning forever.
231 * @return the Duration value meaning forever.
232 */
234 {
235 return Duration(Forever::VALUE);
236 }
237
238#if defined(DOXYGEN_ONLY)
239 /**
240 * Test if the forever value is being held
241 * @return True if the forever value is held False otherwise
242 */
243 bool isForever() const;
244#else
245 // Overload when Forever isn't defined
246 template<typename DefaultForever = void*>
247 std::enable_if_t<
248 std::is_same<DefaultForever, Forever>::value,
249 bool
250 >
251 isForever() const
252 {
253 return false;
254 }
255
256 // Overload when Forever is defined
257 template<typename DefaultForever = void*>
258 std::enable_if_t<
259 !std::is_same<DefaultForever, Forever>::value,
260 bool
261 >
262 isForever() const
263 {
264 return duration == Forever::VALUE;
265 }
266#endif
267
268 /**
269 * Convert the duration into an std::chrono one.
270 * @return The duration in the std::chrono format.
271 */
272 std::chrono::duration<Rep, typename std::ratio<TB, 1000000>::type>
274 {
276
277 return std::chrono::duration<Rep, typename std::ratio<TB, 1000000>::type>{duration};
278 }
279
280private:
281 static Rep clamp(Rep in)
282 {
283 if (in < MIN) {
284 return MIN;
285 } else if (in > MAX) {
286 return MAX;
287 } else {
288 return in;
289 }
290 }
291
292 Rep duration;
293};
294
295/**
296 * Type that represents micro seconds.
297 */
299
300/**
301 * Type that represents milliseconds.
302 */
304
305/**
306 * Type that represents seconds.
307 */
309
310/**
311 * Cast a duration to another.
312 *
313 * @tparam DurationOut Type of the Duration in output.
314 * @tparam RepIn The representation type of duration.
315 * @tparam TBIn The timebase of duration.
316 * @tparam RangeIn The range of duration.
317 * @tparam FIn The Forever value of duration.
318 * @param duration The duration to convert.
319 * @return The converted duration. It is rounded up if precision is lost.
320 *
321 * @related Duration
322 */
323template<typename DurationOut, typename RepIn, uint32_t TBIn, typename RangeIn, typename FIn>
325{
326 return DurationOut(((duration.value() * TBIn) + DurationOut::TIME_BASE - 1) / DurationOut::TIME_BASE);
327}
328
329/**
330 * Add two durations together and return the result in microseconds.
331 * @param lhs Left hand side operand.
332 * @param rhs Right hand side operand.
333 * @return The result of the addition of the two durations in microseconds.
334 *
335 * @related Duration
336 */
337template<
338 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
339 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS>
343)
344{
345 return microsecond_t((lhs.value() * lhs.TIME_BASE) + (rhs.value() * rhs.TIME_BASE));
346}
347
348/**
349 * Add two durations together.
350 * @param lhs Left hand side operand.
351 * @param rhs Right hand side operand.
352 * @return The addition of the two durations in input.
353 *
354 * @related Duration
355 */
356template<typename Rep, uint32_t TB, typename Range, typename F>
360)
361{
362 return Duration<Rep, TB, Range, F>(lhs.value() + rhs.value());
363}
364
365/**
366 * Multiply a duration and a positive integer.
367 *
368 * @param lhs The duration.
369 * @param rhs The integer.
370 *
371 * @return A duration that represents the multiplication of lhs with rhs.
372 *
373 * @related Duration
374 */
375template<typename Rep, uint32_t TB, typename Range, typename F>
377{
378 return Duration<Rep, TB, Range, F>(lhs.value() * rhs);
379}
380
381/**
382 * Multiply a duration and a positive integer.
383 *
384 * @param lhs The integer.
385 * @param rhs The multiplication.
386 *
387 * @return A duration that represents the multiplication of lhs with rhs.
388 *
389 * @related Duration
390 */
391template<typename Rep, uint32_t TB, typename Range, typename F>
393{
394 return Duration<Rep, TB, Range, F>(lhs * rhs.value());
395}
396
397/**
398 * Indicate if the duration lhs is less than the duration rhs.
399 * @param lhs Left hand side operand.
400 * @param rhs Right hand side operand.
401 * @return true if lhs is less than rhs and false otherwise.
402 *
403 * @related Duration
404 */
405template<
406 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
407 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
408>
410{
411 return lhs.value() * lhs.TIME_BASE < rhs.value() * rhs.TIME_BASE;
412}
413
414/**
415 * Indicate if the duration lhs is less than the duration rhs.
416 * @param lhs Left hand side operand.
417 * @param rhs Right hand side operand.
418 * @return true if lhs is less than rhs and false otherwise.
419 *
420 * @related Duration
421 */
422template<typename Rep, uint32_t Us, typename Range, typename F>
424{
425 return lhs.value() < rhs.value();
426}
427
428/**
429 * Indicate if the duration lhs is less than or equal to the duration rhs.
430 * @param lhs Left hand side operand.
431 * @param rhs Right hand side operand.
432 * @return true if lhs is less than or equal to rhs and false otherwise.
433 *
434 * @related Duration
435 */
436template<
437 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
438 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
439>
443)
444{
445 return lhs.value() * lhs.TIME_BASE <= rhs.value() * rhs.TIME_BASE;
446}
447
448/**
449 * Indicate if the duration lhs is less than or equal to the duration rhs.
450 * @param lhs Left hand side operand.
451 * @param rhs Right hand side operand.
452 * @return true if lhs is less than or equal to rhs and false otherwise.
453 *
454 * @related Duration
455 */
456template<typename Rep, uint32_t Us, typename Range>
458{
459 return lhs.value() <= rhs.value();
460}
461
462/**
463 * Indicate if the duration lhs is equal to the duration rhs.
464 * @param lhs Left hand side operand.
465 * @param rhs Right hand side operand.
466 * @return true if lhs is equal to rhs and false otherwise.
467 *
468 * @related Duration
469 */
470template<
471 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
472 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
473>
477)
478{
479 return lhs.value() * lhs.TIME_BASE == rhs.value() * rhs.TIME_BASE;
480}
481
482/**
483 * Indicate if the duration lhs is equal to the duration rhs.
484 * @param lhs Left hand side operand.
485 * @param rhs Right hand side operand.
486 * @return true if lhs is equal to rhs and false otherwise.
487 *
488 * @related Duration
489 */
490template<typename Rep, uint32_t Us, typename Range, typename F>
492{
493 return lhs.value() == rhs.value();
494}
495
496/**
497 * Indicate if the duration lhs is not equal to the duration rhs.
498 * @param lhs Left hand side operand.
499 * @param rhs Right hand side operand.
500 * @return true if lhs is not equal to rhs and false otherwise.
501 *
502 * @related Duration
503 */
504template<
505 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
506 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
507>
511)
512{
513 return !(lhs == rhs);
514}
515
516/**
517 * Indicate if the duration lhs is not equal to the duration rhs.
518 * @param lhs Left hand side operand.
519 * @param rhs Right hand side operand.
520 * @return true if lhs is not equal to rhs and false otherwise.
521 *
522 * @related Duration
523 */
524template<typename Rep, uint32_t Us, typename Range, typename F>
526{
527 return !(lhs == rhs);
528}
529
530/**
531 * Indicate if the duration lhs greater or equal to the duration rhs.
532 * @param lhs Left hand side operand.
533 * @param rhs Right hand side operand.
534 * @return true if lhs is greater or equal to rhs and false otherwise.
535 *
536 * @related Duration
537 */
538template<
539 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
540 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
541>
545)
546{
547 return rhs <= lhs;
548}
549
550/**
551 * Indicate if the duration lhs greater or equal to the duration rhs.
552 * @param lhs Left hand side operand.
553 * @param rhs Right hand side operand.
554 * @return true if lhs is greater or equal to rhs and false otherwise.
555 *
556 * @related Duration
557 */
558template<typename Rep, uint32_t Us, typename Range, typename F>
560{
561 return rhs <= lhs;
562}
563
564/**
565 * Indicate if the duration lhs greater than the duration rhs.
566 * @param lhs Left hand side operand.
567 * @param rhs Right hand side operand.
568 * @return true if lhs is greater than rhs and false otherwise.
569 *
570 * @related Duration
571 */
572template<
573 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
574 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
575>
579)
580{
581 return rhs < lhs;
582}
583
584/**
585 * Indicate if the duration lhs greater than the duration rhs.
586 * @param lhs Left hand side operand.
587 * @param rhs Right hand side operand.
588 * @return true if lhs is greater than rhs and false otherwise.
589 *
590 * @related Duration
591 */
592template<typename Rep, uint32_t Us, typename Range, typename F>
594{
595 return rhs < lhs;
596}
597
598/* ---------------------- Static variable initialization -------------------- */
599
600#if !defined(DOXYGEN_ONLY)
601
602template<uint32_t Min, uint32_t Max, uint32_t Default>
603const uint32_t Range<Min, Max, Default>::MIN;
604
605template<uint32_t Min, uint32_t Max, uint32_t Default>
606const uint32_t Range<Min, Max, Default>::MAX;
607
608template<uint32_t Min, uint32_t Max, uint32_t Default>
609const uint32_t Range<Min, Max, Default>::DEFAULT;
610
611template<typename T, T V>
612const T Value<T, V>::VALUE;
613
614#endif
615
616template<typename Rep, uint32_t TB, typename Range, typename Forever>
618
619template<typename Rep, uint32_t TB, typename Range, typename Forever>
621
622template<typename Rep, uint32_t TB, typename Range, typename Forever>
624
625}
626
627#endif //BLE_COMMON_DURATION_H_
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:66
Entry namespace for all BLE API definitions.
Duration< uint32_t, 1000 *millisecond_t::TIME_BASE > second_t
Type that represents seconds.
Definition: Duration.h:308
Duration< uint32_t, 1 > microsecond_t
Type that represents micro seconds.
Definition: Duration.h:298
Duration< uint32_t, 1000 *microsecond_t::TIME_BASE > millisecond_t
Type that represents milliseconds.
Definition: Duration.h:303
Model BLE durations.
Definition: Duration.h:104
Duration< Rep, TB, Range, F > operator+(Duration< Rep, TB, Range, F > lhs, Duration< Rep, TB, Range, F > rhs)
Add two durations together.
Definition: Duration.h:357
static const uint32_t TIME_BASE
The time base.
Definition: Duration.h:187
std::chrono::duration< Rep, typename std::ratio< TB, 1000000 >::type > valueChrono() const
Convert the duration into an std::chrono one.
Definition: Duration.h:273
bool operator!=(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Indicate if the duration lhs is not equal to the duration rhs.
Definition: Duration.h:508
DurationOut durationCast(Duration< RepIn, TBIn, RangeIn, FIn > duration)
Cast a duration to another.
Definition: Duration.h:324
bool operator<=(Duration< Rep, Us, Range > lhs, Duration< Rep, Us, Range > rhs)
Indicate if the duration lhs is less than or equal to the duration rhs.
Definition: Duration.h:457
bool operator<(Duration< Rep, Us, Range, F > lhs, Duration< Rep, Us, Range, F > rhs)
Indicate if the duration lhs is less than the duration rhs.
Definition: Duration.h:423
static const Rep MIN
Left-bound of the duration range.
Definition: Duration.h:192
Rep value() const
Return the duration in TB units.
Definition: Duration.h:169
static const Rep MAX
Right bound of the duration range.
Definition: Duration.h:197
Duration(Duration< OtherRep, OtherTB, OtherRange, OtherF > other)
Construct a Duration from another Duration.
Definition: Duration.h:141
bool operator==(Duration< Rep, Us, Range, F > lhs, Duration< Rep, Us, Range, F > rhs)
Indicate if the duration lhs is equal to the duration rhs.
Definition: Duration.h:491
Duration< Rep, TB, Range, F > operator*(Duration< Rep, TB, Range, F > lhs, uint32_t rhs)
Multiply a duration and a positive integer.
Definition: Duration.h:376
bool operator==(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Indicate if the duration lhs is equal to the duration rhs.
Definition: Duration.h:474
static Duration min()
Return the minimum duration.
Definition: Duration.h:204
bool operator>=(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Indicate if the duration lhs greater or equal to the duration rhs.
Definition: Duration.h:542
Duration(Rep v)
Construct a Duration from an integer value.
Definition: Duration.h:124
bool operator>(Duration< Rep, Us, Range, F > lhs, Duration< Rep, Us, Range, F > rhs)
Indicate if the duration lhs greater than the duration rhs.
Definition: Duration.h:593
static Duration max()
Return the maximum duration.
Definition: Duration.h:214
const Rep * storage() const
Return a pointer to the value of the duration.
Definition: Duration.h:224
Duration< Rep, TB, Range, F > operator*(uint32_t lhs, Duration< Rep, TB, Range, F > rhs)
Multiply a duration and a positive integer.
Definition: Duration.h:392
bool operator>(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Indicate if the duration lhs greater than the duration rhs.
Definition: Duration.h:576
uint32_t valueInMs() const
Return the duration in milliseconds.
Definition: Duration.h:179
bool operator!=(Duration< Rep, Us, Range, F > lhs, Duration< Rep, Us, Range, F > rhs)
Indicate if the duration lhs is not equal to the duration rhs.
Definition: Duration.h:525
bool isForever() const
Test if the forever value is being held.
microsecond_t operator+(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Add two durations together and return the result in microseconds.
Definition: Duration.h:340
Rep representation_t
Type of the actual representation.
Definition: Duration.h:108
Duration()
Construct a default Duration.
Definition: Duration.h:115
Duration(Duration< OtherRep, 1000, OtherRange, OtherF > other_ms, void *=nullptr)
Construct a new Duration from a Duration in milliseconds.
Definition: Duration.h:159
bool operator<(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Indicate if the duration lhs is less than the duration rhs.
Definition: Duration.h:409
bool operator>=(Duration< Rep, Us, Range, F > lhs, Duration< Rep, Us, Range, F > rhs)
Indicate if the duration lhs greater or equal to the duration rhs.
Definition: Duration.h:559
bool operator<=(Duration< RepLHS, TBLHS, RangeLHS, FLHS > lhs, Duration< RepRHS, TBRHS, RangeRHS, FRHS > rhs)
Indicate if the duration lhs is less than or equal to the duration rhs.
Definition: Duration.h:440
static Duration forever()
Return the Duration value meaning forever.
Definition: Duration.h:233