Skip to content

Instantly share code, notes, and snippets.

@jonesinator
Created October 10, 2017 22:46
Show Gist options
  • Save jonesinator/ef95aba9346fa636d3ab7cfc3f3ec884 to your computer and use it in GitHub Desktop.
Save jonesinator/ef95aba9346fa636d3ab7cfc3f3ec884 to your computer and use it in GitHub Desktop.
c++17 - Decompose a std::chrono::duration into several component durations.
#include <chrono>
#include <iostream>
#include <tuple>
template <typename lhs_t, typename rhs_t, typename... other_ts>
constexpr bool has_decreasing_periods() {
if constexpr (std::ratio_less_v<typename lhs_t::period,
typename rhs_t::period>) {
return false;
} else if constexpr (sizeof...(other_ts)) {
return has_decreasing_periods<rhs_t, other_ts...>();
} else {
return true;
}
}
template <typename return_duration_t, typename input_duration_t>
return_duration_t chrono_extract(input_duration_t& value) {
auto extracted = std::chrono::duration_cast<return_duration_t>(value);
value -= extracted;
return extracted;
}
template <typename... return_ts, typename duration_t>
std::tuple<return_ts...> chrono_decompose(duration_t value) {
static_assert(has_decreasing_periods<return_ts...>());
using smallest_t = std::tuple_element_t<sizeof...(return_ts) - 1,
std::tuple<return_ts...>>;
auto small_value = std::chrono::duration_cast<smallest_t>(value);
return {chrono_extract<return_ts>(small_value)...};
}
int main()
{
std::chrono::seconds before(19874);
{
auto [h, m] = chrono_decompose<std::chrono::hours,
std::chrono::minutes>(before);
std::chrono::seconds after(h + m);
std::cout << h.count() << " hours "
<< m.count() << " minutes = "
<< after.count() << " seconds\n";
}
{
auto [m, s, ms] = chrono_decompose<std::chrono::minutes,
std::chrono::seconds,
std::chrono::milliseconds>(before);
auto after =
std::chrono::duration_cast<std::chrono::seconds>(m + s + ms);
std::cout << m.count() << " minutes "
<< s.count() << " seconds "
<< ms.count() << " milliseconds = "
<< after.count() << " seconds\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment