Revised 2012-11-03 at 04:11:23 UTC

## Tentative Issues

### 2078. Throw specification of `async()` incomplete

Section: 30.6.8 [futures.async] Status: Tentatively NAD Editorial Submitter: Nicolai Josuttis Opened: 2011-08-29 Last modified: 2012-11-02

View other active issues in [futures.async].

View all other issues in [futures.async].

View all issues with Tentatively NAD Editorial status.

Discussion:

The current throw specification of `async()` does state:

> -6- Throws: `system_error` if policy is `launch::async` and the implementation is unable to start a new thread.

First it seems not clear whether this only applies if policy equals `launch::async` of if the `async` launch mode flag is set (if `policy|launch::async!=0`)

In the discussion Lawrence Crowl also wrote:

> More generally, I think what we want to say is that if the implementation cannot successfully execute on one of the policies allowed, then it must choose another. The principle would apply to implementation-defined policies as well.

Peter Sommerlad:

> Should not throw. That was the intent. "is async" meat exactly.

[2012, Portland: move to Tentatively NAD Editorial]

If no launch policy, it is undefined behavior.

Agree with Lawrence, should try all the allowed policies. We will rephrase so that the policy argument should be `lauch::async`. Current wording seems good enough.

We believe this choice of policy statement is really an editorial issue.

Proposed resolution:

### 2080. Specify when `once_flag` becomes invalid

Section: 30.4.4 [thread.once] Status: Tentatively Ready Submitter: Nicolai Josuttis Opened: 2011-08-30 Last modified: 2012-11-02

View all issues with Tentatively Ready status.

Discussion:

In function `call_once` 30.4.4.2 [thread.once.callonce] paragraph 4 and 5 specify for `call_once()`:

> Throws: `system_error` when an exception is required (30.2.2 [thread.req.exception]), or any exception thrown by `func`.

> Error conditions:
> - `invalid_argument` — if the `once_flag` object is no longer valid.

However, nowhere in 30.4.4 [thread.once] is specified, when a once-flag becomes invalid.

As far as I know this happens if the flag is used for different functions. So we either have to have to insert a sentence/paragraph in

> 30.4.4.2 Function call_once [thread.once.callonce]

or

> 30.4.4 Call once [thread.once]

explaining when a `once_flag` becomes invalidated or we should state as error condition something like:

- `invalid_argument` — if the `func` used in combination with the `once_flag` is different from a previously passed `func` for the same `once_flag`

Anthony Williams:

> A `once_flag` is invalidated if you destroy it (e.g. it is an automatic object, or heap allocated and deleted, etc.)

> If the library can detect that this is the case then it will throw this exception. If it cannot detect such a case then it will never be thrown.

Jonathan Wakely:

> I have also wondered how that error can happen in C++, where the type system will reject a non-callable type being passed to `call_once()` and should prevent a `once_flag` being used after its destructor runs.

> If a `once_flag` is used after its destructor runs then it is indeed undefined behaviour, so implementations are already free to throw any exception (or set fire to a printer) without the standard saying so.

> My assumption was that it's an artefact of basing the API on pthreads, which says:

> > The `pthread_once()` function may fail if:

> > `[EINVAL]` If either `once_control` or `init_routine` is invalid.

Pete Becker:

> Yes, probably. We had to clean up several UNIXisms that were in the original design.

[2012, Kona]

Remove error conditions, move to Review.

[2012, Portland: move to Tentatively Ready]

Concurrency move to Ready, pending LWG review.

LWG did not have time to perform the final review in Portland, so moving to tentatively ready to reflect the Concurrency belief that the issue is ready, but could use a final inspection from library wordsmiths.

Proposed resolution:

This wording is relative to N3337.

1. Change 30.4.4.2 [thread.once.callonce] as indicated:

   >     template<class Callable, class ...Args>
   >     void call_once(once_flag& flag, Callable&& func, Args&&... args);

   > > […]

   > > -4- Throws: `system_error` when an exception is required (30.2.2), or any exception thrown by `func`.

   > > -5- Error conditions:
   > > - `invalid_argument` — if the `once_flag` object is no longer valid.

### 2106. `move_iterator` wrapping iterators returning prvalues

