|
| 1 | +/* |
| 2 | + * Copyright (c) 2024 Niklas Hauser |
| 3 | + * |
| 4 | + * This file is part of the modm project. |
| 5 | + * |
| 6 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 7 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 8 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 9 | + */ |
| 10 | +// ---------------------------------------------------------------------------- |
| 11 | + |
| 12 | +#pragma once |
| 13 | + |
| 14 | +#include <chrono> |
| 15 | +#include <ctime> |
| 16 | +%% if options.with_printf |
| 17 | +#include <inttypes.h> |
| 18 | +%% endif |
| 19 | + |
| 20 | +namespace modm |
| 21 | +{ |
| 22 | + |
| 23 | +/// @ingroup modm_io |
| 24 | +/// @{ |
| 25 | + |
| 26 | +%% if not is_avr |
| 27 | +inline modm::IOStream& |
| 28 | +operator << (modm::IOStream& s, const std::chrono::year year) |
| 29 | +{ |
| 30 | +%% if options.with_printf |
| 31 | + return s.printf("%04" PRIi16, int16_t(int(year))); |
| 32 | +%% else |
| 33 | + return s << int(year); |
| 34 | +%% endif |
| 35 | +} |
| 36 | + |
| 37 | +inline modm::IOStream& |
| 38 | +operator << (modm::IOStream& s, const std::chrono::month month) |
| 39 | +{ |
| 40 | + static constexpr std::string_view map = "???JanFebMarAprMayJunJulAugSepOctNovDec"; |
| 41 | + return s << map.substr((unsigned(month) <= 12 ? unsigned(month) : 0u) * 3, 3); |
| 42 | +} |
| 43 | + |
| 44 | +inline modm::IOStream& |
| 45 | +operator << (modm::IOStream& s, const std::chrono::day day) |
| 46 | +{ |
| 47 | +%% if options.with_printf |
| 48 | + return s.printf("%02" PRIu8, uint8_t(unsigned(day))); |
| 49 | +%% else |
| 50 | + return s << unsigned(day); |
| 51 | +%% endif |
| 52 | +} |
| 53 | + |
| 54 | +inline modm::IOStream& |
| 55 | +operator << (modm::IOStream& s, const std::chrono::weekday wd) |
| 56 | +{ |
| 57 | + static constexpr std::string_view map = "SunMonTueWedThuFriSat???"; |
| 58 | + return s << map.substr((wd.c_encoding() < 7u ? wd.c_encoding() : 7u) * 3, 3); |
| 59 | +} |
| 60 | + |
| 61 | +inline modm::IOStream& |
| 62 | +operator << (modm::IOStream& s, const std::chrono::weekday_indexed wdi) |
| 63 | +{ |
| 64 | + s << wdi.weekday(); |
| 65 | + const auto index = wdi.index(); |
| 66 | + if (1 <= index and index <= 5) return s << '[' << index << ']'; |
| 67 | + return s << "[?]"; |
| 68 | +} |
| 69 | + |
| 70 | +inline modm::IOStream& |
| 71 | +operator << (modm::IOStream& s, const std::chrono::weekday_last wdl) |
| 72 | +{ |
| 73 | + return s << wdl.weekday() << "[last]"; |
| 74 | +} |
| 75 | + |
| 76 | +inline modm::IOStream& |
| 77 | +operator << (modm::IOStream& s, const std::chrono::month_day md) |
| 78 | +{ |
| 79 | + return s << md.month() << '/' << md.day(); |
| 80 | +} |
| 81 | + |
| 82 | +inline modm::IOStream& |
| 83 | +operator << (modm::IOStream& s, const std::chrono::month_day_last mdl) |
| 84 | +{ |
| 85 | + return s << mdl.month() << "/last"; |
| 86 | +} |
| 87 | + |
| 88 | +inline modm::IOStream& |
| 89 | +operator << (modm::IOStream& s, const std::chrono::month_weekday mwd) |
| 90 | +{ |
| 91 | + return s << mwd.month() << '/' << mwd.weekday_indexed(); |
| 92 | +} |
| 93 | + |
| 94 | +inline modm::IOStream& |
| 95 | +operator << (modm::IOStream& s, const std::chrono::month_weekday_last mwdl) |
| 96 | +{ |
| 97 | + return s << mwdl.month() << '/' << mwdl.weekday_last(); |
| 98 | +} |
| 99 | + |
| 100 | +inline modm::IOStream& |
| 101 | +operator << (modm::IOStream& s, const std::chrono::year_month ym) |
| 102 | +{ |
| 103 | + return s << ym.year() << '/' << ym.month(); |
| 104 | +} |
| 105 | + |
| 106 | +inline modm::IOStream& |
| 107 | +operator << (modm::IOStream& s, const std::chrono::year_month_day& ymd) |
| 108 | +{ |
| 109 | +%% if options.with_printf |
| 110 | + return s.printf("%04" PRIi16 "-%02" PRIu8 "-%02" PRIu8, |
| 111 | + int16_t(int(ymd.year())), uint8_t(unsigned(ymd.month())), uint8_t(unsigned(ymd.day()))); |
| 112 | +%% else |
| 113 | + return s << ymd.year() << '-' << unsigned(ymd.month()) << '-' << ymd.day(); |
| 114 | +%% endif |
| 115 | +} |
| 116 | + |
| 117 | +inline modm::IOStream& |
| 118 | +operator << (modm::IOStream& s, const std::chrono::year_month_day_last& ymdl) |
| 119 | +{ |
| 120 | + return s << ymdl.year() << '/' << ymdl.month_day_last(); |
| 121 | +} |
| 122 | + |
| 123 | +inline modm::IOStream& |
| 124 | +operator << (modm::IOStream& s, const std::chrono::year_month_weekday& ymwd) |
| 125 | +{ |
| 126 | + return s << ymwd.year() << '/' << ymwd.month() << '/' << ymwd.weekday_indexed(); |
| 127 | +} |
| 128 | + |
| 129 | +inline modm::IOStream& |
| 130 | +operator << (modm::IOStream& s, const std::chrono::year_month_weekday_last& ymwdl) |
| 131 | +{ |
| 132 | + return s << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); |
| 133 | +} |
| 134 | + |
| 135 | +template< class Duration > |
| 136 | +modm::IOStream& |
| 137 | +operator << (modm::IOStream& s, const std::chrono::hh_mm_ss<Duration>& hms) |
| 138 | +{ |
| 139 | +%% if options.with_printf |
| 140 | + s.printf("%02" PRIu8 ":%02" PRIu8 ":%02" PRIu8 ".%03" PRIu16, |
| 141 | + uint8_t(hms.hours().count()), uint8_t(hms.minutes().count()), uint8_t(hms.seconds().count()), |
| 142 | + uint16_t(std::chrono::duration_cast<std::chrono::milliseconds>(hms.subseconds()).count())); |
| 143 | +%% else |
| 144 | + s << uint8_t(hms.hours().count()) << ':' << uint8_t(hms.minutes().count()) << ':' << uint8_t(hms.seconds().count()); |
| 145 | + s << '.' << uint16_t(std::chrono::duration_cast<std::chrono::milliseconds>(hms.subseconds()).count()); |
| 146 | +%% endif |
| 147 | + return s; |
| 148 | +} |
| 149 | +%% endif |
| 150 | + |
| 151 | +template< class Rep, class Period > |
| 152 | +inline modm::IOStream& |
| 153 | +operator << (modm::IOStream& s, const std::chrono::duration<Rep, Period>& d) |
| 154 | +{ |
| 155 | + s << d.count(); |
| 156 | + |
| 157 | + if constexpr (std::is_same_v<typename Period::type, std::atto>) s << "as"; |
| 158 | + if constexpr (std::is_same_v<typename Period::type, std::femto>) s << "fs"; |
| 159 | + if constexpr (std::is_same_v<typename Period::type, std::pico>) s << "ps"; |
| 160 | + if constexpr (std::is_same_v<typename Period::type, std::nano>) s << "ns"; |
| 161 | + if constexpr (std::is_same_v<typename Period::type, std::micro>) s << "us"; |
| 162 | + if constexpr (std::is_same_v<typename Period::type, std::milli>) s << "ms"; |
| 163 | + if constexpr (std::is_same_v<typename Period::type, std::centi>) s << "cs"; |
| 164 | + if constexpr (std::is_same_v<typename Period::type, std::deci>) s << "ds"; |
| 165 | + if constexpr (std::is_same_v<typename Period::type, std::ratio<1>>) s << 's'; |
| 166 | + if constexpr (std::is_same_v<typename Period::type, std::deca>) s << "as"; |
| 167 | + if constexpr (std::is_same_v<typename Period::type, std::hecto>) s << "hs"; |
| 168 | + if constexpr (std::is_same_v<typename Period::type, std::kilo>) s << "ks"; |
| 169 | + if constexpr (std::is_same_v<typename Period::type, std::mega>) s << "Ms"; |
| 170 | + if constexpr (std::is_same_v<typename Period::type, std::giga>) s << "Gs"; |
| 171 | + if constexpr (std::is_same_v<typename Period::type, std::tera>) s << "Ts"; |
| 172 | + if constexpr (std::is_same_v<typename Period::type, std::peta>) s << "Ps"; |
| 173 | + if constexpr (std::is_same_v<typename Period::type, std::exa>) s << "Es"; |
| 174 | + |
| 175 | + if constexpr (std::is_same_v<typename Period::type, std::ratio<60>>) s << "min"; |
| 176 | + if constexpr (std::is_same_v<typename Period::type, std::ratio<3600>>) s << 'h'; |
| 177 | + if constexpr (std::is_same_v<typename Period::type, std::ratio<86400>>) s << 'd'; |
| 178 | + |
| 179 | + return s; |
| 180 | +} |
| 181 | + |
| 182 | +template< class Clock, class Duration > |
| 183 | +modm::IOStream& |
| 184 | +operator << (modm::IOStream& s, const std::chrono::time_point<Clock, Duration>& tp) |
| 185 | +{ |
| 186 | + return s << tp.time_since_epoch(); |
| 187 | +} |
| 188 | + |
| 189 | +inline modm::IOStream& |
| 190 | +operator << (modm::IOStream& s, const std::tm& tm) |
| 191 | +{ |
| 192 | +%% if options.with_printf |
| 193 | + s.printf("%04" PRIu16 "-%02" PRIu8 "-%02" PRIu8 " %02" PRIu8 ":%02" PRIu8 ":%02" PRIu8, |
| 194 | + uint16_t(tm.tm_year + 1900u), uint8_t(tm.tm_mon), uint8_t(tm.tm_mday), |
| 195 | + uint8_t(tm.tm_hour), uint8_t(tm.tm_min), uint8_t(tm.tm_sec)); |
| 196 | +%% else |
| 197 | + s << (tm.tm_year + 1900u) << '-' << tm.tm_mon << '-' << tm.tm_mday << ' '; |
| 198 | + s << tm.tm_hour << ':' << tm.tm_min << ':' << tm.tm_sec; |
| 199 | +%% endif |
| 200 | + return s; |
| 201 | +} |
| 202 | + |
| 203 | +/// @} |
| 204 | + |
| 205 | +} |
| 206 | + |
| 207 | + |
| 208 | + |
0 commit comments