Blame view

RIOT/sys/cpp11-compat/include/riot/chrono.hpp 3.49 KB
a752c7ab   elopes   add first test an...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  /*
   * Copyright (C) 2015 Hamburg University of Applied Sciences (HAW)
   *
   * This file is subject to the terms and conditions of the GNU Lesser
   * General Public License v2.1. See the file LICENSE in the top level
   * directory for more details.
   */
  
  /**
   * @ingroup cpp11-compat
   * @{
   *
   * @file
   * @brief  C++11 chrono drop in replacement that adds the function now based on
   *         xtimer/timex
   * @see    <a href="http://en.cppreference.com/w/cpp/thread/thread">
   *           std::thread, defined in header thread
   *         </a>
   *
   * @author Raphael Hiesgen <raphael.hiesgen (at) haw-hamburg.de>
   *
   * @}
   */
  
  #ifndef RIOT_CHRONO_HPP
  #define RIOT_CHRONO_HPP
  
  #include <chrono>
  #include <algorithm>
  
  #include "time.h"
  #include "xtimer.h"
  
  namespace riot {
  
  namespace {
  constexpr uint32_t microsecs_in_sec = 1000000;
  } // namespace anaonymous
  
  /**
   * @brief A time point for timed wait, as clocks from the standard are not
   *        available on RIOT.
   */
  class time_point {
    using native_handle_type = timex_t;
  
   public:
    /**
     * @brief Creates a time point with seconds and microseconds set to 0.
     */
    inline time_point() : m_handle{0, 0} {}
    /**
     * @brief Create time point from timex_t struct.
     */
    explicit inline time_point(timex_t&& tp) : m_handle(tp) {}
    /**
     * @brief Use default copy constructor.
     */
    constexpr time_point(const time_point& tp) = default;
    /**
     * @brief Use default move constructor.
     */
    constexpr time_point(time_point&& tp) = default;
  
    /**
     * @brief Gives access to the native handle that stores the time information.
     */
    inline native_handle_type native_handle() const { return m_handle; }
  
    /**
     * @brief Add a standard chrono::duration to this time point.
     */
    template <class Rep, class Period>
    inline time_point& operator+=(const std::chrono::duration<Rep, Period>& d) {
      auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
      auto m = (std::chrono::duration_cast<std::chrono::microseconds>(d) - s);
      m_handle.seconds += s.count();
      m_handle.microseconds += m.count();
      adjust_overhead();
      return *this;
    }
  
    /**
     * @brief Returns seconds member as uint32_t.
     */
    inline uint32_t seconds() const { return m_handle.seconds; }
  
    /**
     * @brief Returns microseconds member as uint32_t.
     */
    inline uint32_t microseconds() const { return m_handle.microseconds; }
  
   private:
    timex_t m_handle;
    void inline adjust_overhead() {
      auto secs = m_handle.microseconds / microsecs_in_sec;
      m_handle.seconds += secs;
      m_handle.microseconds -= (secs * microsecs_in_sec);
    }
  };
  
  /**
   * @brief Returns the current time saved in a time point.
   *
   * @return time_point containing the current time.
   */
  inline time_point now() {
    timex_t tp;
    xtimer_now_timex(&tp);
    return time_point(std::move(tp));
  }
  
  /**
   * @brief Compares two timepoints.
   */
  inline bool operator<(const time_point& lhs, const time_point& rhs) {
    return lhs.seconds() < rhs.seconds()
           || (lhs.seconds() == rhs.seconds() && lhs.microseconds()
                                                 < rhs.microseconds());
  }
  
  /**
   * @brief Compares two timepoints.
   */
  inline bool operator>(const time_point& lhs, const time_point& rhs) {
    return rhs < lhs;
  }
  
  /**
   * @brief Compares two timepoints.
   */
  inline bool operator<=(const time_point& lhs, const time_point& rhs) {
    return !(rhs < lhs);
  }
  
  /**
   * @brief Compare two timepoints.
   */
  inline bool operator>=(const time_point& lhs, const time_point& rhs) {
    return !(lhs < rhs);
  }
  
  } // namespace riot
  
  #endif // RIOT_CHRONO_HPP