return __res;
};
+ template<typename _Duration>
+ static consteval
+ _ChronoSpec<_CharT>
+ _S_spec_for_tp()
+ {
+ using enum _ChronoParts;
+ // streaming of local_time is defined in terms of sys_time
+ constexpr bool __stream_insertable =
+ requires (basic_ostream<_CharT>& __os, chrono::sys_time<_Duration> __t)
+ { __os << __t; };
+ if constexpr (!__stream_insertable)
+ return _S_spec_for<_Duration>(_None);
+ else if constexpr (is_convertible_v<_Duration, chrono::days>)
+ return _S_spec_for<_Duration>(_Date);
+ else
+ return _S_spec_for<_Duration>(_DateTime);
+ }
+
using __formatter_chrono<_CharT>::__formatter_chrono;
using __formatter_chrono<_CharT>::_M_spec;
parse(basic_format_parse_context<_CharT>& __pc)
{
using enum __format::_ChronoParts;
- auto __next
+ auto __res
= _M_f.template _M_parse<_Duration>(__pc, _ZonedDateTime, __defSpec);
- if constexpr (!__stream_insertable)
+ if constexpr (__defSpec._M_chrono_specs.empty())
if (_M_f._M_spec._M_chrono_specs.empty())
__format::__invalid_chrono_spec(); // chrono-specs can't be empty
- return __next;
+ return __res;
}
template<typename _Out>
}
private:
- static constexpr bool __stream_insertable
- = requires (basic_ostream<_CharT>& __os,
- chrono::sys_time<_Duration> __t) { __os << __t; };
-
- static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
- {
- using enum __format::_ChronoParts;
- __format::_ChronoParts __needed = _DateTime;
- if constexpr (!__stream_insertable)
- __needed = _None;
- else if constexpr (is_convertible_v<_Duration, chrono::days>)
- __needed = _Date;
- return __format::__formatter_duration<_CharT>::
- template _S_spec_for<_Duration>(__needed);
- }();
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec =
+ __format::__formatter_duration<_CharT>::template _S_spec_for_tp<_Duration>();
__format::__formatter_duration<_CharT> _M_f{__defSpec};
};
parse(basic_format_parse_context<_CharT>& __pc)
{
using enum __format::_ChronoParts;
- return _M_f.template _M_parse<_Duration>(__pc, _DateTime, __defSpec);
+ auto __res
+ = _M_f.template _M_parse<_Duration>(__pc, _DateTime, __defSpec);
+ if constexpr (__defSpec._M_chrono_specs.empty())
+ if (_M_f._M_spec._M_chrono_specs.empty())
+ __format::__invalid_chrono_spec(); // chrono-specs can't be empty
+ return __res;
}
template<typename _Out>
}
private:
- static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
- {
- using enum __format::_ChronoParts;
- __format::_ChronoParts __needed = _DateTime;
- if constexpr (is_convertible_v<_Duration, chrono::days>)
- __needed = _Date;
- return __format::__formatter_duration<_CharT>::
- template _S_spec_for<_Duration>(__needed);
- }();
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec =
+ __format::__formatter_duration<_CharT>::template _S_spec_for_tp<_Duration>();
__format::__formatter_duration<_CharT> _M_f{__defSpec};
};
using decadays = duration<days::rep, std::ratio_multiply<std::deca, days::period>>;
using kilodays = duration<days::rep, std::ratio_multiply<std::kilo, days::period>>;
-template<typename CharT, typename Clock>
+template<typename CharT, typename Clock, bool CustomizedOstream>
void
-test_time_point(bool daysAsTime)
+test_time_point()
{
std::basic_string<CharT> res;
const auto lt = local_days(2024y/March/22) + 13h + 24min + 54s + 111222333ns;
- auto strip_time = [daysAsTime](std::basic_string_view<CharT> sv)
- { return daysAsTime ? sv : sv.substr(0, 10); };
+ auto strip_time = [](std::basic_string_view<CharT> sv)
+ { return CustomizedOstream ? sv.substr(0, 10) : sv; };
verify( wall_cast<Clock, nanoseconds>(lt),
WIDEN("2024-03-22 13:24:54.111222333") );
strip_time(WIDEN("2024-03-18 00:00:00")) );
verify( wall_cast<Clock, kilodays>(lt),
strip_time(WIDEN("2022-01-08 00:00:00")) );
+
+ if constexpr (!CustomizedOstream)
+ {
+ verify( wall_cast<Clock, duration<double>>(lt),
+ WIDEN("2024-03-22 13:24:54") );
+ verify( wall_cast<Clock, years>(lt),
+ WIDEN("2024-01-01 02:16:48") );
+ }
+ else
+ {
+ test_no_empty_spec<CharT, time_point<Clock, duration<double>>>();
+ test_no_empty_spec<CharT, time_point<Clock, years>>();
+ }
}
template<typename CharT>
void
test_time_points()
{
- test_time_point<CharT, local_t>(false);
- test_time_point<CharT, system_clock>(false);
- test_time_point<CharT, utc_clock>(true);
- test_time_point<CharT, tai_clock>(true);
- test_time_point<CharT, gps_clock>(true);
- test_time_point<CharT, file_clock>(true);
+ test_time_point<CharT, local_t, true>();
+ test_time_point<CharT, system_clock, true>();
+ test_time_point<CharT, utc_clock, false>();
+ test_time_point<CharT, tai_clock, false>();
+ test_time_point<CharT, gps_clock, false>();
+ test_time_point<CharT, file_clock, false>();
test_leap_second<CharT>();
#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI
test_zoned_time<CharT>();
#endif
test_local_time_format<CharT>();
- test_no_empty_spec<CharT, sys_time<years>>();
- test_no_empty_spec<CharT, sys_time<duration<float>>>();
}
#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI