Revised 2019-06-17 at 05:09:46 UTC

Tentative Issues


2155(i). Macro __bool_true_false_are_defined should be removed

Section: 17.13 [support.runtime] Status: Tentatively Resolved Submitter: Thomas Plum Opened: 2012-04-30 Last modified: 2019-03-26

Priority: 4

View all other issues in [support.runtime].

View all issues with Tentatively Resolved status.

Discussion:

Since C99, the C standard describes a macro named __bool_true_false_are_defined.

In the process of harmonizing C++11 with C99, this name became part of the C++ standard.

I propose that all mention of this name should be removed from the C and C++ standards.

Here's the problem: The name was originally proposed as a transition tool, so that the headers for a project could contain lines like the following.

#if !defined(__bool_true_false_are_defined)
#define bool int /* or whatever */
#define true 1
#define false 0
#endif

Then when the project was compiled by a "new" compiler that implemented bool as defined by the evolving C++98 or C99 standards, those lines would be skipped; but when compiled by an "old" compiler that didn't yet provide bool, true, and false, then the #define's would provide a simulation that worked for most purposes.

It turns out that there is an unfortunate ambiguity in the name. One interpretation is as shown above, but a different reading says "bool, true, and false are #define'd", i.e. that the meaning of the macro is to assert that these names are macros (not built-in) ... which is true in C, but not in C++.

In C++11, the name appears in parentheses followed by a stray period, so some editorial change is needed in any event:

17.13 [support.runtime] para 1:

Headers <csetjmp> (nonlocal jumps), <csignal> (signal handling), <cstdalign> (alignment), <cstdarg> (variable arguments), <cstdbool> (__bool_true_false_are_defined). <cstdlib> (runtime environment getenv(), system()), and <ctime> (system clock clock(), time()) provide further compatibility with C code.

However, para 2 says

"The contents of these headers are the same as the Standard C library headers <setjmp.h>, <signal.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stdlib.h>, and <time.h>, respectively, with the following changes:",

and para 8 says

"The header <cstdbool> and the header <stdbool.h> shall not define macros named bool, true, or false."

Thus para 8 doesn't exempt the C++ implementation from the arguably clear requirement of the C standard, to provide a macro named __bool_true_false_are_defined defined to be 1.

Real implementations of the C++ library differ, so the user cannot count upon any consistency; furthermore, the usefulness of the transition tool has faded long ago.

That's why my suggestion is that both C and C++ standards should eliminate any mention of __bool_true_false_are_defined. In that case, the name belongs to implementers to provide, or not, as they choose.

[2013-03-15 Issues Teleconference]

Moved to Open.

While not strictly necessary, the clean-up look good.

We would like to hear from our C liaison before moving on this issue though.

[2015-05 Lenexa]

LWG agrees. Jonathan provides wording.

[2017-03-04, Kona]

The reference to <cstdbool> in p2 needs to be struck as well. Continue the discussion on the reflector once the DIS is available.

Previous resolution [SUPERSEDED]:

This wording is relative to N4296.

  1. Edit the footnote on 16.5.1.2 [headers] p7:

    176) In particular, including any of the standard headers <stdbool.h>, <cstdbool>, <iso646.h> or <ciso646> has no effect.

  2. Edit 17.13 [support.runtime] p1 as indicated (and remove the index entry for __bool_true_false_are_defined):

    -1- Headers <csetjmp> (nonlocal jumps), <csignal> (signal handling), <cstdalign> (alignment), <cstdarg> (variable arguments), <cstdbool>, (__bool_true_false_are_defined). <cstdlib> (runtime environment getenv(), system()), and <ctime> (system clock clock(), time()) provide further compatibility with C code.

  3. Remove Table 38 — Header <cstdbool> synopsis [tab:support.hdr.cstdbool] from 17.13 [support.runtime]

    Table 38 — Header <cstdbool> synopsis
    TypeName(s)
    Macro:__bool_true_false_are_defined

[2019-03-18; Daniel comments and eliminates previously proposed wording]

With the approval of P0619R4 in Rapperswil, the offending wording has now been eliminated from the working draft. I suggest to close this issue as: Resolved by P0619R4.

Rationale:

Resolved by P0619R4.

Proposed resolution:


2292(i). Find a better phrasing for "shall not participate in overload resolution"

Section: 16.4.1.4 [structure.specifications] Status: Tentatively Resolved Submitter: Jeffrey Yasskin Opened: 2013-09-03 Last modified: 2019-03-26

