@@ -2602,30 +2602,36 @@ class TShift : public TBoxedValue {
2602
2602
}
2603
2603
};
2604
2604
2605
- template <size_t Digits, bool Exacly = true >
2605
+ template <size_t Digits, bool Trailing = true , bool Leading = true >
2606
2606
struct PrintNDigits ;
2607
2607
2608
- template <bool Exacly >
2609
- struct PrintNDigits <0U , Exacly > {
2608
+ template <bool Trailing, bool Leading >
2609
+ struct PrintNDigits <0U , Trailing, Leading > {
2610
2610
static constexpr ui32 Miltiplier = 1U ;
2611
2611
2612
2612
template <typename T>
2613
2613
static constexpr size_t Do (T, char *) { return 0U ; }
2614
2614
};
2615
2615
2616
- template <size_t Digits, bool Exacly >
2616
+ template <size_t Digits, bool Trailing, bool Leading >
2617
2617
struct PrintNDigits {
2618
- using TNextPrint = PrintNDigits<Digits - 1U , Exacly>;
2619
- static constexpr ui32 Miltiplier = TNextPrint::Miltiplier * 10U ;
2618
+ using TNextNoLeadPrint = PrintNDigits<Digits - 1U , Trailing, false >;
2619
+ using TNextCommonPrint = PrintNDigits<Digits - 1U , Trailing, true >;
2620
+ static_assert (TNextNoLeadPrint::Miltiplier == TNextCommonPrint::Miltiplier);
2621
+ static constexpr ui32 Miltiplier = TNextCommonPrint::Miltiplier * 10U ;
2620
2622
2621
2623
template <typename T>
2622
2624
static constexpr size_t Do (T in, char * out) {
2623
2625
in %= Miltiplier;
2624
- if (Exacly || in) {
2625
- *out = " 0123456789" [in / TNextPrint::Miltiplier];
2626
- return 1U + TNextPrint::Do (in, ++out);
2626
+ if (!Trailing && in == 0 ) {
2627
+ return 0U ;
2627
2628
}
2628
- return 0U ;
2629
+ const auto digit = in / TNextCommonPrint::Miltiplier;
2630
+ if (!Leading && digit == 0 ) {
2631
+ return TNextNoLeadPrint::Do (in, out);
2632
+ }
2633
+ *out = " 0123456789" [digit];
2634
+ return 1U + TNextCommonPrint::Do (in, ++out);
2629
2635
}
2630
2636
};
2631
2637
@@ -2664,24 +2670,10 @@ class TShift : public TBoxedValue {
2664
2670
return true ;
2665
2671
}
2666
2672
2667
- auto stringType = builder.SimpleType <char *>();
2668
-
2669
- auto boolType = builder.SimpleType <bool >();
2670
- auto optionalBoolType = builder.Optional ()->Item (boolType).Build ();
2671
-
2672
- auto args = builder.Args ();
2673
- args->Add (stringType);
2674
- args->Add (optionalBoolType).Name (" AlwaysWriteFractionalSeconds" );
2675
- args->Done ();
2676
- builder.OptionalArgs (1 );
2673
+ builder.OptionalArgs (1 ).Args ()->Add <char *>()
2674
+ .Add <TOptional<bool >>().Name (" AlwaysWriteFractionalSeconds" );
2677
2675
builder.Returns (
2678
- builder.Callable (1 )
2679
- ->Returns (stringType)
2680
- .Arg (resourceType)
2681
- .Flags (ICallablePayload::TArgumentFlags::AutoMap)
2682
- .Build ()
2683
- );
2684
-
2676
+ builder.SimpleSignatureType <char *(TAutoMap<TResource<TM64ResourceName>>)>());
2685
2677
if (!typesOnly) {
2686
2678
builder.Implementation (new TFormat (builder.GetSourcePosition ()));
2687
2679
}
@@ -2780,73 +2772,85 @@ class TShift : public TBoxedValue {
2780
2772
break ;
2781
2773
}
2782
2774
case ' Y' : {
2783
- static constexpr size_t size = 4 ;
2775
+ static constexpr size_t size = 6 ;
2784
2776
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2785
- return PrintNDigits<size>::Do (GetYear (value), out);
2777
+ i64 year = GetYear<TM64ResourceName>(value);
2778
+ Y_DEBUG_ABORT_UNLESS (year != 0 );
2779
+ i64 yearRepr = std::abs (year);
2780
+ if (year < 0 ) {
2781
+ *out++ = ' -' ;
2782
+ }
2783
+ return (year < 0 ? 1 : 0 ) + PrintNDigits<size, true , false >::Do (yearRepr, out);
2786
2784
});
2787
- ReservedSize_ += size;
2785
+ // Reserve one more slot for possible '-' char.
2786
+ ReservedSize_ += size + 1 ;
2788
2787
break ;
2789
2788
}
2790
2789
case ' m' : {
2791
2790
static constexpr size_t size = 2 ;
2792
2791
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2793
- return PrintNDigits<size>::Do (GetMonth (value), out);
2792
+ return PrintNDigits<size>::Do (GetMonth<TM64ResourceName> (value), out);
2794
2793
});
2795
2794
ReservedSize_ += size;
2796
2795
break ;
2797
2796
}
2798
2797
case ' d' : {
2799
2798
static constexpr size_t size = 2 ;
2800
2799
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2801
- return PrintNDigits<size>::Do (GetDay (value), out);
2800
+ return PrintNDigits<size>::Do (GetDay<TM64ResourceName> (value), out);
2802
2801
});
2803
2802
ReservedSize_ += size;
2804
2803
break ;
2805
2804
}
2806
2805
case ' H' : {
2807
2806
static constexpr size_t size = 2 ;
2808
2807
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2809
- return PrintNDigits<size>::Do (GetHour (value), out);
2808
+ return PrintNDigits<size>::Do (GetHour<TM64ResourceName> (value), out);
2810
2809
});
2811
2810
ReservedSize_ += size;
2812
2811
break ;
2813
2812
}
2814
2813
case ' M' : {
2815
2814
static constexpr size_t size = 2 ;
2816
2815
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2817
- return PrintNDigits<size>::Do (GetMinute (value), out);
2816
+ return PrintNDigits<size>::Do (GetMinute<TM64ResourceName> (value), out);
2818
2817
});
2819
2818
ReservedSize_ += size;
2820
2819
break ;
2821
2820
}
2822
2821
case ' S' :
2823
2822
Printers_.emplace_back ([alwaysWriteFractionalSeconds](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2824
2823
constexpr size_t size = 2 ;
2825
- if (const auto microsecond = GetMicrosecond (value); microsecond || alwaysWriteFractionalSeconds) {
2826
- out += PrintNDigits<size>::Do (GetSecond (value), out);
2824
+ if (const auto microsecond = GetMicrosecond<TM64ResourceName> (value); microsecond || alwaysWriteFractionalSeconds) {
2825
+ out += PrintNDigits<size>::Do (GetSecond<TM64ResourceName> (value), out);
2827
2826
*out++ = ' .' ;
2828
2827
constexpr size_t msize = 6 ;
2829
2828
auto addSz = alwaysWriteFractionalSeconds ?
2830
2829
PrintNDigits<msize, true >::Do (microsecond, out) :
2831
2830
PrintNDigits<msize, false >::Do (microsecond, out);
2832
2831
return size + 1U + addSz;
2833
2832
}
2834
- return PrintNDigits<size>::Do (GetSecond (value), out);
2833
+ return PrintNDigits<size>::Do (GetSecond<TM64ResourceName> (value), out);
2835
2834
});
2836
2835
ReservedSize_ += 9 ;
2837
2836
break ;
2838
2837
2839
2838
case ' z' : {
2840
2839
static constexpr size_t size = 5 ;
2841
2840
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder& builder) {
2842
- auto timezoneId = GetTimezoneId (value);
2841
+ auto timezoneId = GetTimezoneId<TM64ResourceName> (value);
2843
2842
if (TTMStorage::IsUniversal (timezoneId)) {
2844
2843
std::memcpy (out, " +0000" , size);
2845
2844
return size;
2846
2845
}
2847
2846
i32 shift;
2848
- if (!builder.GetTimezoneShift (GetYear (value), GetMonth (value), GetDay (value),
2849
- GetHour (value), GetMinute (value), GetSecond (value), timezoneId, shift))
2847
+ if (!builder.GetTimezoneShift (GetYear<TM64ResourceName>(value),
2848
+ GetMonth<TM64ResourceName>(value),
2849
+ GetDay<TM64ResourceName>(value),
2850
+ GetHour<TM64ResourceName>(value),
2851
+ GetMinute<TM64ResourceName>(value),
2852
+ GetSecond<TM64ResourceName>(value),
2853
+ timezoneId, shift))
2850
2854
{
2851
2855
std::memcpy (out, " +0000" , size);
2852
2856
return size;
@@ -2863,7 +2867,7 @@ class TShift : public TBoxedValue {
2863
2867
}
2864
2868
case ' Z' :
2865
2869
Printers_.emplace_back ([](char * out, const TUnboxedValuePod& value, const IDateBuilder&) {
2866
- const auto timezoneId = GetTimezoneId (value);
2870
+ const auto timezoneId = GetTimezoneId<TM64ResourceName> (value);
2867
2871
const auto tzName = NUdf::GetTimezones ()[timezoneId];
2868
2872
std::memcpy (out, tzName.data (), std::min (tzName.size (), MAX_TIMEZONE_NAME_LEN));
2869
2873
return tzName.size ();
@@ -2887,7 +2891,7 @@ class TShift : public TBoxedValue {
2887
2891
" Nov" ,
2888
2892
" Dec"
2889
2893
};
2890
- auto month = GetMonth (value);
2894
+ auto month = GetMonth<TM64ResourceName> (value);
2891
2895
Y_ENSURE (month > 0 && month <= sizeof (mp) / sizeof (mp[0 ]), " Invalid month value" );
2892
2896
std::memcpy (out, mp[month - 1 ].data (), size);
2893
2897
return size;
@@ -2911,7 +2915,7 @@ class TShift : public TBoxedValue {
2911
2915
" November" ,
2912
2916
" December"
2913
2917
};
2914
- auto month = GetMonth (value);
2918
+ auto month = GetMonth<TM64ResourceName> (value);
2915
2919
Y_ENSURE (month > 0 && month <= sizeof (mp) / sizeof (mp[0 ]), " Invalid month value" );
2916
2920
const std::string_view monthFullName = mp[month - 1 ];
2917
2921
std::memcpy (out, monthFullName.data (), monthFullName.size ());
0 commit comments