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