Priority: 3

View other active issues in [structure.specifications].

View all other issues in [structure.specifications].

View all issues with Tentatively Resolved status.

Discussion:

The C++14 CD has 25 sections including the phrase "X shall not participate in overload resolution ...". Most of these uses are double negatives, which are hard to interpret. "shall not ... unless" tends to be the easiest to read, since the condition is true when the function is available, but we also have a lot of "if X is not Y, then Z shall not participate", which actually means "You can call Z if X is Y." The current wording is also clumsy and long-winded. We should find a better and more concise phrasing.

As an initial proposal, I'd suggest using "X is enabled if and only if Y" in prose and adding an "Enabled If: ..." element to 16.4.1.4 [structure.specifications].

Daniel:

I suggest to name this new specification element for 16.4.1.4 [structure.specifications] as "Template Constraints:" instead, because the mentioned wording form was intentionally provided starting with LWG 1237 to give implementations more freedom to realize the concrete constraints. Instead of the original std::enable_if-based specifications we can use better forms of "SFINAE" constraints today and it eases the path to possible language-based constraints in the future.

[2019-03-21; Daniel comments ]

Apparently the adoption of P0788R3 at the Rapperswil 2018 meeting has resolved this issue by introduction of the new Constraints: element.

Rationale:

Resolved by P0788R3.

Proposed resolution:


2808(i). Requirements for fpos and stateT

Section: 29.5.4.2 [fpos.operations] Status: Tentatively Resolved Submitter: Great Britain Opened: 2016-11-09 Last modified: 2019-03-26

Priority: 4

View other active issues in [fpos.operations].

View all other issues in [fpos.operations].

View all issues with Tentatively Resolved status.

Discussion:

Addresses GB 60

The requirements on the stateT type used to instantiate class template fpos are not clear, and the following Table 108 — "Position type requirements" is a bit of a mess. This is old wording, and should be cleaned up with better terminology from the Clause 17 Requirements. For example, stateT might be require CopyConstructible?, CopyAssignable?, and Destructible. Several entries in the final column of the table appear to be post-conditions, but without the post markup to clarify they are not assertions or preconditions. They frequently refer to identifiers that do not apply to all entries in their corresponding Expression column, leaving some expressions without a clearly defined semantic. If stateT is a trivial type, is fpos also a trivial type, or is a default constructor not required/supported?

Proposed change:

Clarify the requirements and the table.

[Issues Telecon 16-Dec-2016]

Priority 4; no consensus for any concrete change

[2019-03-17; Daniel comments]

With the acceptance of P0759R1 at the Rapperswil 2018 meeting this issue should be closed as Resolved (Please note that this paper resolves a historic NB comment that was originally written against C++17 but was at that time responded: "invite a paper if anybody wants to change it - no concensus for change").

Rationale:

Resolved by P0759R1.

Proposed resolution:


2832(i). §[fpos.operations] strange requirement for P(i)

Section: 29.5.4.2 [fpos.operations] Status: Tentatively Resolved Submitter: Jens Maurer Opened: 2016-11-24 Last modified: 2019-03-26

Priority: 3

View other active issues in [fpos.operations].

View all other issues in [fpos.operations].

View all issues with Tentatively Resolved status.

Discussion:

This is from editorial issue #1031.

The first row in Table 112 "Position type requirements" talks about the expression P(i) and then has an assertion p == P(i). However, there are no constraints on p other than being of type P, so (on the face of it) this seems to require that operator== on P always returns true, which is non-sensical.

[2017-01-27 Telecon]

Priority 3

[2019-03-17; Daniel comments]

With the acceptance of P0759R1 at the Rapperswil 2018 meeting this issue should be closed as Resolved.

Rationale:

Resolved by P0759R1.

Proposed resolution:


2999(i). §[thread.decaycopy] issue

Section: 99 [thread.decaycopy] Status: Tentatively Resolved Submitter: Marshall Clow Opened: 2017-07-11 Last modified: 2019-03-26

Priority: 3

View all issues with Tentatively Resolved status.

Discussion:

[thread.decaycopy] says:

In several places in this Clause the operation DECAY_COPY(x) is used. All such uses mean call the function decay_copy(x) and use the result, where decay_copy is defined as follows:

but decay_copy is not defined in any synopsis.

The Ranges TS has a similar use of DECAY_COPY, except that theirs is also constexpr and noexcept.

We should mark the function decay_copy as "exposition only" and constexpr and noexcept.

