Doc. no. | R0165??? |
Date: | Revised 2019-08-05 at 16:08:15 UTC |
Project: | Programming Language C++ |
Reply to: | Marshall Clow <lwgchair@gmail.com> |
Section: 29.11.7.4.11 [fs.path.gen] Status: Ready Submitter: Billy O'Neal III Opened: 2018-02-23 Last modified: 2019-07-22
Priority: 2
View all other issues in [fs.path.gen].
View all issues with Ready status.
Discussion:
path::lexically_relative constructs the resulting path with operator/=. If any of the filename elements from *this are themselves acceptable root-names, operator/= will destroy any previous value, and take that root_name(). For example:
path("/a:/b:").lexically_relative("/a:/c:")
On a POSIX implementation, this would return path("../b:"), but on a Windows implementation, the "b:" element is interpreted as a root-name, and clobbers the entire result path, giving path("b:"). We should detect this problematic condition and fail (by returning path()).
[2019-01-20 Reflector prioritization]
Set Priority to 2
[2019 Cologne Wednesday night]
Status to Ready
Proposed resolution:
This wording is relative to N4727.
Change 29.11.7.4.11 [fs.path.gen] as indicated:
path lexically_relative(const path& base) const;-3- […]
-4- Effects: If root_name() != base.root_name() is true or is_absolute() != base.is_absolute() is true or !has_root_directory() && base.has_root_directory() is true or if any filename in relative_path() or base.relative_path() can be interpreted as a root-name, returns path(). [Note: On a POSIX implementation, no filename in a relative-path is acceptable as a root-name — end note] Determines the first mismatched element of *this and base as if by:auto [a, b] = mismatch(begin(), end(), base.begin(), base.end());Then,
(4.1) — if a == end() and b == base.end(), returns path("."); otherwise
(4.2) — let n be the number of filename elements in [b, base.end()) that are not dot or dot-dot minus the number that are dot-dot. If n < 0, returns path(); otherwise
(4.3) — returns an object of class path that is default-constructed, followed by
(4.3.1) — application of operator/=(path("..")) n times, and then
(4.3.2) — application of operator/= for each element in [a, end()).
Section: 22.7.3.3 [span.sub] Status: Ready Submitter: Tomasz Kamiński Opened: 2018-04-13 Last modified: 2019-07-22
Priority: 3
View all issues with Ready status.
Discussion:
Currently all out-of-bound/inputs errors in the functions taking an subview of span lead to undefined behavior, even in the situation when they could be detected at compile time. This is inconsistent with the behavior of the span constructors, which make similar constructs ill-formed.
Furthermore, with the current specification of the subspan function, the following invocation:span<T, N> s; // N > 0 s.subspan<O>(); // with O > 0
is ill-formed when O > N + 1, as the return of the function is span<T, K> with K < -1. However in case when O == N + 1, runtime sized span is returned (span<T, -1>) instead and the behavior of the function is undefined.
Firstly, for either run time sized (N == dynamic_extent) and fixed sized (N > 0) object s of type span<T, N>, the following constructs should be ill-formed, instead of having undefined behavior:s.first<C>() with C < 0
s.last<C>() with C < 0
s.subspan<O, E> with O < 0 or E < 0 and E != dynamic_extent.
This would follow span specification, that make instantiation of span<T, N> ill-formed for N < 0 and N != dynamic_extent.
In addition the following constructs should be made ill-formed for fixed size span s of type span<T, N> (with N > 0):s.first<C>() with C > N
s.last<C>() with C > N
s.subspan<O, dynamic_extent>() with O > N
s.subspan<O, C>() with O + C > N
This will match the span constructor that made construction of fixed size span<T, N> from fixed size span of different size ill-formed.
[2018-04-24 Priority set to 3 after discussion on the reflector.]
[2018-11 San Diego Thursday night issue processing]
Tomasz to provide updated wording.
Previous resolution: [SUPERSEDED]This wording is relative to N4741.
Edit 22.7.3.3 [span.sub] as indicated:
template<ptrdiff_t Count> constexpr span<element_type, Count> first() const;-?- Remarks: If Count < 0 || (Extent != dynamic_extent && Count > Extent), the program is ill-formed.
-1- Requires:0 <= Count &&Count <= size(). -2- Effects: Equivalent to: return {data(), Count};template<ptrdiff_t Count> constexpr span<element_type, Count> last() const;-?- Remarks: If Count < 0 || (Extent != dynamic_extent && Count > Extent), the program is ill-formed.
-3- Requires:0 <= Count &&Count <= size(). -4- Effects: Equivalent to: return {data() + (size() - Count), Count};template<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const;-?- Remarks: The program is ill-formed if:
-5- Requires:
Offset < 0 || (Count < 0 && Count != dynamic_extent), or
Extend != dynamic_extent && (Offset > Extent || (Count != dynamic_extent && Offset + Count > Extent)).
(0 <= Offset &&Offset <= size())&& (Count == dynamic_extent ||Count >= 0 &&Offset + Count <= size()). -6- Effects: Equivalent to: return span<ElementType, see below>( data() + Offset, Count != dynamic_extent ? Count : size() - Offset); -7- Remarks: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)
[2018-11-09; Tomasz provides updated wording]
I have decided to replace all Requires: elements in the section 22.7.3.3 [span.sub] to preserve consistency.
Previous resolution: [SUPERSEDED]This wording is relative to N4778.
Edit 22.7.3.3 [span.sub] as indicated:
template<ptrdiff_t Count> constexpr span<element_type, Count> first() const;-?- Mandates: Count >= 0 && (Extent == dynamic_extent || Count <= Extent).
-1-RequiresExpects:0 <= Count &&Count <= size(). -2- Effects: Equivalent to: return {data(), Count};template<ptrdiff_t Count> constexpr span<element_type, Count> last() const;-?- Mandates: Count >= 0 && (Extent == dynamic_extent || Count <= Extent).
-3-RequiresExpects:0 <= Count &&Count <= size(). -4- Effects: Equivalent to: return {data() + (size() - Count), Count};template<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const;-?- Mandates: Offset >= 0 && (Count >= 0 || Count == dynamic_extent) && (Extent == dynamic_extent || (Offset <= Extent && (Count == dynamic_extent || Offset + Count <= Extent))).
-5-RequiresExpects:(0 <= Offset &&Offset <= size())&& (Count == dynamic_extent ||Count >= 0 &&Offset + Count <= size()). -6- Effects: Equivalent to: return span<ElementType, see below>( data() + Offset, Count != dynamic_extent ? Count : size() - Offset); -7- Remarks: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)constexpr span<element_type, dynamic_extent> first(index_type count) const;-8-
-9- Effects: Equivalent to: return {data(), count};RequiresExpects: 0 <= count && count <= size().constexpr span<element_type, dynamic_extent> last(index_type count) const;-10-
-11- Effects: Equivalent to: return {data() + (size() - count), count};RequiresExpects: 0 <= count && count <= size().constexpr span<element_type, dynamic_extent> subspan( index_type offset, index_type count = dynamic_extent) const;-12-
-13- Effects: Equivalent to: return {data() + offset, count == dynamic_extent ? size() - offset : count};RequiresExpects: (0 <= offset && offset <= size()) && (count == dynamic_extent || count >= 0 && offset + count <= size())
[2019-06-23; Tomasz comments and provides updated wording]
The current proposed resolution no longer applies to the newest revision of the standard (N4820), due changes introduced in P1227 (making size() and template parameters of span unsigned).
[2019 Cologne Wednesday night]
Status to Ready
Proposed resolution:
This wording is relative to N4820.
[Drafting note: This wording relies on observation, that the condition in formExtent == dynamic_extent || Count <= Extent
, can be simplified intoCount <= Extent
, becausedynamic_extent
is equal tonumeric_limits<size_t>::max()
, thussize() <= Extent
is always true, andExtent == dynamic_extent
implies thatCount <= Extent
. Furthermore we check thatCount != dynamic_extent || Count <= Extent - Offset
, as theOffset + Count <= Extent
may overflow (defined for unsigned integers) and produce false positive result. This change is also applied to Expects clause. ]
Edit 22.7.3.3 [span.sub] as indicated:
template<size_t Count> constexpr span<element_type, Count> first() const;-?- Mandates: Count <= Extent is true.
-1- Expects: Count <= size() is true. -2- Effects: Equivalent to: return {data(), Count};template<size_t Count> constexpr span<element_type, Count> last() const;-?- Mandates: Count <= Extent is true.
-3- Expects: Count <= size() is true. -4- Effects: Equivalent to: return {data() + (size() - Count), Count};template<size_t Offset, size_t Count = dynamic_extent> constexpr span<element_type, see below> subspan() const;[…]-?- Mandates: Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset) is true.
-5- Expects: Offset <= size() && (Count == dynamic_extent ||Offset + Count <= size()Count <= size() - Offset) is true. -6- Effects: Equivalent to: return span<ElementType, see below>(data() + Offset, Count != dynamic_extent ? Count : size() - Offset); -7- Remarks: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)constexpr span<element_type, dynamic_extent> subspan( index_type offset, index_type count = dynamic_extent) const;-12- Expects: offset <= size() && (count == dynamic_extent ||
-13- Effects: Equivalent to: return {data() + offset, count == dynamic_extent ? size() - offset : count};offset + count <= size()count <= size() - offset) is true.
Section: 18.4.12 [concept.defaultconstructible] Status: Ready Submitter: Casey Carter Opened: 2018-08-09 Last modified: 2019-07-22
Priority: 2
View all issues with Ready status.
Discussion:
DefaultConstructible<T> is equivalent to Constructible<T> (18.4.11 [concept.constructible]), which is equivalent to is_constructible_v<T> (20.15.4.3 [meta.unary.prop]). Per 20.15.4.3 [meta.unary.prop] paragraph 8:
DefaultConstructible<T> requires that objects of type T can be value-initialized, rather than default-initialized as intended.The predicate condition for a template specialization is_constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(declval<Args>()...);
The library needs a constraint that requires object types to be default-initializable: the "rangified" versions of the algorithms in 20.10.11.3 [uninitialized.construct.default] proposed in P0896 "The One Ranges Proposal", for example. Users will also want a mechanism to provide such a constraint, and they're likely to choose DefaultConstructible despite its subtle unsuitability.
There are two alternative solutions: (1) change DefaultConstructible to require default-initialization, (2) change is_default_constructible_v to require default-initializaton and specify the concept in terms of the trait. (2) is probably too breaking a change to be feasible.
[2018-08-20 Priority set to 2 after reflector discussion]
Previous resolution [SUPERSEDED]:
Modify 18.4.12 [concept.defaultconstructible] as follows:
template<class T> concept DefaultConstructible = Constructible<T> && see below;-?- Type T models DefaultConstructible only if the variable definition
is well-formed for some invented variable t. Access checking is performed as if in a context unrelated to T. Only the validity of the immediate context of the variable initialization is considered.T t;
[2018-08-23 Tim provides updated P/R based on Batavia discussion]
[2018-10-28 Casey expands the problem statement and the P/R]
During Batavia review of P0896R3, Tim Song noted that {} is not necessarily a valid initializer for a DefaultConstructible type. In this sample program (see Compiler Explorer):
S1 can be default-initialized, but not list-initialized from an empty braced-init-list. The consensus among those present was that DefaultConstructible should prohibit this class of pathological types by requiring that initialization form to be valid.struct S0 { explicit S0() = default; }; struct S1 { S0 x; }; // Note: aggregate S1 x; // Ok S1 y{}; // ill-formed; copy-list-initializes x from {}
[2019 Cologne Wednesday night]
Status to Ready
Proposed resolution:
This wording is relative to N4762.
Modify 18.4.12 [concept.defaultconstructible] as follows:
template<class T> inline constexpr bool is-default-initializable = see below; // exposition only template<class T> concept DefaultConstructible = Constructible<T> && requires { T{}; } && is-default-initializable<T>;-?- For a type T, is-default-initializable<T> is true if and only if the variable definition
is well-formed for some invented variable t; otherwise it is false. Access checking is performed as if in a context unrelated to T. Only the validity of the immediate context of the variable initialization is considered.T t;
Section: 20.10.10.1 [allocator.members] Status: Ready Submitter: Casey Carter Opened: 2019-02-20 Last modified: 2019-07-22
Priority: 3
View other active issues in [allocator.members].
View all other issues in [allocator.members].
View all issues with Ready status.
Discussion:
20.10.10.1 [allocator.members]/2 says:
-2- Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropriately for objects of type T.
As in LWG 3038, we should not return too little storage for n objects of size sizeof(T), e.g. when n is SIZE_MAX / 2 and T is short.
[2019-03-05 Priority set to 3 after reflector discussion]
[2019 Cologne Wednesday night]
Status to Ready; will open additional issue to reconcile this and 3038
Proposed resolution:
This wording is relative to N4800.
Change 20.10.10.1 [allocator.members] as indicated:
[[nodiscard]] T* allocate(size_t n);[…]
-4- Throws: bad_array_new_length if SIZE_MAX / sizeof(T) < n, or bad_alloc if the storage cannot be obtained.
Section: 27.13 [time.parse] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-13 Last modified: 2019-07-23
Priority: 0
View other active issues in [time.parse].
View all other issues in [time.parse].
View all issues with Tentatively Ready status.
Discussion:
Currently, the '%d
' parse flags accepts the 'E
' modifier to parse the
locale's alternative representation, see Table 88 —
"Meaning of parse
flags":
The modified command
%Ed
interprets the locale's alternative representation of the day of the month.
This is inconsistent with the
POSIX
strftime
specification and the format functions, that uses 'O
'
to output alternate locale representation. Per Table 87 —
"Meaning of format
conversion specifiers":
The modified command
%Od
produces the locale's alternative representation.
[2019-06-24; Howard comments]
This was simply a type-o in my documentation that infected the proposal and subsequently the C++ working draft.
None of std::time_put, C's strftime, or POSIX's strftime support %Ed but all support %Od. Furthermore the existing example implementation supports %Od but not %Ed. And all the existing example implementation does is forward to std::time_put.[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4810.
Modify 27.13 [time.parse], Table 88 — "Meaning of parse
flags",
as indicated:
Table 88 — Meaning of parse
flagsFlag Parsed value […] %d The day of the month as a decimal number. The modified command %Nd specifies the maximum number of characters to read. If N is not specified, the default is 2. Leading zeroes are permitted but not required. The modified command % EOd interprets the locale's alternative representation of the day of the month.[…]
Section: 27.8.13.3 [time.cal.ym.nonmembers] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-16 Last modified: 2019-07-23
Priority: 0
View all issues with Tentatively Ready status.
Discussion:
The current specification of the addition of year_month
and
months
does not define a unique result value.
year(2019)/month(1)
and year(2018)/month(13)
are valid results of year(2018)/month(12) + months(1)
addition,
according to the spec in 27.8.13.3 [time.cal.ym.nonmembers].
[2019-06-24; LWG discussion]
During discussions on the LWG reflector there was a preference to add "is true" at the end of the modified Returns: element. This additional edit has been applied to Tomasz' original wording below.
[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4810.
Modify 27.8.13.3 [time.cal.ym.nonmembers] as indicated:
constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;-3- Returns: A year_month value z such that z.ok() && z - ym == dm is true.
Complexity: 𝒪(1) with respect to the value of dm.
Section: 25.9.8 [inclusive.scan], 25.9.10 [transform.inclusive.scan] Status: Tentatively Ready Submitter: Jonathan Wakely Opened: 2019-06-18 Last modified: 2019-07-23
Priority: 0
View all issues with Tentatively Ready status.
Discussion:
after applying P0574R1 to the working draft, 25.9.10 [transform.inclusive.scan] bullet 1.1 says "If init is provided, […]; otherwise, ForwardIterator1's value type shall be […]." 25.9.10 [transform.inclusive.scan] bullet 1.2 says "If init is provided, […]; otherwise, […] shall be convertible to ForwardIterator1's value type."
For the first overload init is not provided, but there is no ForwardIterator1, so these requirements cannot be met. The requirements for the first overload need to be stated in terms of InputIterator's value type, not ForwardIterator1's value type. The same problem exists in 25.9.8 [inclusive.scan]. 25.9.11 [adjacent.difference] solves this problem by saying "Let T be the value type of decltype(first)".[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4820.
Modify 25.9.8 [inclusive.scan] as indicated:
template<class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op); template<class InputIterator, class OutputIterator, class BinaryOperation, class T> OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, T init); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class T> ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init);-?- Let U be the value type of decltype(first).
-3- Requires:
(3.1) — If init is provided, T shall be Cpp17MoveConstructible (Table 26); otherwise,
ForwardIterator1's value typeU shall be Cpp17MoveConstructible.(3.2) — If init is provided, all of binary_op(init, init), binary_op(init, *first), and binary_op(*first, *first) shall be convertible to T; otherwise, binary_op(*first, *first) shall be convertible to
ForwardIterator1's value typeU.(3.3) — binary_op shall neither invalidate iterators or subranges, nor modify elements in the ranges [first, last] or [result, result + (last - first)].
Modify 25.9.10 [transform.inclusive.scan] as indicated:
template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class UnaryOperation> ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op); template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation, class T> OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op, T init); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryOperation, class UnaryOperation, class T> ForwardIterator2 transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op, T init);-?- Let U be the value type of decltype(first).
-1- Requires:
(1.1) — If init is provided, T shall be Cpp17MoveConstructible (Table 26); otherwise,
ForwardIterator1's value typeU shall be Cpp17MoveConstructible.(1.2) — If init is provided, all of
(1.2.1) — binary_op(init, init),
(1.2.2) — binary_op(init, unary_op(*first)), and
(1.2.3) — binary_op(unary_op(*first), unary_op(*first))
shall be convertible to T; otherwise, binary_op(unary_op(*first), unary_op(*first)) shall be convertible to
ForwardIterator1's value typeU.(1.3) — Neither unary_op nor binary_op shall invalidate iterators or subranges, nor modify elements in the ranges [first, last] or [result, result + (last - first)].
Section: 27.11.7.2 [time.zone.zonedtime.ctor] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-20 Last modified: 2019-07-23
Priority: 0
View other active issues in [time.zone.zonedtime.ctor].
View all other issues in [time.zone.zonedtime.ctor].
View all issues with Tentatively Ready status.
Discussion:
The zoned_time(TimeZonePtr z)
does not specify how the tp_
sub-element is initialized. It should be consistent with zoned_time(string_view)
that default initializes tp_
.
[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4820.
Modify 27.11.7.2 [time.zone.zonedtime.ctor] as indicated:
explicit zoned_time(TimeZonePtr z);-5- Requires: z refers to a time zone.
-6- Effects: Constructs a zoned_time by initializing zone_ with std::move(z) and default constructing tp_.
Section: 27.11.7.2 [time.zone.zonedtime.ctor] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-20 Last modified: 2019-07-23
Priority: 0
View other active issues in [time.zone.zonedtime.ctor].
View all other issues in [time.zone.zonedtime.ctor].
View all issues with Tentatively Ready status.
Discussion:
The zoned_time
constructor from zoned_time<Duration2,
TimeZonePtr>
(preserving same time zone, different precision of
representation) is currently marked noexcept. Given that the exposition-only
member tp_ of type sys_time<duration> has essentially type
time_point<system_clock, Duration>, this is incompatible with the
invoked time_point
constructor, which is not marked as noexcept.
[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4820.
Modify 27.11.7.1 [time.zone.zonedtime.overview], class template zoned_time synopsis, as indicated:
template<class Duration2> zoned_time(const zoned_time<Duration2, TimeZonePtr>& zt)noexcept;
Modify 27.11.7.2 [time.zone.zonedtime.ctor] as indicated:
template<class Duration2> zoned_time(const zoned_time<Duration2, TimeZonePtr>& y)noexcept;-9- Requires: Does not participate in overload resolution unless sys_time<Duration2> is implicitly convertible to sys_time<Duration>.
-10- Effects: Constructs a zoned_time by initializing zone_ with y.zone_ and tp_ with y.tp_.
Section: 27.13 [time.parse] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-29 Last modified: 2019-07-23
Priority: 0
View other active issues in [time.parse].
View all other issues in [time.parse].
View all issues with Tentatively Ready status.
Discussion:
The year format specifier ('y', 'Y') are missing the locale alternative
version ('%EY', '%Ey' and '%Oy'). That makes it inconsistent with the
POSIX
strftime
specification:
%Ey Replaced by the offset from %EC (year only) in the locale's alternative representation.
%EY Replaced by the full alternative year representation.
%Oy Replaced by the year (offset from %C) using the locale's alternative numeric symbols.
and parse
specifiers 27.13 [time.parse] that accepts these modified command.
[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4820.
[Drafting note: For the '%Oy' specifier we preserve consistency with the current specification for '%Od' and '%Oe' from Table 87 "Meaning of
format
conversion specifier" [tab:time.format.spec]:
%d […] The modified command
%Od
produces the locale's alternative representation.%e […] The modified command
%Oe
produces the locale's alternative representation.as their corresponding POSIX specification is matching one for '%Oy':
%Od Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading zeros if there is any alternative symbol for zero; otherwise, with leading <space> characters.
%Oe Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading <space> characters.
]
Modify "Table 87 — Meaning of format
conversion specifiers"
[tab:time.format.spec] as indicated:
Table 87 — Meaning of format conversion specifiers [tab:time.format.spec] Specifier Replacement […] %y The last two decimal digits of the year. If the result is a single digit it is prefixed by 0. The modified command %Oy
produces the locale's alternative representation. The modified command%Ey
produces the locale's alternative representation of offset from%EC
(year only).%Y The year as a decimal number. If the result is less than four digits it is left-padded with 0 to four digits. The modified command %EY
produces the locale's alternative full year representation.[…]
Section: 27.8.15.2 [time.cal.ymdlast.members] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-29 Last modified: 2019-08-05
Priority: 0
View all issues with Tentatively Ready status.
Discussion:
The current specification of the year_month_day_last::day
function does not cover the behaviour in the situation when year_month_day_last
value is not ok()
. To illustrate the sentence from
27.8.15.2 [time.cal.ymdlast.members] p13:
A
day
representing the last day of the (year
,month
) pair represented by*this
.
is unclear in the situation when month
member has
!ok
value, e.g. what is last day of 14th month of 2019.
ymdl.day()
(and by
consequence conversion to sys_days
/local_days
)
unspecified if ymdl.ok()
is false
. This make is
consistent with rest of the library, that produces unspecified values in
similiar situation, e.g.: 27.8.14.2 [time.cal.ymd.members] p18,
27.8.16.2 [time.cal.ymwd.members] p19,
27.8.17.2 [time.cal.ymwdlast.members] p14.
[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4820.
Modify 27.8.15.2 [time.cal.ymdlast.members] as indicated:
constexpr chrono::day day() const noexcept;-13- Returns: If ok() is true, returns a
-14- [Note: This value may be computed on demand. — end note]Aday representing the last day of the (year, month) pair represented by *this. Otherwise the returned value is unspecified.
Section: 27.11.7.1 [time.zone.zonedtime.overview] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-06-30 Last modified: 2019-07-23
Priority: 0
View all issues with Tentatively Ready status.
Discussion:
Currently, the time_zone
is always storing the time with
the precision not coarser that seconds
, as consequence any
instance with the duration with coarser precision with seconds
,
is de-facto equivalent to one instantiated to the duration of seconds.
This is caused by the fact, that time zone offset can be defined up to
seconds precision. To illustrate both of following specialization has
the same behavior (keep seconds
):
zoned_time<minutes> zt(current_zone(), floor<minutes>(system_clock::now()); zoned_time<hours> zt(current_zone(), floor<hours>(system_clock::now()); zoned_time<seconds> zt(current_zone(), floor<seconds>(system_clock::now());
To avoid unnecessary code bloat caused by above, most deduction guides
are instantiating zoned_time
with at least seconds
precision (i.e. zoned_time<seconds>
will be deduced
for all of above):
template<class TimeZonePtr, class Duration> zoned_time(TimeZonePtr, zoned_time<Duration>, choose = choose::earliest) -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>;
However there is single exception:
template<class Duration, class TimeZonePtr, class TimeZonePtr2> zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest) -> zoned_time<Duration, TimeZonePtr>;
This deduction guide should be updated to preserve the consistency of design.
[2019-07 Issue Prioritiztion]
Status to Tentatively Ready after five positive votes on the reflector.
Proposed resolution:
This wording is relative to N4820.
Modify 27.11.7.1 [time.zone.zonedtime.overview] as indicated:
[…] template<class Duration, class TimeZonePtr, class TimeZonePtr2> zoned_time(TimeZonePtr, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest) -> zoned_time<common_type_t<Duration, seconds>, TimeZonePtr>; […]