Section: 24.5.3 [move.iterators] Status: Tentatively Ready Submitter: Dave Abrahams Opened: 2011-11-30 Last modified: 2012-11-02

View all other issues in [move.iterators].

View all issues with Tentatively Ready status.

Discussion:

Shouldn't `move_iterator` be specialized so that if the iterator it wraps returns a prvalue when dereferenced, the `move_iterator` also returns by value? Otherwise, it creates a dangling reference.

Howard: I believe just changing `move_iterator<I>::reference` would do. A direction might be testing on `is_reference<iterator_traits<I>::reference>`, or `is_reference<decltype(*declval<I>())>`.

Daniel: I would prefer to use a consistent style among the iterator adaptors, so I suggest to keep with the `iterator_traits` typedefs if possible.

>     using reference = typename conditional<
>       is_reference<typename iterator_traits<Iterator>::reference>::value,
>       value_type&&,
>       value_type
>     >::type;

We might also want to ensure that if `Iterator`'s `reference` type is a reference, the referent is equal to `value_type` (after removal of cv-qualifiers). In general we have no such guarantee.

Marc: In the default case where we don't return `value_type&&`, should we use `value_type` or should we keep the `reference` type of the wrapped iterator?

Daniel: This suggestion looks appealing at first, but the problem here is that using this typedef can make it impossible for `move_iterator` to satisfy its contract, which means returning an rvalue of the value type (Currently it says rvalue-reference, but this must be fixed as of this issue anyway). I think that user-code can reasonably expect that when it has constructed an object `m` of `move_iterator<It>`, where `It` is a valid mutable iterator type, the expression

>     It::value_type&& rv = *m;

is well-formed.

Let's set `R` equal to `iterator_traits<Iterator>::reference` in the following. We can discuss the following situations:

1. `R` is a reference type: We can only return the corresponding xvalue of `R`, if `value_type` is reference-related to the referent type, else this is presumably no forward iterator and we cannot say much about it, except that it must be convertible to `value_type`, so it better should return a prvalue.
2. `R` is not a reference type: In this case we can rely on a conversion to `value_type` again, but not much more. Assume we would return `R` directly, this might turn out to have a conversion to an lvalue-reference type of the value type (for example). If that is the case, this would indirectly violate the contract of `move_iterator`.

In regard to the first scenario I suggest that implementations are simply required to check that `V2 = remove_cv<remove_reference<R>::type>::type` is equal to the value type `V1` as a criterion to return this reference as an xvalue, in all other cases it should return the value type directly as prvalue.

The additional advantage of this strategy is, that we always ensure that `reference` has the correct cv-qualification, if `R` is a real reference.

It is possible to improve this a bit by indeed supporting reference-related types, this would require to test `is_same<V1, V2>::value || is_base_of<V1, V2>::value` instead. I'm unsure whether (a) this additional effort is worth it and (b) a strict reading of the forward iterator requirements seems not to allow to return a reference-related type (Whether this is a defect or not is another question).

[2011-12-05: Marc Glisse comments and splits into two resolution alternatives]

I guess I am looking at the speed of:

>     value_type x;
>     x = *m;

(copy construction would likely trigger copy elision and thus be neutral) instead of the validity of:

>     value_type&& x = *m;