[2017-07-16, Daniel comments]

Currently there exists no proper way to mark decay_copy as conditionally noexcept as explained in N3255 section "Adding to the Standard". This is also slighly related to the request to add an is_nothrow_convertible trait, as requested by LWG 2040.

[ 2017-11-01 P3 as result of c++std-lib online vote. ]

[2019-03-22; Daniel comments]

Starting with N4800 have now a constexpr and conditionally noexcept decay-copy in the working draft (16.4.2.1 [expos.only.func]). The pre-condition for that specification helper became possible by adoption of P0758R1, which introduced the missing is_nothrow_convertible trait.

Rationale:

Resolved by editorial creation of decay-copy after acceptance of P0758R1.

Proposed resolution:


3178(i). std::mismatch is missing an upper bound

Section: 25.5.10 [mismatch] Status: Tentatively Resolved Submitter: Geoffrey Romer Opened: 2018-12-20 Last modified: 2019-03-26

Priority: 0

View all other issues in [mismatch].

View all issues with Tentatively Resolved status.

Discussion:

Consider the following code:

std::vector<int> v1 = {1, 2, 3, 4};
std::vector<int> v2 = {1, 2, 3, 5};
auto result = std::mismatch(v1.begin(), v1.begin() + 2, v2.begin(), v2.begin() + 2);

The current wording of [mismatch] seems to require result to be {v1.begin() + 3, v2.begin() + 3}, because 3 is the smallest integer n such that *(v1.begin() + n) != *(v2.begin + n). In other words, if there's a mismatch that's reachable from first1 and first2, then std::mismatch must find and return it, even if it's beyond the end iterators passed by the user.

This is doubly unimplementable: the library has no way of knowing that it's safe to keep going past the end of the user-supplied range, and even if it could, doing so would violate the complexity requirements. More importantly, it would violate the fundamental convention that STL algorithms operate on user-supplied ranges, not on the underlying containers.

[2019-01-26 Priority to 0 and Status to Tentatively Ready after discussions on the reflector]

During that reflector discussion several contributers argued in favour for changing the current wording in 25.5.10 [mismatch] p3 from "smallest integer" to "smallest nonnegative integer". This minor wording delta has also been added to the original proposed wording.

Previous resolution [SUPERSEDED]:

This wording is relative to N4791.

  1. Change 25.5.10 [mismatch] as indicated:

    template<class InputIterator1, class InputIterator2>
      constexpr pair<InputIterator1, InputIterator2>
        mismatch(InputIterator1 first1, InputIterator1 last1,
                 InputIterator2 first2);
    […]
    namespace ranges {
      template<InputIterator I1, Sentinel<I1> S1, InputIterator I2, Sentinel<I2> S2,
               class Proj1 = identity, class Proj2 = identity,
               IndirectRelation<projected<I1, Proj1>,
               projected<I2, Proj2>> Pred = ranges::equal_to<>>
        constexpr mismatch_result<I1, I2>
          mismatch(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
                   Proj1 proj1 = {}, Proj2 proj2 = {});
      template<InputRange R1, InputRange R2,
               class Proj1 = identity, class Proj2 = identity,
               IndirectRelation<projected<iterator_t<R1>, Proj1>,
               projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to<>>
        constexpr mismatch_result<safe_iterator_t<R1>, safe_iterator_t<R2>>
          mismatch(R1&& r1, R2&& r2, Pred pred = {},
                   Proj1 proj1 = {}, Proj2 proj2 = {});
    }
    

    -1- Let last2 be first2 + (last1 - first1) for the overloads with no parameter last2 or r2.

    -2- Let E be:

    1. (2.1) — !(*(first1 + n) == *(first2 + n)) for the overloads with no parameter pred,

    2. (2.2) — pred(*(first1 + n), *(first2 + n)) == false for the overloads with a parameter pred and no parameter proj1,

    3. (2.3) — !invoke(pred, invoke(proj1, *(first1 + n)), invoke(proj2, *(first2 + n))) for the overloads with both parameters pred and proj1.

    -?- Let N be min(last1 - first1, last2 - first2).

    -3- Returns: { first1 + n, first2 + n }, where n is the smallest nonnegative integer such that E holds, or min(last1 - first1, last2 - first2)N if no such integer less than N exists.

    -4- Complexity: At most min(last1 - first1, last2 - first2)N applications of the corresponding predicate and any projections.

[2019-03-15; Daniel comments]

