@@ -379,8 +379,12 @@ class MexFunction : public matlab::mex::Function {
379379 tzStr = matlabStringToUtf8 (tz.toUTF16 ());
380380 }
381381
382+ auto [ldt, precision] = extractLocalDatetime (val);
383+
382384 if (tzStr.empty ()) {
383- return toml::ordered_value (extractLocalDatetime (val));
385+ auto result = toml::ordered_value (ldt);
386+ result.as_local_datetime_fmt ().subsecond_precision = precision;
387+ return result;
384388 }
385389
386390 matlab::data::Array offsetDuration = engine->feval (u" tzoffset" , {val});
@@ -390,40 +394,59 @@ class MexFunction : public matlab::mex::Function {
390394 auto h = std::chrono::duration_cast<std::chrono::hours>(totalOffset);
391395 auto m = totalOffset - h;
392396
393- toml::local_datetime ldt = extractLocalDatetime (val);
394- return toml::ordered_value (toml::offset_datetime (
397+ auto result = toml::ordered_value (toml::offset_datetime (
395398 ldt.date , ldt.time ,
396399 toml::time_offset (h.count (), std::abs (m.count ()))));
400+ result.as_offset_datetime_fmt ().subsecond_precision = precision;
401+ return result;
397402 }
398403
399- toml::local_datetime extractLocalDatetime (
404+ std::pair< toml::local_datetime, std:: size_t > extractLocalDatetime (
400405 const matlab::data::Array& val) {
401- auto intField = [&](const char16_t * fn) -> int {
402- matlab::data::TypedArray<double > r =
403- engine->feval (fn, {val});
404- return static_cast <int >(r[0 ]);
405- };
406-
407- int y = intField (u" year" );
408- int mo = intField (u" month" );
409- int d = intField (u" day" );
410- int h = intField (u" hour" );
411- int mi = intField (u" minute" );
406+ matlab::data::TypedArray<double > dv =
407+ engine->feval (u" datevec" , {val});
408+ int y = static_cast <int >(dv[0 ]);
409+ int mo = static_cast <int >(dv[1 ]);
410+ int d = static_cast <int >(dv[2 ]);
411+ int h = static_cast <int >(dv[3 ]);
412+ int mi = static_cast <int >(dv[4 ]);
413+ double sec = dv[5 ];
412414
413- matlab::data::TypedArray<double > secArr =
414- engine->feval (u" second" , {val});
415- double sec = secArr[0 ];
416415 int wholeSec = static_cast <int >(sec);
417- int microseconds = static_cast <int >(
416+ int totalUs = static_cast <int >(
418417 std::round ((sec - wholeSec) * 1e6 ));
419-
420- return toml::local_datetime (
421- toml::local_date (y, static_cast <toml::month_t >(mo - 1 ), d),
422- toml::local_time (h, mi, wholeSec, microseconds * 1000 , 0 ));
418+ int ms = totalUs / 1000 ;
419+ int us = totalUs % 1000 ;
420+
421+ std::size_t precision = 0 ;
422+ if (us != 0 ) precision = 6 ;
423+ else if (ms != 0 ) precision = 3 ;
424+
425+ return {
426+ toml::local_datetime (
427+ toml::local_date (y, static_cast <toml::month_t >(mo - 1 ), d),
428+ toml::local_time (h, mi, wholeSec, ms, us)),
429+ precision
430+ };
423431 }
424432
425433 // --- Array converters ---
426434
435+ template <typename Func>
436+ toml::ordered_value buildArray (size_t n, Func&& convertElem,
437+ bool isTableArray = false ) {
438+ toml::ordered_array tomlArr;
439+ tomlArr.reserve (n);
440+ for (size_t i = 0 ; i < n; ++i) {
441+ tomlArr.push_back (convertElem (i));
442+ }
443+ toml::array_format_info fmt;
444+ fmt.body_indent = indentSize;
445+ fmt.fmt = isTableArray ? resolveTableArrayFormat (tomlArr)
446+ : resolveArrayFormat (tomlArr);
447+ return toml::ordered_value (std::move (tomlArr), fmt);
448+ }
449+
427450 template <typename T>
428451 toml::ordered_value convertIntType (const matlab::data::Array& val,
429452 size_t numel) {
@@ -439,97 +462,52 @@ class MexFunction : public matlab::mex::Function {
439462 toml::ordered_value convertNumericArray (
440463 const matlab::data::Array& val, size_t numel) {
441464 matlab::data::TypedArray<T> arr = val;
442- toml::ordered_array tomlArr;
443- tomlArr.reserve (numel);
444-
445- for (auto elem : arr) {
465+ return buildArray (numel, [&](size_t i) -> toml::ordered_value {
446466 if constexpr (std::is_same_v<T, bool >) {
447- tomlArr.push_back (toml::ordered_value (
448- static_cast <bool >(elem)));
467+ return toml::ordered_value (static_cast <bool >(arr[i]));
449468 } else if constexpr (std::is_floating_point_v<T>) {
450- tomlArr.push_back (convertDouble (
451- static_cast <double >(elem)));
469+ return convertDouble (static_cast <double >(arr[i]));
452470 } else {
453- tomlArr.push_back (toml::ordered_value (
454- static_cast <toml::ordered_value::integer_type>(
455- elem)));
471+ return toml::ordered_value (
472+ static_cast <toml::ordered_value::integer_type>(arr[i]));
456473 }
457- }
458-
459- toml::array_format_info fmt;
460- fmt.fmt = resolveArrayFormat (tomlArr);
461- fmt.body_indent = indentSize;
462- return toml::ordered_value (std::move (tomlArr), fmt);
474+ });
463475 }
464476
465477 toml::ordered_value convertStringArray (
466478 const matlab::data::Array& val, size_t numel) {
467479 matlab::data::TypedArray<matlab::data::MATLABString> arr = val;
468- toml::ordered_array tomlArr;
469- tomlArr.reserve (numel);
470-
471480 toml::string_format_info strFmt;
472481 strFmt.fmt = resolveStringFormat ();
473- for (const auto & ms : arr) {
474- std::string s = matlabStringToUtf8 (ms);
475- tomlArr.push_back (toml::ordered_value (std::move (s), strFmt));
476- }
477-
478- toml::array_format_info fmt;
479- fmt.fmt = resolveArrayFormat (tomlArr);
480- fmt.body_indent = indentSize;
481- return toml::ordered_value (std::move (tomlArr), fmt);
482+ return buildArray (numel, [&](size_t i) {
483+ std::string s = matlabStringToUtf8 (arr[i]);
484+ return toml::ordered_value (std::move (s), strFmt);
485+ });
482486 }
483487
484488 toml::ordered_value convertCellArray (
485489 const matlab::data::Array& val, size_t numel) {
486490 matlab::data::TypedArray<matlab::data::Array> cells = val;
487- toml::ordered_array tomlArr;
488- tomlArr.reserve (numel);
489-
490- for (size_t i = 0 ; i < numel; ++i) {
491- tomlArr.push_back (convert (cells[i]));
492- }
493-
494- toml::array_format_info fmt;
495- fmt.fmt = resolveArrayFormat (tomlArr);
496- fmt.body_indent = indentSize;
497- return toml::ordered_value (std::move (tomlArr), fmt);
491+ return buildArray (numel, [&](size_t i) {
492+ return convert (cells[i]);
493+ });
498494 }
499495
500496 toml::ordered_value convertObjectArray (
501497 const matlab::data::Array& val, size_t numel) {
502498 matlab::data::TypedArray<matlab::data::Array> cells = val;
503-
504- toml::ordered_array tomlArr;
505- tomlArr.reserve (numel);
506-
507- for (size_t i = 0 ; i < numel; ++i) {
508- tomlArr.push_back (convertTable (cells[i]));
509- }
510-
511- toml::array_format_info fmt;
512- fmt.body_indent = indentSize;
513- fmt.fmt = resolveTableArrayFormat (tomlArr);
514- return toml::ordered_value (std::move (tomlArr), fmt);
499+ return buildArray (numel, [&](size_t i) {
500+ return convertTable (cells[i]);
501+ }, true );
515502 }
516503
517504 toml::ordered_value convertDatetimeArray (
518505 const matlab::data::Array& val, size_t numel) {
519506 matlab::data::TypedArray<matlab::data::Array> cells =
520507 engine->feval (u" num2cell" , {val});
521-
522- toml::ordered_array tomlArr;
523- tomlArr.reserve (numel);
524-
525- for (size_t i = 0 ; i < numel; ++i) {
526- tomlArr.push_back (convertDatetime (cells[i]));
527- }
528-
529- toml::array_format_info fmt;
530- fmt.fmt = resolveArrayFormat (tomlArr);
531- fmt.body_indent = indentSize;
532- return toml::ordered_value (std::move (tomlArr), fmt);
508+ return buildArray (numel, [&](size_t i) {
509+ return convertDatetime (cells[i]);
510+ });
533511 }
534512
535513 // --- Format resolution ---
0 commit comments