Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Duration.h Source File

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_