The editorial issue #2611 had been resolved via this pull request #2613. The editorial changes should make the suggested wording changes obsolete and I recommend to close this issue as Resolved.

Rationale:

Resolved by editorial pull request #2613.

Proposed resolution:


3183(i). Normative permission to specialize Ranges variable templates

Section: 23.3.4.8 [iterator.concept.sizedsentinel] Status: Tentatively Ready Submitter: Casey Carter Opened: 2019-01-14 Last modified: 2019-02-26

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

P0896R4 "The One Ranges Proposal" added boolean variable templates std::disable_sized_sentinel and std::ranges::disable_sized_range which users are intended to specialize to false for program-defined Iterator-Sentinel pairs / Range types which meet the syntax but do not model the semantics of the SizedSentinel / SizedRange concepts, respectively. Specializing these traits allows the use of such types with the library which would otherwise treat them as if they model SizedSentinel / SizedRange. The wording in P0896R4 failed, however, to provide normative permission to specialize these variable templates as is required by 16.5.4.2.1 [namespace.std] after the application of P0551R3.

Furthermore, 16.5.4.2.1 [namespace.std] notably does not require that program-defined specializations of standard library variable templates meet the requirements on the primary template (as is the case for class templates) or indeed any requirements. P0896R4 also added the enable_view variable template which is used to explicitly opt in or out of the View concept 24.4.4 [range.view] when the default chosen by the heuristic is incorrect. P0896R4 did include normative permission to specialize enable_view, but the wording does not place sufficient requirements on such user specializations so as to make them usable by the View concept definition. Specializations must be required to be usable as constant expressions of type bool to avoid hard errors in the concept.

