@@ -1226,6 +1226,152 @@ duration_as_double_cpp(cpp11::list_of<cpp11::integers> fields,
12261226
12271227// -----------------------------------------------------------------------------
12281228
1229+ template <class ClockDuration >
1230+ static
1231+ inline
1232+ cpp11::writable::list
1233+ duration_abs_impl (const ClockDuration& x) {
1234+ using Duration = typename ClockDuration::duration;
1235+ using Rep = typename Duration::rep;
1236+
1237+ const r_ssize size = x.size ();
1238+ ClockDuration out (size);
1239+
1240+ const Rep zero{0 };
1241+
1242+ for (r_ssize i = 0 ; i < size; ++i) {
1243+ if (x.is_na (i)) {
1244+ out.assign_na (i);
1245+ continue ;
1246+ }
1247+
1248+ const Duration elt = x[i];
1249+ const Rep elt_rep = elt.count ();
1250+ const Rep out_rep = (elt_rep < zero) ? std::abs (elt_rep) : elt_rep;
1251+ const Duration out_elt{out_rep};
1252+
1253+ out.assign (out_elt, i);
1254+ }
1255+
1256+ return out.to_list ();
1257+ }
1258+
1259+ [[cpp11::register ]]
1260+ cpp11::writable::list
1261+ duration_abs_cpp (cpp11::list_of<cpp11::integers> fields,
1262+ const cpp11::integers& precision_int) {
1263+ using namespace rclock ;
1264+
1265+ cpp11::integers ticks = duration::get_ticks (fields);
1266+ cpp11::integers ticks_of_day = duration::get_ticks_of_day (fields);
1267+ cpp11::integers ticks_of_second = duration::get_ticks_of_second (fields);
1268+
1269+ duration::years dy{ticks};
1270+ duration::quarters dq{ticks};
1271+ duration::months dm{ticks};
1272+ duration::weeks dw{ticks};
1273+ duration::days dd{ticks};
1274+ duration::hours dh{ticks, ticks_of_day};
1275+ duration::minutes dmin{ticks, ticks_of_day};
1276+ duration::seconds ds{ticks, ticks_of_day};
1277+ duration::milliseconds dmilli{ticks, ticks_of_day, ticks_of_second};
1278+ duration::microseconds dmicro{ticks, ticks_of_day, ticks_of_second};
1279+ duration::nanoseconds dnano{ticks, ticks_of_day, ticks_of_second};
1280+
1281+ switch (parse_precision (precision_int)) {
1282+ case precision::year: return duration_abs_impl (dy);
1283+ case precision::quarter: return duration_abs_impl (dq);
1284+ case precision::month: return duration_abs_impl (dm);
1285+ case precision::week: return duration_abs_impl (dw);
1286+ case precision::day: return duration_abs_impl (dd);
1287+ case precision::hour: return duration_abs_impl (dh);
1288+ case precision::minute: return duration_abs_impl (dmin);
1289+ case precision::second: return duration_abs_impl (ds);
1290+ case precision::millisecond: return duration_abs_impl (dmilli);
1291+ case precision::microsecond: return duration_abs_impl (dmicro);
1292+ case precision::nanosecond: return duration_abs_impl (dnano);
1293+ }
1294+
1295+ never_reached (" duration_abs_cpp" );
1296+ }
1297+
1298+ // -----------------------------------------------------------------------------
1299+
1300+ template <class ClockDuration >
1301+ static
1302+ inline
1303+ cpp11::writable::integers
1304+ duration_sign_impl (const ClockDuration& x) {
1305+ using Duration = typename ClockDuration::duration;
1306+ using Rep = typename Duration::rep;
1307+
1308+ const r_ssize size = x.size ();
1309+ cpp11::writable::integers out (size);
1310+
1311+ const Rep zero{0 };
1312+
1313+ for (r_ssize i = 0 ; i < size; ++i) {
1314+ if (x.is_na (i)) {
1315+ out[i] = r_int_na;
1316+ continue ;
1317+ }
1318+
1319+ const Duration elt = x[i];
1320+ const Rep elt_rep = elt.count ();
1321+
1322+ if (elt_rep == zero) {
1323+ out[i] = 0 ;
1324+ } else if (elt_rep > zero) {
1325+ out[i] = 1 ;
1326+ } else {
1327+ out[i] = -1 ;
1328+ }
1329+ }
1330+
1331+ return out;
1332+ }
1333+
1334+ [[cpp11::register ]]
1335+ cpp11::writable::integers
1336+ duration_sign_cpp (cpp11::list_of<cpp11::integers> fields,
1337+ const cpp11::integers& precision_int) {
1338+ using namespace rclock ;
1339+
1340+ cpp11::integers ticks = duration::get_ticks (fields);
1341+ cpp11::integers ticks_of_day = duration::get_ticks_of_day (fields);
1342+ cpp11::integers ticks_of_second = duration::get_ticks_of_second (fields);
1343+
1344+ duration::years dy{ticks};
1345+ duration::quarters dq{ticks};
1346+ duration::months dm{ticks};
1347+ duration::weeks dw{ticks};
1348+ duration::days dd{ticks};
1349+ duration::hours dh{ticks, ticks_of_day};
1350+ duration::minutes dmin{ticks, ticks_of_day};
1351+ duration::seconds ds{ticks, ticks_of_day};
1352+ duration::milliseconds dmilli{ticks, ticks_of_day, ticks_of_second};
1353+ duration::microseconds dmicro{ticks, ticks_of_day, ticks_of_second};
1354+ duration::nanoseconds dnano{ticks, ticks_of_day, ticks_of_second};
1355+
1356+ switch (parse_precision (precision_int)) {
1357+ case precision::year: return duration_sign_impl (dy);
1358+ case precision::quarter: return duration_sign_impl (dq);
1359+ case precision::month: return duration_sign_impl (dm);
1360+ case precision::week: return duration_sign_impl (dw);
1361+ case precision::day: return duration_sign_impl (dd);
1362+ case precision::hour: return duration_sign_impl (dh);
1363+ case precision::minute: return duration_sign_impl (dmin);
1364+ case precision::second: return duration_sign_impl (ds);
1365+ case precision::millisecond: return duration_sign_impl (dmilli);
1366+ case precision::microsecond: return duration_sign_impl (dmicro);
1367+ case precision::nanosecond: return duration_sign_impl (dnano);
1368+ }
1369+
1370+ never_reached (" duration_sign_impl" );
1371+ }
1372+
1373+ // -----------------------------------------------------------------------------
1374+
12291375template <class ClockDuration >
12301376static
12311377inline
0 commit comments