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, uint32_t Default = Min>
37 struct 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  */
49 template<typename Rep>
50 struct DefaultRange;
51 
52 /**
53  * DefaultRange specialization for uint8_t.
54  */
55 template<>
56 struct DefaultRange<uint8_t> {
57  typedef Range<0, 0xFF> type;
58 };
59 
60 /**
61  * DefaultRange specialization for uint16_t.
62  */
63 template<>
64 struct DefaultRange<uint16_t > {
65  typedef Range<0, 0xFFFF> type;
66 };
67 
68 /**
69  * DefaultRange specialization for uint32_t
70  */
71 template<>
72 struct 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  */
82 template<typename T, T V>
83 struct 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  */
98 template<
99  typename Rep,
100  uint32_t TB,
101  typename Range = typename DefaultRange<Rep>::type,
102  typename Forever = void*
103 >
104 struct 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  */
233  static Duration forever()
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>
273  valueChrono() const
274  {
275  MBED_ASSERT(!isForever());
276 
277  return std::chrono::duration<Rep, typename std::ratio<TB, 1000000>::type>{duration};
278  }
279 
280 private:
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  */
323 template<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  */
337 template<
338  typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
339  typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS>
340 microsecond_t operator+(
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  */
356 template<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  */
375 template<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  */
391 template<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  */
405 template<
406  typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
407  typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
408 >
409 bool operator<(Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs)
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  */
422 template<typename Rep, uint32_t Us, typename Range, typename F>
423 bool operator<(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
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  */
436 template<
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  */
456 template<typename Rep, uint32_t Us, typename Range>
457 bool operator<=(Duration<Rep, Us, Range> lhs, Duration<Rep, Us, Range> rhs)
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  */
470 template<
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  */
490 template<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  */
504 template<
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  */
524 template<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  */
538 template<
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  */
558 template<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  */
572 template<
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  */
592 template<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 
602 template<uint32_t Min, uint32_t Max, uint32_t Default>
603 const uint32_t Range<Min, Max, Default>::MIN;
604 
605 template<uint32_t Min, uint32_t Max, uint32_t Default>
606 const uint32_t Range<Min, Max, Default>::MAX;
607 
608 template<uint32_t Min, uint32_t Max, uint32_t Default>
609 const uint32_t Range<Min, Max, Default>::DEFAULT;
610 
611 template<typename T, T V>
612 const T Value<T, V>::VALUE;
613 
614 #endif
615 
616 template<typename Rep, uint32_t TB, typename Range, typename Forever>
618 
619 template<typename Rep, uint32_t TB, typename Range, typename Forever>
621 
622 template<typename Rep, uint32_t TB, typename Range, typename Forever>
624 
625 }
626 
627 #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:357
DurationOut durationCast(Duration< RepIn, TBIn, RangeIn, FIn > duration)
Cast a duration to another.
Definition: Duration.h:324
static Duration forever()
Return the Duration value meaning forever.
Definition: Duration.h:233
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< uint32_t, 1000 *millisecond_t::TIME_BASE > second_t
Type that represents seconds.
Definition: Duration.h:308
Rep value() const
Return the duration in TB units.
Definition: Duration.h:169
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
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
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
#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:214
uint32_t valueInMs() const
Return the duration in milliseconds.
Definition: Duration.h:179
Duration< uint32_t, 1000 *microsecond_t::TIME_BASE > millisecond_t
Type that represents milliseconds.
Definition: Duration.h:303
static const uint32_t TIME_BASE
The time base.
Definition: Duration.h:187
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< 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 v)
Construct a Duration from an integer value.
Definition: Duration.h:124
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
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:66
const Rep * storage() const
Return a pointer to the value of the duration.
Definition: Duration.h:224
#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:141
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
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
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
Duration()
Construct a default Duration.
Definition: Duration.h:115
Rep representation_t
Type of the actual representation.
Definition: Duration.h:108
static Duration min()
Return the minimum duration.
Definition: Duration.h:204
Entry namespace for all BLE API definitions.
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
Duration< uint32_t, 1 > microsecond_t
Type that represents micro seconds.
Definition: Duration.h:298
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
Duration(Duration< OtherRep, 1000, OtherRange, OtherF > other_ms, void *=nullptr)
Construct a new Duration from a Duration in milliseconds.
Definition: Duration.h:159
Model BLE durations.
Definition: Duration.h:104
std::chrono::duration< Rep, typename std::ratio< TB, 1000000 >::type > valueChrono() const
Convert the duration into an std::chrono one.
Definition: Duration.h:273
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.