1#include <iostream>
2#include <chrono>
3#include <ratio>
4
5// In NDK GCC 4.6 and below, "steady_clock" is called "monotonic_clock",
6// and "is_steady" is called "is_monotonic".  One may be tempted to use
7// __GLIBCXX__ to detect it by doing
8//
9//   # if __GLIBCXX__ < 20120920  /* 20120920 is the date of gcc-4.7 in NDK */
10//
11// But __GLIBCXX__ get date from gcc/DATESTAMP.  Although it never changes
12// (so far) once deposit in toolchain/gcc.git, it gets daily bump in upstream.
13// Thus, this approach may not work in other gcc release.
14//
15// We can detect it by
16//
17//     #if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
18//
19// But unfortunately clang uses gcc libstdc++ w/o defining __GNUC__ at all.
20// Since clang now sides with gcc-4.7, we need the following intead
21//
22//     #if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(__clang__))
23//
24// This approach won't be valid if clang sides with gcc4.6 (in standalone mode, for
25// example).
26//
27// ToDo: better approach
28
29#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(__clang__))
30namespace std {
31namespace chrono {
32    typedef monotonic_clock steady_clock;
33}
34}
35#define is_steady is_monotonic
36#endif
37
38template <typename C>
39void printClockData (bool &is_high_res, bool &is_steady)
40{
41    using namespace std;
42
43    cout << "- precision: ";
44    // if time unit is less or equal one millisecond
45    typedef typename C::period P;// type of time unit
46    if (ratio_less_equal<P,milli>::value) {
47       // convert to and print as milliseconds
48       typedef typename ratio_multiply<P,kilo>::type TT;
49       cout << fixed << double(TT::num)/TT::den
50            << " milliseconds" << endl;
51       is_high_res = true;
52    }
53    else {
54        // print as seconds
55        cout << fixed << double(P::num)/P::den << " seconds" << endl;
56       is_high_res = false;
57    }
58    cout << "- is_steady: " << boolalpha << C::is_steady << endl;
59    is_steady = C::is_steady;
60}
61
62int main()
63{
64    bool is_high_res1, is_high_res2, is_high_res3, is_steady;
65    std::cout << "system_clock: " << std::endl;
66    printClockData<std::chrono::system_clock>(is_high_res1, is_steady);
67    std::cout << "\nhigh_resolution_clock: " << std::endl;
68    printClockData<std::chrono::high_resolution_clock>(is_high_res2, is_steady);
69    std::cout << "\nsteady_clock: " << std::endl;
70    printClockData<std::chrono::steady_clock>(is_high_res3, is_steady);
71
72    return (is_high_res1 && is_high_res2 && is_high_res3 && is_steady)? 0 : 1;
73}
74