[2019-02-03 Priority to 0 and Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4791.

[Drafting Note: This wording uses the recently-defined core language term "usable in constant expressions" from 7.7 [expr.const] paragraph 3 which may be unfamiliar to reviewers.]

  1. Change 23.3.4.8 [iterator.concept.sizedsentinel] as follows:

    […]

    (2.2) — If −N is representable by iter_difference_t<I>, then i - s is well-defined and equals −N.

    -?- Pursuant to 16.5.4.2.1 [namespace.std], users may specialize disable_sized_sentinel for cv-unqualified non-array object types S and I at least one of which is a program-defined type. Such specializations shall be usable in constant expressions (7.7 [expr.const]) and have type const bool.

    3 [Note: disable_sized_sentinel allows use of sentinels and iterators with the library that satisfy but do not in fact model SizedSentinel.—end note]

    […]

  2. Add an index entry for disable_sized_sentinel that points to [iterator.concepts.sizedsentinel].

  3. Change 24.4.3 [range.sized] as follows:

    […]

    3 [Note: The complexity requirement for the evaluation of ranges::size is non-amortized, unlike the case for the complexity of the evaluations of ranges::begin and ranges::end in the Range concept.—end note]

    -?- Pursuant to 16.5.4.2.1 [namespace.std], users may specialize disable_sized_range for cv-unqualified program-defined types. Such specializations shall be usable in constant expressions (7.7 [expr.const]) and have type const bool.

    4 [Note: disable_sized_range allows use of range types with the library that satisfy but do not in fact model SizedRange.—end note]

  4. Add an index entry for disable_sized_range that points to 24.4.3 [range.sized].

  5. Change 24.4.4 [range.view] as follows:

    […]

    5 Pursuant to 16.5.4.2.1 [namespace.std], users may specialize enable_view to true for cv-unqualified program-defined types which model View, and false for types which do not. Such specializations shall be usable in constant expressions (7.7 [expr.const]) and have type const bool.


3184(i). Inconsistencies in bind_front wording

Section: 99 [func.bind_front] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-01-16 Last modified: 2019-02-26

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

During the merge of the P0356R5, following "oddities" of the new wording was pointed out by Jens Maurer:

  1. The initialization of the state entities of the bind_front/not_fn is specified using formulation "xx initialized with the initializer (yyy)". Per author knowledge this specification is correct, however inconsistent with the other parts of the of the standard, that direct-non-list-initialization term in such context.

  2. The specification of the Mandates element for bind_front uses conjunction_v to specify conjunction of the requirements, while corresponding element of the not_fn specifies it using &&. As conjuction_v implies order of evaluation that is not necessary in this case (for every valid program, all provided traits must evaluate to true), it may be replaced with usage of fold expression with operator &&.

[2019-01-26 Priority to 0 and Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4791.

  1. Change 99 [func.not_fn] as indicated:

    template<class F> unspecified not_fn(F&& f);
    

    -1- In the text that follows:

    1. (1.1) — […]

    2. (1.2) — […]

    3. (1.3) — fd is the target object of g (20.14.2 [func.def]) of type FD direct-non-list-initialized withinitialized with the initializer (std::forward<F>(f)) (9.3 [dcl.init]),

    4. (1.4) — […]

  2. Change 99 [func.bind_front] as indicated:

    template <class F, class... Args>
    unspecified bind_front(F&& f, Args&&... args);
    

    -1- In the text that follows:

    1. (1.1) — […]

    2. (1.2) — […]

    3. (1.3) — fd is the target object of g (20.14.2 [func.def]) of type FD direct-non-list-initialized withinitialized with the initializer (std::forward<F>(f)) (9.3 [dcl.init]),

    4. (1.4) — […]

    5. (1.5) — bound_args is a pack of bound argument entities of g (20.14.2 [func.def]) of types BoundArgs..., direct-non-list-initialized withinitialized with initializers (std::forward<Args>(args))..., respectively, and

    6. (1.6) — […]

    -2- Mandates:

    is_constructible_v<FD, F> && is_move_constructible_v<FD> && 
    (is_constructible_v<BoundArgs, Args> && ...) && (is_move_constructible_v<BoundArgs> && ...)conjunction_v<is_constructible<FD, F>, is_move_constructible<FD>,
    is_constructible<BoundArgs, Args>..., is_move_constructible<BoundArgs>...>
    

    shall be true.


3185(i). Uses-allocator construction functions missing constexpr and noexcept

Section: 20.10.8.2 [allocator.uses.construction] Status: Tentatively Ready Submitter: Pablo Halpern Opened: 2019-01-29 Last modified: 2019-02-26

Priority: 0

View other active issues in [allocator.uses.construction].

View all other issues in [allocator.uses.construction].

View all issues with Tentatively Ready status.

Discussion:

The uses-allocator construction functions introduced into WP when P0591r4 was accepted (Nov 2018, San Diego) should all be constexpr. All but two should also be noexcept. Getting this right is an important part of correctly adding constexpr memory allocation into the WP.

The minimal change is to add the constexpr to all of the new functions except uninitialized_construct_using_allocator and noexcept to all of the overloads of uses_allocator_construction_args. Optionally, we could consider adding conditional noexcept to the remaining two functions. If p0784 is accepted, then also add constexpr to uninitialized_construct_using_allocator.

[2019-02-12 Priority to 0 and Status to Tentatively Ready after six positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4800.

  1. Change header <memory> synopsis, 20.10.2 [memory.syn], as indicated:

    […]
    // 20.10.8.2 [allocator.uses.construction], uses-allocator construction
    template <class T, class Alloc, class... Args>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept -> see below;
    template <class T, class Alloc, class Tuple1, class Tuple2>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
                                          Tuple1&& x, Tuple2&& y) noexcept -> see below;
    template <class T, class Alloc>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
    template <class T, class Alloc, class U, class V>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) noexcept -> see below;
    template <class T, class Alloc, class U, class V>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair<U,V>& pr) noexcept -> see below;
    template <class T, class Alloc, class U, class V>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair<U,V>&& pr) noexcept -> see below;
    template <class T, class Alloc, class... Args>
    constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
    template <class T, class Alloc, class... Args>
    T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
    […]
    
  2. Change 20.10.8.2 [allocator.uses.construction] as indicated:

    template <class T, class Alloc, class... Args>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class Tuple1, class Tuple2>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
                                            Tuple1&& x, Tuple2&& y) noexcept -> see below;
    

    […]

    template <class T, class Alloc>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class U, class V>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class U, class V>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair<U,V>& pr) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class U, class V>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair<U,V>&& pr) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class... Args>
      constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
    

    […]

    template <class T, class Alloc, class... Args>
      T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
    

    […]


3191(i). std::ranges::shuffle synopsis does not match algorithm definition

Section: 25.6.13 [alg.random.shuffle] Status: Tentatively Ready Submitter: Christopher Di Bella Opened: 2019-03-02 Last modified: 2019-06-16

Priority: 1

View all other issues in [alg.random.shuffle].

View all issues with Tentatively Ready status.

Discussion:

25.4 [algorithm.syn] declares std::ranges::shuffle like so:

