Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
Duration.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef BLE_COMMON_DURATION_H_ 00018 #define BLE_COMMON_DURATION_H_ 00019 00020 #include <stdint.h> 00021 #include <stddef.h> 00022 #include "platform/mbed_assert.h" 00023 00024 namespace ble { 00025 00026 #if !defined(DOXYGEN_ONLY) 00027 00028 /** 00029 * Define a compile time range. 00030 * @tparam Min left-bound 00031 * @tparam Max right-bound 00032 */ 00033 template<uint32_t Min, uint32_t Max> 00034 struct Range { 00035 static const uint32_t MIN = Min; 00036 static const uint32_t MAX = Max; 00037 }; 00038 00039 /** 00040 * Deduce default range for C++ basic integer types. 00041 * 00042 * 00043 * @tparam Rep The C++ integer type. 00044 */ 00045 template<typename Rep> 00046 struct DefaultRange; 00047 00048 /** 00049 * DefaultRange specialization for uint8_t. 00050 */ 00051 template<> 00052 struct DefaultRange<uint8_t> { 00053 typedef Range<0, 0xFF> type; 00054 }; 00055 00056 /** 00057 * DefaultRange specialization for uint16_t. 00058 */ 00059 template<> 00060 struct DefaultRange<uint16_t > { 00061 typedef Range<0, 0xFFFF> type; 00062 }; 00063 00064 /** 00065 * DefaultRange specialization for uint32_t 00066 */ 00067 template<> 00068 struct DefaultRange<uint32_t> { 00069 typedef Range<0, 0xFFFFFFFF> type; 00070 }; 00071 00072 /** 00073 * Represent an integral compile time value that can be used in Duration. 00074 * 00075 * @tparam T Type of the integral value. 00076 * @tparam V The integer value representing a never ending duration. 00077 */ 00078 template<typename T, T V> 00079 struct Value { 00080 static const T VALUE = V; 00081 }; 00082 00083 #endif 00084 00085 /** 00086 * Model BLE durations. 00087 * 00088 * @tparam Rep The representation type of the duration. 00089 * @tparam TB The time base in micro seconds. 00090 * @tparam Range Closed interval of the duration 00091 * @tparam Forever The special value (if applicable) that represents a forever 00092 * duration. 00093 */ 00094 template< 00095 typename Rep, 00096 uint32_t TB, 00097 typename Range = typename DefaultRange<Rep>::type, 00098 typename Forever = void* 00099 > 00100 struct Duration { 00101 /** 00102 * Type of the actual representation. 00103 */ 00104 typedef Rep representation_t; 00105 00106 /** 00107 * Construct a default Duration. 00108 * 00109 * It is initialized with the minimum value acceptable. 00110 */ 00111 Duration() : duration(Range::MIN) 00112 { 00113 } 00114 00115 /** 00116 * Construct a Duration from an integer value. 00117 * 00118 * @param v The value of the duration in TIME_BASE units. 00119 */ 00120 explicit Duration(Rep v) : duration(clamp(v)) 00121 { 00122 } 00123 00124 /** 00125 * Construct a Duration from another Duration. 00126 * 00127 * @note The operation fail at compile time if there is a loss of precision. 00128 * 00129 * @tparam OtherRep The type used to represent the other Duration. 00130 * @tparam OtherTB The time base in micro seconds of the other Duration. 00131 * @tparam OtherRange The range of the other Duration. 00132 * @tparam OtherF The forever value of the other type. 00133 * 00134 * @param other The Duration used to construct this object. 00135 */ 00136 template<typename OtherRep, uint32_t OtherTB, typename OtherRange, typename OtherF> 00137 Duration(Duration<OtherRep, OtherTB, OtherRange, OtherF> other) : 00138 duration(clamp(other.value() * (OtherTB / TB))) 00139 { 00140 MBED_STATIC_ASSERT(OtherTB >= TB && (OtherTB % TB) == 0, "Incompatible units"); 00141 } 00142 00143 /** 00144 * Construct a new Duration from a Duration in milliseconds. 00145 * 00146 * @note The result of the conversion is rounded up. 00147 * 00148 * @tparam OtherRep The representation type used by other_ms. 00149 * @tparam OtherRange The range used by other_ms. 00150 * @tparam OtherF The forever value used by other_ms. 00151 * 00152 * @param other_ms The Duration in millisecond to convert. 00153 */ 00154 template<typename OtherRep, typename OtherRange, typename OtherF> 00155 explicit Duration(Duration<OtherRep, 1000, OtherRange, OtherF> other_ms, void* = NULL) : 00156 duration(clamp(((other_ms.value() * 1000) + TB - 1) / TB)) 00157 { 00158 } 00159 00160 /** 00161 * Return the duration in TB units. 00162 * 00163 * @return The duration in TB units. 00164 */ 00165 Rep value() const 00166 { 00167 return duration; 00168 } 00169 00170 /** 00171 * Return the duration in milliseconds. 00172 * 00173 * @return The duration in milliseconds. 00174 */ 00175 uint32_t valueInMs() const 00176 { 00177 return ((uint32_t)duration * TB) / 1000; 00178 } 00179 00180 /** 00181 * The time base. 00182 */ 00183 static const uint32_t TIME_BASE = TB; 00184 00185 /** 00186 * Left-bound of the duration range. 00187 */ 00188 static const Rep MIN = Range::MIN; 00189 00190 /** 00191 * Right bound of the duration range. 00192 */ 00193 static const Rep MAX = Range::MAX; 00194 00195 /** 00196 * Return the minimum duration. 00197 * 00198 * @return The minimum duration. 00199 */ 00200 static Duration min() 00201 { 00202 return Duration(MIN); 00203 } 00204 00205 /** 00206 * Return the maximum duration. 00207 * 00208 * @return The maximum duration. 00209 */ 00210 static Duration max() 00211 { 00212 return Duration(MAX); 00213 } 00214 00215 /** 00216 * Return a pointer to the value of the duration. 00217 * 00218 * @return a pointer to the value of the duration. 00219 */ 00220 const Rep* storage() const 00221 { 00222 return &duration; 00223 } 00224 00225 /** 00226 * Return the Duration value meaning forever. 00227 * @return the Duration value meaning forever. 00228 */ 00229 static Duration forever() 00230 { 00231 return Duration(Forever::VALUE); 00232 } 00233 00234 private: 00235 static Rep clamp(Rep in) 00236 { 00237 if (in < MIN) { 00238 return MIN; 00239 } else if (in > MAX) { 00240 return MAX; 00241 } else { 00242 return in; 00243 } 00244 } 00245 00246 Rep duration; 00247 }; 00248 00249 /** 00250 * Type that represents micro seconds. 00251 */ 00252 typedef Duration<uint32_t, 1> microsecond_t; 00253 00254 /** 00255 * Type that represents milliseconds. 00256 */ 00257 typedef Duration<uint32_t, 1000 * microsecond_t::TIME_BASE> millisecond_t; 00258 00259 /** 00260 * Type that represents seconds. 00261 */ 00262 typedef Duration<uint32_t, 1000 * millisecond_t::TIME_BASE> second_t; 00263 00264 /** 00265 * Cast a duration to another. 00266 * 00267 * @tparam DurationOut Type of the Duration in output. 00268 * @tparam RepIn The representation type of duration. 00269 * @tparam TBIn The timebase of duration. 00270 * @tparam RangeIn The range of duration. 00271 * @tparam FIn The Forever value of duration. 00272 * @param duration The duration to convert. 00273 * @return The converted duration. It is rounded up if precision is lost. 00274 * 00275 * @related Duration 00276 */ 00277 template<typename DurationOut, typename RepIn, uint32_t TBIn, typename RangeIn, typename FIn> 00278 DurationOut durationCast(Duration<RepIn, TBIn, RangeIn, FIn> duration) 00279 { 00280 return DurationOut(((duration.value() * TBIn) + DurationOut::TIME_BASE - 1) / DurationOut::TIME_BASE); 00281 } 00282 00283 /** 00284 * Add two durations together and return the result in microseconds. 00285 * @param lhs Left hand side operand. 00286 * @param rhs Right hand side operand. 00287 * @return The result of the addition of the two durations in microseconds. 00288 * 00289 * @related Duration 00290 */ 00291 template< 00292 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00293 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS> 00294 microsecond_t operator+ ( 00295 Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, 00296 Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs 00297 ) 00298 { 00299 return microsecond_t((lhs.value() * lhs.TIME_BASE) + (rhs.value() * rhs.TIME_BASE)); 00300 } 00301 00302 /** 00303 * Add two durations together. 00304 * @param lhs Left hand side operand. 00305 * @param rhs Right hand side operand. 00306 * @return The addition of the two durations in input. 00307 * 00308 * @related Duration 00309 */ 00310 template<typename Rep, uint32_t TB, typename Range, typename F> 00311 Duration<Rep, TB, Range, F> operator+ ( 00312 Duration<Rep, TB, Range, F> lhs, 00313 Duration<Rep, TB, Range, F> rhs 00314 ) 00315 { 00316 return Duration<Rep, TB, Range, F>(lhs.value() + rhs.value()); 00317 } 00318 00319 /** 00320 * Multiply a duration and a positive integer. 00321 * 00322 * @param lhs The duration. 00323 * @param rhs The integer. 00324 * 00325 * @return A duration that represents the multiplication of lhs with rhs. 00326 * 00327 * @related Duration 00328 */ 00329 template<typename Rep, uint32_t TB, typename Range, typename F> 00330 Duration<Rep, TB, Range, F> operator*(Duration<Rep, TB, Range, F> lhs, uint32_t rhs) 00331 { 00332 return Duration<Rep, TB, Range, F>(lhs.value() * rhs); 00333 } 00334 00335 /** 00336 * Multiply a duration and a positive integer. 00337 * 00338 * @param lhs The integer. 00339 * @param rhs The multiplication. 00340 * 00341 * @return A duration that represents the multiplication of lhs with rhs. 00342 * 00343 * @related Duration 00344 */ 00345 template<typename Rep, uint32_t TB, typename Range, typename F> 00346 Duration<Rep, TB, Range, F> operator*(uint32_t lhs, Duration<Rep, TB, Range, F> rhs) 00347 { 00348 return Duration<Rep, TB, Range, F>(lhs * rhs.value()); 00349 } 00350 00351 /** 00352 * Indicate if the duration lhs is less than the duration rhs. 00353 * @param lhs Left hand side operand. 00354 * @param rhs Right hand side operand. 00355 * @return true if lhs is less than rhs and false otherwise. 00356 * 00357 * @related Duration 00358 */ 00359 template< 00360 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00361 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS 00362 > 00363 bool operator<(Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs) 00364 { 00365 return lhs.value() * lhs.TIME_BASE < rhs.value() * rhs.TIME_BASE; 00366 } 00367 00368 /** 00369 * Indicate if the duration lhs is less than the duration rhs. 00370 * @param lhs Left hand side operand. 00371 * @param rhs Right hand side operand. 00372 * @return true if lhs is less than rhs and false otherwise. 00373 * 00374 * @related Duration 00375 */ 00376 template<typename Rep, uint32_t Us, typename Range, typename F> 00377 bool operator<(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs) 00378 { 00379 return lhs.value() < rhs.value(); 00380 } 00381 00382 /** 00383 * Indicate if the duration lhs is less than or equal to the duration rhs. 00384 * @param lhs Left hand side operand. 00385 * @param rhs Right hand side operand. 00386 * @return true if lhs is less than or equal to rhs and false otherwise. 00387 * 00388 * @related Duration 00389 */ 00390 template< 00391 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00392 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS 00393 > 00394 bool operator<=( 00395 Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, 00396 Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs 00397 ) 00398 { 00399 return lhs.value() * lhs.TIME_BASE <= rhs.value() * rhs.TIME_BASE; 00400 } 00401 00402 /** 00403 * Indicate if the duration lhs is less than or equal to the duration rhs. 00404 * @param lhs Left hand side operand. 00405 * @param rhs Right hand side operand. 00406 * @return true if lhs is less than or equal to rhs and false otherwise. 00407 * 00408 * @related Duration 00409 */ 00410 template<typename Rep, uint32_t Us, typename Range> 00411 bool operator<=(Duration<Rep, Us, Range> lhs, Duration<Rep, Us, Range> rhs) 00412 { 00413 return lhs.value() <= rhs.value(); 00414 } 00415 00416 /** 00417 * Indicate if the duration lhs is equal to the duration rhs. 00418 * @param lhs Left hand side operand. 00419 * @param rhs Right hand side operand. 00420 * @return true if lhs is equal to rhs and false otherwise. 00421 * 00422 * @related Duration 00423 */ 00424 template< 00425 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00426 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS 00427 > 00428 bool operator==( 00429 Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, 00430 Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs 00431 ) 00432 { 00433 return lhs.value() * lhs.TIME_BASE == rhs.value() * rhs.TIME_BASE; 00434 } 00435 00436 /** 00437 * Indicate if the duration lhs is equal to the duration rhs. 00438 * @param lhs Left hand side operand. 00439 * @param rhs Right hand side operand. 00440 * @return true if lhs is equal to rhs and false otherwise. 00441 * 00442 * @related Duration 00443 */ 00444 template<typename Rep, uint32_t Us, typename Range, typename F> 00445 bool operator==(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs) 00446 { 00447 return lhs.value() == rhs.value(); 00448 } 00449 00450 /** 00451 * Indicate if the duration lhs is not equal to the duration rhs. 00452 * @param lhs Left hand side operand. 00453 * @param rhs Right hand side operand. 00454 * @return true if lhs is not equal to rhs and false otherwise. 00455 * 00456 * @related Duration 00457 */ 00458 template< 00459 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00460 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS 00461 > 00462 bool operator!=( 00463 Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, 00464 Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs 00465 ) 00466 { 00467 return !(lhs == rhs); 00468 } 00469 00470 /** 00471 * Indicate if the duration lhs is not equal to the duration rhs. 00472 * @param lhs Left hand side operand. 00473 * @param rhs Right hand side operand. 00474 * @return true if lhs is not equal to rhs and false otherwise. 00475 * 00476 * @related Duration 00477 */ 00478 template<typename Rep, uint32_t Us, typename Range, typename F> 00479 bool operator!=(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs) 00480 { 00481 return !(lhs == rhs); 00482 } 00483 00484 /** 00485 * Indicate if the duration lhs greater or equal to the duration rhs. 00486 * @param lhs Left hand side operand. 00487 * @param rhs Right hand side operand. 00488 * @return true if lhs is greater or equal to rhs and false otherwise. 00489 * 00490 * @related Duration 00491 */ 00492 template< 00493 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00494 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS 00495 > 00496 bool operator>=( 00497 Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, 00498 Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs 00499 ) 00500 { 00501 return rhs <= lhs; 00502 } 00503 00504 /** 00505 * Indicate if the duration lhs greater or equal to the duration rhs. 00506 * @param lhs Left hand side operand. 00507 * @param rhs Right hand side operand. 00508 * @return true if lhs is greater or equal to rhs and false otherwise. 00509 * 00510 * @related Duration 00511 */ 00512 template<typename Rep, uint32_t Us, typename Range, typename F> 00513 bool operator>=(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs) 00514 { 00515 return rhs <= lhs; 00516 } 00517 00518 /** 00519 * Indicate if the duration lhs greater than the duration rhs. 00520 * @param lhs Left hand side operand. 00521 * @param rhs Right hand side operand. 00522 * @return true if lhs is greater than rhs and false otherwise. 00523 * 00524 * @related Duration 00525 */ 00526 template< 00527 typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS, 00528 typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS 00529 > 00530 bool operator>( 00531 Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, 00532 Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs 00533 ) 00534 { 00535 return rhs < lhs; 00536 } 00537 00538 /** 00539 * Indicate if the duration lhs greater than the duration rhs. 00540 * @param lhs Left hand side operand. 00541 * @param rhs Right hand side operand. 00542 * @return true if lhs is greater than rhs and false otherwise. 00543 * 00544 * @related Duration 00545 */ 00546 template<typename Rep, uint32_t Us, typename Range, typename F> 00547 bool operator>(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs) 00548 { 00549 return rhs < lhs; 00550 } 00551 00552 /* ---------------------- Static variable initialization -------------------- */ 00553 00554 #if !defined(DOXYGEN_ONLY) 00555 00556 template<uint32_t Min, uint32_t Max> 00557 const uint32_t Range<Min, Max>::MIN; 00558 00559 template<uint32_t Min, uint32_t Max> 00560 const uint32_t Range<Min, Max>::MAX; 00561 00562 template<typename T, T V> 00563 const T Value<T, V>::VALUE; 00564 00565 #endif 00566 00567 template<typename Rep, uint32_t TB, typename Range, typename Forever> 00568 const uint32_t Duration<Rep, TB, Range, Forever>::TIME_BASE; 00569 00570 template<typename Rep, uint32_t TB, typename Range, typename Forever> 00571 const Rep Duration<Rep, TB, Range, Forever>::MIN; 00572 00573 template<typename Rep, uint32_t TB, typename Range, typename Forever> 00574 const Rep Duration<Rep, TB, Range, Forever>::MAX; 00575 00576 } 00577 00578 #endif //BLE_COMMON_DURATION_H_
Generated on Tue Jul 12 2022 13:54:17 by