In this sense, Daniels earlier proposition that ignored `value_type` and just did switch_lvalue_ref_to_rvalue_ref<reference> was easier to understand (and it didn't require thinking about reference related types).

The currently proposed resolution has been split into two alternatives.

[2012, Kona]

Move to Review.

Alisdair: This only applies to input iterators, so keep that in mind when thinking about this.

STL: I see what B is doing, but not A.

Howard: I agree.

Alisdair: Should we use `add_rvalue_reference`?

STL: No, we do not want reference collapsing.

STL: Re A, messing with the CV qualification scares me.

Alisdair: Agree. That would break my intent.

STL: Actually I don't think it's actually wrong, but I still don't see what it's doing.

Alisdair: A is picking the value type, B is picking the proxy type.

Howard: I like returning the proxy type.

STL: Returning a reference (B) seems right, because the requirements say "reference". I suspect that B works correctly if you have a move iterator wrapping a move iterator wrapping a thing. I think that A would mess up the type in the middle.

Considerable discussion about which version is correct, checking various examples.

STL: Still think B is right. Still don't understand A. In A we are losing the proxyness.

Howard: Agree 100%. We don't want to lose the proxy. If it's const, so be it.

STL: B is also understandable by mortals.

Howard: Remove to review, keep A but move it out of the proposed resolution area (but keep it for rational).

Alisdair: Adding an explanatory note might be a good idea, if someone wants to write one.

Walter: Concerned about losing the word "reference" in p.1.

Howard: `move_iterator` will return an xvalue or a prvalue, both of which are rvalues.

[Proposed resolution A, rejected in preference to the currently proposed resolution (B)

1. Change 24.5.3 [move.iterators] p1 as indicated:

   > Class template `move_iterator` is an iterator adaptor with the same behavior as the underlying iterator except that its dereference operator implicitly converts the value returned by the underlying iterator’s dereference operator to an rvalue reference of the value type. Some generic algorithms can be called with move iterators to replace copying with moving.

2. Change 24.5.3.1 [move.iterator], class template `move_iterator` synopsis, as indicated:

   >     namespace std {
   >       template <class Iterator>
   >       class move_iterator {
   >       public:
   >         typedef Iterator iterator_type;
   >         typedef typename iterator_traits<Iterator>::difference_type difference_type;
   >         typedef Iterator pointer;
   >         typedef typename iterator_traits<Iterator>::value_type value_type;
   >         typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
   >         typedef value_type&&see below reference;
   >         […]
   >       };
   >     }

3. Immediately following the class template `move_iterator` synopsis in 24.5.3.1 [move.iterator] insert a new paragraph as indicated:

   > -?- Let `R` be `iterator_traits<Iterator>::reference` and let `V` be `iterator_traits<Iterator>::value_type`. If `is_reference<R>::value` is `true` and if `remove_cv<remove_reference<R>::type>::type` is the same type as `V`, the template instantiation `move_iterator<Iterator>` shall define the nested type named `reference` as a synonym for `remove_reference<R>::type&&`, otherwise as a synonym for `V`.

]

[2012, Portland: Move to Tentatively Ready]

AJM wonders if the implied trait might be useful elsewhere, and worth adding to type traits as a transformation type trait.

Suspicion that the Range SG might find such a trait useful, but wait until there is clear additional use of such a trait before standardizing.

Minor wording tweak to use `add_rvalue_reference` rather than manually adding the `&&`, then move to Tentatively Ready.

Proposed resolution:

This wording is relative to the FDIS.

This section shows two mutually exclusive resolutions — only one can be picked!

1. Change 24.5.3 [move.iterators] p1 as indicated:

   > Class template `move_iterator` is an iterator adaptor with the same behavior as the underlying iterator except that its dereference operator implicitly converts the value returned by the underlying iterator’s dereference operator to an rvalue reference. Some generic algorithms can be called with move iterators to replace copying with moving.

2. Change 24.5.3.1 [move.iterator], class template `move_iterator` synopsis, as indicated:

   >     namespace std {
   >       template <class Iterator>
   >       class move_iterator {
   >       public:
   >         typedef Iterator iterator_type;
   >         typedef typename iterator_traits<Iterator>::difference_type difference_type;
   >         typedef Iterator pointer;
   >         typedef typename iterator_traits<Iterator>::value_type value_type;
   >         typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
   >         typedef value_type&&see below reference;
   >         […]
   >       };
   >     }

3. Immediately following the class template `move_iterator` synopsis in 24.5.3.1 [move.iterator] insert a new paragraph as indicated:

   > -?- Let `R` be `iterator_traits<Iterator>::reference`. If `is_reference<R>::value` is `true`, the template instantiation `move_iterator<Iterator>` shall define the nested type named `reference` as a synonym for `add_rvalue_reference<R>::type`, otherwise as a synonym for `R`.

### 2109. Incorrect requirements for `hash` specializations

Section: 19.5.5 [syserr.hash], 20.7.2.6 [util.smartptr.hash], 20.8.12 [unord.hash], 20.13.1 [type.index.synopsis], 21.6 [basic.string.hash], 23.3.7 [vector.bool], 30.3.1.1 [thread.thread.id] Status: Tentatively Ready Submitter: Daniel Krügler Opened: 2011-12-04 Last modified: 2012-11-02

View all issues with Tentatively Ready status.

Discussion:

20.7.2.6 [util.smartptr.hash] p2 is specified as follows:

> Requires: the template specializations shall meet the requirements of class template `hash` (20.8.12).

The problem here is the usage of a Requires element, which is actually a pre-condition that a user of a component has to satisfy. But the intent of this wording is actually to be a requirement on implementations. The Requires element should be removed here and the wording should be improved to say what it was intended for.

We have similar situations in basically all other places where the specification of library-provided `hash` specializations is defined. Usually, the Requires element is incorrect. In the special case of `hash<unique_ptr<T, D>>` the implementation depends on the behaviour of `hash` specializations, that could be user-provided. In this case the specification needs to separate the requirements on these specializations and those that are imposed on the implementation.

[2012, Kona]

Update wording and move to Review.

Believe a simpler formulation is to simply string the term Requires: and leave the current wording intact, rather than strike the whole clause and replace it.

[Originally proposed wording for reference

1. Change 19.5.5 [syserr.hash] as indicated:

   >     template <> struct hash<error_code>;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<system_error>` provides a definition for a specialization of the template `hash<error_code>`. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash].

2. Change 20.5.3 [bitset.hash] as indicated:

   >     template <size_t N> struct hash<bitset<N> >;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<bitset>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `bitset<N>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash].

3. Change 20.7.2.6 [util.smartptr.hash] as indicated:

   >     template <class T, class D> struct hash<unique_ptr<T, D> >;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<memory>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `unique_ptr<T, D>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object `p` of type `UP`, where `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the same value as `hash<typename UP::pointer>()(p.get())`. The specialization `hash<typename UP::pointer>` shall be well-formed.

   > > -?- Requires: The specialization `hash<typename UP::pointer>` shall be well-formed and well-defined [Note: the general requirements of class template `hash` (20.8.12 [unord.hash]) are implied — end note].

   >     template <class T> struct hash<shared_ptr<T> >;

   > > -2- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<memory>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `shared_ptr<T>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object `p` of type `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same value as `hash<T*>()(p.get())`.

4. Change 20.8.12 [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]

   >     template <> struct hash<bool>;
   >     template <> struct hash<char>;
   >     […]
   >     template <> struct hash<long double>;
   >     template <class T> struct hash<T*>;

   > > -2- Requires: the template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<functional>` provides definitions for specializations of the `hash` class template for each cv-unqualified arithmetic type except for the extended integer types. This header also provides a definition for a partial specialization of the `hash` class template for any pointer type. The requirements for the members of these specializations are given in sub-clause 20.8.12 [unord.hash].

5. Change 20.13.4 [type.index.hash] p1 as indicated:

   >     template <> struct hash<type_index>;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<typeindex>` provides a definition for a specialization of the template `hash<type_index>`. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object `index` of type `type_index`, `hash<type_index>()(index)` shall evaluate to the same result as `index.hash_code()`.

6. Change 21.6 [basic.string.hash] p1 as indicated:

   >     template <> struct hash<string>;
   >     template <> struct hash<u16string>;
   >     template <> struct hash<u32string>;
   >     template <> struct hash<wstring>;

   > > -1- Requires: the template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<string>` provides definitions for specializations of the `hash` class template for the types `string`, `u16string`, `u32string`, and `wstring`. The requirements for the members of these specializations are given in sub-clause 20.8.12 [unord.hash].

7. Change 23.3.7 [vector.bool] p7 as indicated:

   >     template <class Allocator> struct hash<vector<bool, Allocator> >;

   > > -7- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<vector>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `vector<bool, Allocator>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash].

