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