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

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.