8. Change 30.3.1.1 [thread.thread.id] p14 as indicated:

   >     template <> struct hash<thread::id>;

   > > -14- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<thread>` provides a definition for a specialization of the template `hash<thread::id>`. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash].

]

[2012, Portland: Move to Tentatively Ready]

No further wording issues, so move to Tentatively Ready (post meeting issues processing).

Proposed resolution:

1. Change 19.5.5 [syserr.hash] as indicated:

   >     template <> struct hash<error_code>;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash].

2. Change 20.5.3 [bitset.hash] as indicated:

   >     template <size_t N> struct hash<bitset<N> >;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

3. Change 20.7.2.6 [util.smartptr.hash] as indicated:

   >     template <class T, class D> struct hash<unique_ptr<T, D> >;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]). For an object `p` of type `UP`, where `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the same value as `hash<typename UP::pointer>()(p.get())`. The specialization `hash<typename UP::pointer>` shall be well-formed.

   > > -?- Requires: The specialization `hash<typename UP::pointer>` shall be well-formed and well-defined, and shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

   >     template <class T> struct hash<shared_ptr<T> >;

   > > -2- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]). For an object `p` of type `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same value as `hash<T*>()(p.get())`.

4. Change 20.8.12 [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]

   >     template <> struct hash<bool>;
   >     template <> struct hash<char>;
   >     […]
   >     template <> struct hash<long double>;
   >     template <class T> struct hash<T*>;

   > > -2- Requires: t The template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

5. Change 20.13.4 [type.index.hash] p1 as indicated:

   >     template <> struct hash<type_index>;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]). For an object `index` of type `type_index`, `hash<type_index>()(index)` shall evaluate to the same result as `index.hash_code()`.

6. Change 21.6 [basic.string.hash] p1 as indicated:

   >     template <> struct hash<string>;
   >     template <> struct hash<u16string>;
   >     template <> struct hash<u32string>;
   >     template <> struct hash<wstring>;

   > > -1- Requires: t The template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

7. Change 23.3.7 [vector.bool] p7 as indicated:

   >     template <class Allocator> struct hash<vector<bool, Allocator> >;

   > > -7- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

8. Change 30.3.1.1 [thread.thread.id] p14 as indicated:

   >     template <> struct hash<thread::id>;

   > > -14- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

### 2125. `TimedMutex` specification problem

Section: 30.4.1.3 [thread.timedmutex.requirements], 30.4.1.3.1 [thread.timedmutex.class] Status: Tentatively NAD Editorial Submitter: Vicente J. Botet Escriba Opened: 2012-01-01 Last modified: 2012-11-02

View other active issues in [thread.timedmutex.requirements].

View all other issues in [thread.timedmutex.requirements].

View all issues with Tentatively NAD Editorial status.

Discussion:

30.4.1.3.1 [thread.timedmutex.class] says:

> The class `timed_mutex` shall satisfy all of the `TimedMutex` requirements (30.4.1.3 [thread.timedmutex.requirements]). It shall be a standardlayout class (Clause 9 [class]).

Problem here is that 30.4.1.3 [thread.timedmutex.requirements] does not define a requirement set named "`TimedMutex`", it only refers to "timed mutex types"

[See also issue 2126]

[2012, Portland: move to Tentatively NAD Editorial]

We have timed mutex type, but it is labeled timed mutex requirements

We can make a suggestion, but will send to the editor as it seems purely editorial. There is a typo, and we don't have the timed mutex but 30.4.1.3 [thread.timedmutex.requirements] already says timed mutex type, and we need to reuse that term down in the class to fulfil the mutex requirement.

[To Editor:]

Replace this one with timed mutex type.

Proposed resolution:

### 2126. Several specification problems in regard to mutex requirements

Section: 30.4.1 [thread.mutex.requirements], 30.4.1.2.1 [thread.mutex.class], 30.4.1.2 [thread.mutex.requirements.mutex], 30.4.1.2.2 [thread.mutex.recursive], 30.4.1.3 [thread.timedmutex.requirements], 30.4.1.3.1 [thread.timedmutex.class], 30.4.1.3.2 [thread.timedmutex.recursive] Status: Tentatively NAD Editorial Submitter: Pete Becker Opened: 2012-01-16 Last modified: 2012-11-02

View all other issues in [thread.mutex.requirements].

View all issues with Tentatively NAD Editorial status.

Discussion:

30.4.1.2.1 [thread.mutex.class]/3 says that the class mutex "shall satisfy all the `Mutex` requirements (30.4.1 [thread.mutex.requirements])". 30.4.1.2.1 [thread.mutex.class] is part of 30.4.1 [thread.mutex.requirements], so at the very least, this requirement is recursive. But worse, there is nothing that says what "the `Mutex` requirements" refers to. For example, the "`Lockable` requirements" section starts with "A type `L` meets the `Lockable` requirements if …". There is no such statement for "the `Mutex` requirements".

Organizationally, paragraphs 1-26 in 30.4.1.2 [thread.mutex.requirements.mutex] should probably be in a subclause with a name. (This is actually an ISO requirement, to avoid exactly this kind of ambiguous referencing) Then the first sentence of 30.4.1.2.1 [thread.mutex.class]/3 can become a note: "The class mutex meets the requirements of (whatever)", since that subclause already says that the mutex types "shall meet the requirements set out in this section."

And similarly for 30.4.1.2.2 [thread.mutex.recursive]/2 (`recursive_mutex`).

30.4.1.3 [thread.timedmutex.requirements], Timed mutex types, also needs the same rearrangement: its introductory requirements should be moved into a subclause, and the first sentences of 30.4.1.3.1 [thread.timedmutex.class]/2 and 30.4.1.3.2 [thread.timedmutex.recursive]/2 should be turned into notes that refer to this new subclause and to the new subclause in 30.4.1.2 [thread.mutex.requirements.mutex].

[See also issue 2125]

[2012, Portland: move to Tentatively NAD Editorial]

Seems no real ambiguity. May need some reorg of text rather then changing the wording.

Is there much that needs to be changed? But Pete's suggestion of putting requirement in separate sub section is good. Should be the direction to editor.

Suggest this is an editorial change. Happy with Pete's comments.

Proposed resolution:

### 2134. Redundant Mutex requirement?

Section: 30.4.1.2 [thread.mutex.requirements.mutex] Status: Tentatively NAD Editorial Submitter: Pete Becker Opened: 2012-03-05 Last modified: 2012-11-02

View all other issues in [thread.mutex.requirements.mutex].

View all issues with Tentatively NAD Editorial status.

Discussion:

30.4.1.2 [thread.mutex.requirements.mutex]/11 says that prior unlock operations synchronize with `m.lock()`.

30.4.1.2 [thread.mutex.requirements.mutex]/19 says that if `m.try_lock()` succeeds, prior unlock operations synchronize with the operation.

30.4.1.2 [thread.mutex.requirements.mutex]/25 says that `m.unlock()` synchronizes with subsequent successful lock operations.

Does the third requirement add anything to the first two? If not, it should probably be a non-normative note.

[2012, Portland: move to Tentatively NAD Editorial]

Agree that third note should be non-normative and adds nothing.

Seems An Editorial change, but does changing a normative to non-normative wording makes it a non-editorial change?

Ask the editor. If not editorial, then we will agree on the fix as removal of the third point, then we will put it in ready state for Bristol.

Proposed resolution:

### 2167. Copy assignment requirements of Containers

Section: 23.2.1 [container.requirements.general] Status: Tentatively NAD Submitter: Dean Michael Berris Opened: 2012-07-13 Last modified: 2012-11-02

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

Discussion:

Table 96 defines the general requirement for copy assignment (row 23, page 704) as:

Table 96 — Container requirements
Expression | Return type | Operational semantics | Assertion/note pre-/post-condition | Complexity
--- | --- | --- | --- | ---
`r = a` | `X&` | `` | post: `r == a.` | linear

However there is no requirement that `T` is `CopyInsertable` into `X`.

[2012, Portland: Move to Tentatively NAD]

Howard notes that this may be a difficult requirement for `std::array`

We already have this requirement for allocator aware containers, and `std::array` already adds the appropriate extra requirement.

We say the necessary things in the necessary places, but the container requirements continue to cause confusion in where we sometimes say things. Consensus is that this issue remains NAD though.

Proposed resolution:

This wording is relative to N3376.

1. Change Table 96 — "Container requirements" in 23.2.1 [container.requirements.general]:

   Table 96 — Container requirements
   Expression | Return type | Operational semantics | Assertion/note pre-/post-condition | Complexity
   --- | --- | --- | --- | ---
   `r = a` | `X&` | `` | Requires: `T` is `CopyInsertable` into `X`. post: `r == a.` | linear

### 2177. Requirements on `Copy/MoveInsertable`

Section: 23.2.1 [container.requirements.general] Status: Tentatively Ready Submitter: Loïc Joly Opened: 2012-08-10 Last modified: 2012-11-02

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

View all issues with Tentatively Ready status.

Discussion:

See also discussion following c++std-lib-32883 and c++std-lib-32897.

The requirements on `CopyInsertable` and `MoveInsertable` are either incomplete, or complete but hard to figure out.

From e-mail c++std-lib-32897:

Pablo Halpern:

I agree that we need semantic requirements for all of the `*Insertable` concepts analogous to the requirements we have on similar concepts.

Howard Hinnant:

I've come to believe that the standard is actually correct as written in this area. But it is really hard to read. I would have no objection whatsoever to clarifications to `CopyInsertable` as you suggest (such as the post-conditions on `v`). And I do agree with you that the correct approach to the clarifications is to confirm that `CopyInsertable` implies `MoveInsertable`.

[2012, Portland: Move to Tentatively Ready]

Move to Tentatively Ready by unanimous consent.

Proposed resolution:

This wording is relative to N3376.

1. Edit 23.2.1 [container.requirements.general] p13 as indicated:

   > -13- […] Given a container type `X` having an `allocator_type` identical to `A` and a `value_type` identical to `T` and given an lvalue `m` of type `A`, a pointer `p` of type `T*`, an expression `v` of type (possibly `const`) `T`, and an rvalue `rv` of type `T`, the following terms are defined. If `X` is not allocator-aware, the terms below are defined as if `A` were `std::allocator<T>` — no allocator object needs to be created and user specializations of `std::allocator<T>` are not instantiated:

   > - `T` is `DefaultInsertable` into `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p);

   > - An element of `X` is default-inserted if it is initialized by evaluation of the expression

   >   >     allocator_traits<A>::construct(m, p);

   >   where `p` is the address of the uninitialized storage for the element allocated within `X`.

   > - `T` is `CopyMoveInsertable` into `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, rv);

   >   and when evaluated the following postconditions hold: The value of `*p` is equivalent to the value of `rv` before the evaluation. [Note: `rv` remains a valid object. Its state is unspecified — end note]

   > - `T` is `MoveCopyInsertable` into `X` means that, in addition to satisfying the `MoveInsertable` requirements, the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, rv);

   >   and when evaluated the following postconditions hold: The value of `v` is unchanged and is equivalent to `*p`.

   > - `T` is `EmplaceConstructible` into `X` from `args`, for zero or more arguments `args`, means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, args);

   > - `T` is `Erasable` from `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::destroy(m, p);

   > [Note: A container calls `allocator_traits<A>::construct(m, p, args)` to construct an element at `p` using `args`. The default construct in `std::allocator` will call `::new((void*)p) T(args)`, but specialized allocators may choose a different definition. — end note]

### 2187. `vector<bool>` is missing `emplace` and `emplace_back` member functions

Section: 23.3.7 [vector.bool] Status: Tentatively Ready Submitter: Nevin Liber Opened: 2012-09-21 Last modified: 2012-11-02

View all other issues in [vector.bool].

View all issues with Tentatively Ready status.

Discussion:

It should have them so that it more closely matches the `vector<T>` interface, as this helps when writing generic code.

[2012, Portland: Move to Tentatively Ready]

Question on whether the variadic template is really needed, but it turns out to be needed to support `emplace` of no arguments.

Proposed resolution:

This wording is relative to N3376.

1. Change the class template `vector<bool>` synopsis, 23.3.7 [vector.bool] p1, as indicated:

   >     namespace std {
   >       template <class Allocator> class vector<bool, Allocator> {
   >       public:
   >         […]
   >         // modifiers:
   >         template <class... Args> void emplace_back(Args&&... args);
   >         void push_back(const bool& x);
   >         void pop_back();
   >         template <class... Args> iterator emplace(const_iterator position, Args&&... args);
   >         iterator insert(const_iterator position, const bool& x);
   >         […]
   >       };
   >     }