/* mbed Microcontroller Library * Copyright (c) 2018 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BLE_COMMON_DURATION_H_ #define BLE_COMMON_DURATION_H_ #include #include #include "platform/mbed_assert.h" namespace ble { template struct Range { enum { MIN = Min, MAX = Max }; }; template struct DefaultRange; template<> struct DefaultRange { typedef Range<0, 0xFF> type; }; template<> struct DefaultRange { typedef Range<0, 0xFFFF> type; }; template<> struct DefaultRange { typedef Range<0, 0xFFFFFFFF> type; }; template struct Forever { static const uint32_t VALUE = V; }; template< typename Rep, uint32_t TB, typename Range = typename DefaultRange::type, typename Forever = void* > struct Duration { Duration() : duration() { } explicit Duration(Rep v) : duration(clamp(v)) { } template Duration(Duration other) : duration(clamp(other.value() * (OtherTB / TB))) { MBED_STATIC_ASSERT(OtherTB >= TB && (OtherTB % TB) == 0, "Incompatible units"); } template explicit Duration(Duration other_ms, void* = NULL) : duration(clamp(((other_ms.value() * 1000) + TB - 1) / TB)) { } Rep value() { return duration; } enum { TIME_BASE = TB, MIN = Range::MIN, MAX = Range::MAX }; static Duration min() { return Duration(MIN); } static Duration max() { return Duration(MAX); } const Rep* storage() const { return &duration; } static Duration forever() { return Duration(Forever::VALUE); } private: static Rep clamp(Rep in) { if (in < MIN) { return MIN; } else if (in > MAX) { return MAX; } else { return in; } } Rep duration; }; typedef Duration microsecond_t; typedef Duration millisecond_t; typedef Duration second_t; template DurationOut durationCast(Duration duration) { return DurationOut(((duration.value() * TBIn) + DurationOut::TIME_BASE - 1) / DurationOut::TIME_BASE); } // ADDITION OPERATOR template microsecond_t operator+(Duration lhs, Duration rhs) { return microsecond_t((lhs.value() * lhs.TIME_BASE) + (rhs.value() * rhs.TIME_BASE)); } template Duration operator+(Duration lhs, Duration rhs) { return Duration(lhs.value() + rhs.value()); } // MULTIPLICATION OPERATOR template Duration operator*(Duration lhs, uint32_t rhs) { return Duration(lhs.value() * rhs); } template Duration operator*(uint32_t lhs, Duration rhs) { return Duration(lhs * rhs.value()); } // LESS THAN template bool operator<(Duration lhs, Duration rhs) { return lhs.value() * lhs.TIME_BASE < rhs.value() * rhs.TIME_BASE; } template bool operator<(Duration lhs, Duration rhs) { return lhs.value() < rhs.value(); } // LESS OR EQUAL TO template bool operator<=(Duration lhs, Duration rhs) { return lhs.value() * lhs.TIME_BASE <= rhs.value() * rhs.TIME_BASE; } template bool operator<=(Duration lhs, Duration rhs) { return lhs.value() <= rhs.value(); } // EQUAL template bool operator==(Duration lhs, Duration rhs) { return lhs.value() * lhs.TIME_BASE == rhs.value() * rhs.TIME_BASE; } template bool operator==(Duration lhs, Duration rhs) { return lhs.value() == rhs.value(); } // NOT EQUAL template bool operator!=(Duration lhs, Duration rhs) { return !(lhs == rhs); } template bool operator!=(Duration lhs, Duration rhs) { return !(lhs == rhs); } // GREATER OR EQUAL template bool operator>=(Duration lhs, Duration rhs) { return rhs <= lhs; } template bool operator>=(Duration lhs, Duration rhs) { return rhs <= lhs; } // GREATER THAN template bool operator>(Duration lhs, Duration rhs) { return rhs < lhs; } template bool operator>(Duration lhs, Duration rhs) { return rhs < lhs; } /* ---------------------- Static variable initialization -------------------- */ template const uint32_t Forever::VALUE; } #endif //BLE_COMMON_DURATION_H_