namespace ranges {
  template<RandomAccessIterator I, Sentinel<I> S, class Gen>
    requires Permutable<I> &&
             UniformRandomBitGenerator<remove_reference_t<Gen>> &&
             ConvertibleTo<invoke_result_t<Gen&>, iter_difference_t<I>>
  I shuffle(I first, S last, Gen&& g);

  template<RandomAccessRange R, class Gen>
    requires Permutable<iterator_t<R> &&
             UniformRandomBitGenerator<remove_reference_t<Gen>> &&
             ConvertibleTo<invoke_result_t<Gen&>, iter_difference_t<iterator_t<R>>>
  safe_iterator_t<R> shuffle(R&& r, Gen&& g);
}

25.6.13 [alg.random.shuffle] defines the algorithm like so:

namespace ranges {
  template<RandomAccessIterator I, Sentinel<I> S, class Gen>
    requires Permutable<I> &&
             UniformRandomBitGenerator<remove_reference_t<Gen>>
  I shuffle(I first, S last, Gen&& g);

  template<RandomAccessRange R, class Gen>
    requires Permutable<iterator_t<R>> &&
             UniformRandomBitGenerator<remove_reference_t<Gen>>
  safe_iterator_t<R> shuffle(R&& r, Gen&& g);
}

Notice the missing ConvertibleTo requirements in the latter. Looking at the Ranges TS, [alg.random.shuffle] includes this requirement, albeit in the Ranges TS-format.

[2019-03-03; Daniel comments]

Given that the accepted proposal P0896R4 voted in San Diego did contain the same error I decided to open this issue instead of submitting an editorial change request.

[2019-03-05 Priority set to 1 after reflector discussion]

Casey: The correct fix here is to remove the ConvertibleTo requirement from the header synopsis. UniformRandomBitGenerators have integral result types, and the core language guarantees that all integral types are convertible to all other integral types. We don't need to validate the core language in the associated constraints of ranges::shuffle.

Previous resolution [SUPERSEDED]:

This wording is relative to N4800.

  1. Change 25.6.13 [alg.random.shuffle] as indicated:

    […]
    namespace ranges {
      template<RandomAccessIterator I, Sentinel<I> S, class Gen>
        requires Permutable<I> &&
                 UniformRandomBitGenerator<remove_reference_t<Gen>> &&
                 ConvertibleTo<invoke_result_t<Gen&>, iter_difference_t<I>>
        I shuffle(I first, S last, Gen&& g);
      template<RandomAccessRange R, class Gen>
        requires Permutable<iterator_t<R>> &&
                 UniformRandomBitGenerator<remove_reference_t<Gen>> &&
                 ConvertibleTo<invoke_result_t<Gen&>, iter_difference_t<iterator_t<R>>>
        safe_iterator_t<R> shuffle(R&& r, Gen&& g);
    }
    

[2019-03-05 Updated proposed wording according to Casey's suggestion]

[2019-06-16 Set to "Tentatively Ready" after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4800.

  1. Change 25.4 [algorithm.syn] as indicated:

    // 25.6.13 [alg.random.shuffle], shuffle
    […]
    namespace ranges {
      template<RandomAccessIterator I, Sentinel<I> S, class Gen>
        requires Permutable<I> &&
                 UniformRandomBitGenerator<remove_reference_t<Gen>> &&
                 ConvertibleTo<invoke_result_t<Gen&>, iter_difference_t<I>>
      I shuffle(I first, S last, Gen&& g);
    
      template<RandomAccessRange R, class Gen>
        requires Permutable<iterator_t<R> &&
                 UniformRandomBitGenerator<remove_reference_t<Gen>> &&
                 ConvertibleTo<invoke_result_t<Gen&>, iter_difference_t<iterator_t<R>>>
      safe_iterator_t<R> shuffle(R&& r, Gen&& g);
    }
    […]
    

3196(i). std::optional<T> is ill-formed is T is an array

Section: 20.6.3 [optional.optional] Status: Tentatively Ready Submitter: Jonathan Wakely Opened: 2019-03-18 Last modified: 2019-06-16

Priority: 0

View other active issues in [optional.optional].

View all other issues in [optional.optional].

View all issues with Tentatively Ready status.

Discussion:

20.6.3 [optional.optional] appears to allow arrays:

T shall be an object type other than cv in_place_t or cv nullopt_t and shall satisfy the Cpp17Destructible requirements (Table 30).

But instantiating it fails, because value_or attempts to return T by value, which isn't possible for an array type.

Existing practice seems to be to reject array types. Libstdc++ and libc++ give an error for the signature of value_or, and MSVC fails a static assert saying the type needs to be destructible (which is misleading, because int[2] is destructible, but either way it's ill-formed).

Previous resolution [SUPERSEDED]:

This wording is relative to N4810.

  1. Modify 20.6.3 [optional.optional] as indicated:

    -3- T shall be an non-array object type other than cv in_place_t or cv nullopt_t and shall satisfy the Cpp17Destructible requirements (Table 30).

[2019-03-26 Marshall provides updated resolution based on reflector discussion]

[2019-06-16 Moved to "Tentatively Ready" based on five positive votes on the reflector]

Proposed resolution:

This wording is relative to N4810.

  1. In 16.5.3.1 [utility.arg.requirements], edit Table 30 — "Cpp17Destructible requirements" as indicated:

    Table 30 — Cpp17Destructible requirements
    Expression Post-condition
    u.~T() All resources owned by u are reclaimed, no exception is propagated.
    [Note: Array types and non-object types are not Cpp17Destructible. — end note]
  1. Modify 20.6.3 [optional.optional] as indicated:

    -3- T shall be a object type other than cv in_place_t or cv nullopt_t and shall satisfythat meets the Cpp17Destructible requirements (Table 30).

  1. Modify 20.7.3 [variant.variant] as indicated:

    -2-All types in Types shall be (possibly cv-qualified) object types that are not arraysmeet the Cpp17Destructible requirements (Table 30).


3198(i). Bad constraint on std::span::span()

Section: 22.7.3.2 [span.cons] Status: Tentatively Ready Submitter: Lars Gullik Bjønnes Opened: 2019-04-03 Last modified: 2019-06-16

Priority: Not Prioritized

View all other issues in [span.cons].

View all issues with Tentatively Ready status.

Discussion:

It seems that this was left out of P1089. The constraint on span() (22.7.3.2 [span.cons]) in the current draft is:

Constraints: Extent <= 0 is true.

This does not seem to make much sense.

The proposal is to change the constraint to be:

Constraints: Extent == dynamic_extent || Extent == 0 is true.

[2019-06-09; Priority to 0 and Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 22.7.3.2 [span.cons] as indicated:

    constexpr span() noexcept;
    

    -1- Constraints: Extent <== dynamic_extent || Extent == 0 is true.


3199(i). istream >> bitset<0> fails

Section: 20.9.4 [bitset.operators] Status: Tentatively Ready Submitter: Davis Herring Opened: 2019-04-05 Last modified: 2019-06-16

Priority: Not Prioritized

View all other issues in [bitset.operators].

View all issues with Tentatively Ready status.

Discussion:

From a StackOverflow question:

[bitset.operators]/5.1 says that extracting a bitset<0> stops after reading 0 characters. /6 then says that, since no characters were stored, failbit is set.

[2019-06-09; Priority to 0 and Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 20.9.4 [bitset.operators] as indicated:

    template<class charT, class traits, size_t N>
      basic_istream<charT, traits>&
        operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
    

    […]

    -6- If N > 0 and no characters are stored in str, calls is.setstate(ios_base::failbit) (which may throw ios_base::failure (29.5.5.4 [iostate.flags])).


3202(i). P0318R1 was supposed to be revised

Section: 20.14.1 [functional.syn] Status: Tentatively Ready Submitter: Jonathan Wakely Opened: 2019-04-23 Last modified: 2019-06-16

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

P0318R1 was discussed in Batavia and the requested changes were made in D0318R2. In San Diego the R1 paper was voted into the WP, despite not having the requested changes. There were also changes to D0318R2 suggested on the reflector, which are incorporated below.

[2019-04-30 Priority to 0 and Status to Tentatively Ready after six positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 20.14.1 [functional.syn], header <functional> synopsis, as indicated:

    template<class T> struct unwrap_reference;
    template<class T> using unwrap_reference_t = typename unwrap_reference<T>::type;
    template<class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> {};
    template<class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
    
  2. Modify 20.14.5.6 [refwrap.unwrapref] as indicated:

    template<class T>
      struct unwrap_reference;
    

    -1- If T is a specialization […]

    template<class T>
      struct unwrap_ref_decay;
    

    -?- The member typedef type of unwrap_ref_decay<T> denotes the type unwrap_reference_t<decay_t<T>>.


3206(i). year_month_day conversion to sys_days uses not-existing member function

Section: 27.8.14.2 [time.cal.ymd.members] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-05-19 Last modified: 2019-06-16

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

The current specification of the year_month_day conversion function to sys_days, uses the day member function on the sys_days (a.k.a. time_point<system_clock, days>), that does not exist.

In 27.8.14.2 [time.cal.ymd.members] p18, the expression sys_days{y_/m_/last}.day() is ill-formed:

[…] Otherwise, if y_.ok() && m_.ok() is true, returns a sys_days which is offset from sys_days{y_/m_/last} by the number of days d_ is offset from sys_days{y_/m_/last}.day(). Otherwise the value returned is unspecified.

[2019-06-08; Priority to 0 and Status to Tentatively Ready after six positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 27.8.14.2 [time.cal.ymd.members] as indicated:

    constexpr operator sys_days() const noexcept;
    

    -18- Returns: If ok(), returns a sys_days holding a count of days from the sys_days epoch to *this (a negative value if *this represents a date prior to the sys_days epoch). Otherwise, if y_.ok() && m_.ok() is true, returns sys_days{y_/m_/1d} + (d_ - 1d)a sys_days which is offset from sys_days{y_/m_/last} by the number of days d_ is offset from sys_days{y_/m_/last}.day(). Otherwise the value returned is unspecified.


3207(i). N in ssize(const T (&)[N]) should be size_t

Section: 23.7 [iterator.range] Status: Tentatively NAD Submitter: Nevin Liber Opened: 2019-05-23 Last modified: 2019-06-16

Priority: Not Prioritized

View other active issues in [iterator.range].

View all other issues in [iterator.range].

Discussion:

The N in ssize(const T (&)[N]) is specified to be of type ptrdiff_t. It should be size_t to be consistent with the rest of the standard library, such as the array overloads for all other range access functions, the swap overload for arrays, and other function template overloads for arrays. (Note: the return type of this function should still be ptrdiff_t.)

[2019-06-12 Tentatively NAD after reflector discussion]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 23.7 [iterator.range] as indicated:

    template<class T, ptrdiffsize_t N> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept;
    

    -19- Returns: static_cast<ptrdiff_t>(N).


3208(i). Boolean's expression requirements are ordered inconsistently

Section: 23.7 [iterator.range] Status: Tentatively Ready Submitter: Casey Carter Opened: 2019-06-06 Last modified: 2019-06-16

Priority: 0

View other active issues in [iterator.range].

View all other issues in [iterator.range].

View all issues with Tentatively Ready status.

Discussion:

For consistency of presentation, we should group and order the && and || expression requirements similarly to the == and != expression requirements. Note that the suggested change is not quite editorial: evaluation of requirements for satisfaction has short-circuiting behavior, so the declaration order of requirements is normatively significant in general.

[2019-06-13; Priority to 0 and Status to Tentatively Ready after seven positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 18.5.2 [concept.boolean] as indicated:

    […]
      { b1 } -> ConvertibleTo<bool>;
      { !b1 } -> ConvertibleTo<bool>;
      { b1 &&  a } -> Same<bool>;
      { b1 ||  a } -> Same<bool>;
      { b1 && b2 } -> Same<bool>;
      { b1 &&  a } -> Same<bool>;
      {  a && b2 } -> Same<bool>;
      { b1 || b2 } -> Same<bool>;
      { b1 ||  a } -> Same<bool>;
      {  a || b2 } -> Same<bool>;
      { b1 == b2 } -> ConvertibleTo<bool>;
      { b1 ==  a } -> ConvertibleTo<bool>;
      {  a == b2 } -> ConvertibleTo<bool>;
      { b1 != b2 } -> ConvertibleTo<bool>;
      { b1 !=  a } -> ConvertibleTo<bool>;
      {  a != b2 } -> ConvertibleTo<bool>;
    };
    

3209(i). Expression in year::ok() returns clause is ill-formed

Section: 27.8.5.2 [time.cal.year.members] Status: Tentatively Ready Submitter: Tomasz Kamiński Opened: 2019-05-28 Last modified: 2019-06-16

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

The expression in the Returns element of year::ok in [time.cal.year.members] p18:

min() <= y_ && y_ <= max()

is ill-formed, as it attempts to compare type short (type of y_ member) with type year (type of year::min() and year::max()).

[2019-06-13; Priority to 0 and Status to Tentatively Ready after seven positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4810.

  1. Modify 27.8.5.2 [time.cal.year.members] as indicated:

    constexpr bool ok() const noexcept;
    

    -18- Returns: min().y_ <= y_ && y_ <= max().y_.