Revised 2018-07-20 at 21:06:25 UTC

Tentative Issues


708(i). Locales need to be per thread and updated for POSIX changes

Section: 26 [localization] Status: Tentatively NAD Submitter: Peter Dimov Opened: 2007-07-28 Last modified: 2018-06-24

Priority: Not Prioritized

View all other issues in [localization].

View all issues with Tentatively NAD status.

Discussion:

The POSIX "Extended API Set Part 4,"

http://www.opengroup.org/sib/details.tpl?id=C065

introduces extensions to the C locale mechanism that allow multiple concurrent locales to be used in the same application by introducing a type locale_t that is very similar to std::locale, and a number of _l functions that make use of it.

The global locale (set by setlocale) is now specified to be per- process. If a thread does not call uselocale, the global locale is in effect for that thread. It can install a per-thread locale by using uselocale.

There is also a nice querylocale mechanism by which one can obtain the name (such as "de_DE") for a specific facet, even for combined locales, with no std::locale equivalent.

std::locale should be harmonized with the new POSIX locale_t mechanism and provide equivalents for uselocale and querylocale.

[ Kona (2007): Bill and Nick to provide wording. ]

[ San Francisco: Bill and Nick still intend to provide wording, but this is a part of the task to be addressed by the group that will look into issue 860. ]

[ 2009-07 Frankfurt: ]

It's our intention to stay in sync with WG14. If WG14 makes a decision that requires a change in WG21 the issue will be reopened.

Move to NAD Future.

[LEWG Kona 2017]

Recommend NAD: uselocale() is bad; pass locales around as objects

Proposed resolution:


935(i). clock error handling needs to be specified

Section: 25.7 [time.clock] Status: Tentatively NAD Submitter: Beman Dawes Opened: 2008-11-24 Last modified: 2018-06-24

Priority: Not Prioritized

View all issues with Tentatively NAD status.

Discussion:

Each of the three clocks specified in Clocks 25.7 [time.clock] provides the member function:

static time_point now();

The semantics specified by Clock requirements 25.3 [time.clock.req] make no mention of error handling. Thus the function may throw bad_alloc or an implementation-defined exception (15.5.5.12 [res.on.exception.handling] paragraph 4).

Some implementations of these functions on POSIX, Windows, and presumably on other operating systems, may fail in ways only detectable at runtime. Some failures on Windows are due to supporting chipset errata and can even occur after successful calls to a clock's now() function.

These functions are used in cases where exceptions are not appropriate or where the specifics of the exception or cause of error need to be available to the user. See N2828, Library Support for hybrid error handling (Rev 1), for more specific discussion of use cases. Thus some change in the interface of now is required.

The proposed resolution has been implemented in the Boost version of the chrono library. No problems were encountered.

[ Batavia (2009-05): ]

We recommend this issue be deferred until the next Committee Draft has been issued and the prerequisite paper has been accepted.

Move to Open.

[ 2009-10 Santa Cruz: ]

Mark as NAD future. Too late to make this change without having already accepted the hybrid error handling proposal.

[LEWG Kona 2017]

Recommend NAD. Needs a paper. Proposed resolution no longer applies.

Proposed resolution:

Accept the proposed wording of N2828, Library Support for hybrid error handling (Rev 1).

Change Clock requirements 25.3 [time.clock.req] as indicated:

-2- In Table 55 C1 and C2 denote clock types. t1 and t2 are values returned by C1::now() where the call returning t1 happens before (1.10) the call returning t2 and both of these calls happen before C1::time_point::max(). ec denotes an object of type error_code (18.5.3.1 [syserr.errcode.overview]).

Table 55 — Clock requirements
ExpressionReturn typeOperational semantics
... ... ...
C1::now() C1::time_point Returns a time_point object representing the current point in time.
C1::now(ec) C1::time_point Returns a time_point object representing the current point in time.

Change class system_clock 25.7.1 [time.clock.system] as indicated:

static time_point now(error_code& ec=throws());

Change class monotonic_clock 99 [time.clock.monotonic] as indicated:

static time_point now(error_code& ec=throws());

Change class high_resolution_clock 25.7.7 [time.clock.hires] as indicated:

static time_point now(error_code& ec=throws());

1121(i). Support for multiple arguments

Section: 19.16.4 [ratio.arithmetic] Status: Tentatively NAD Submitter: Alisdair Meredith Opened: 2009-05-25 Last modified: 2018-06-24

Priority: Not Prioritized

View all other issues in [ratio.arithmetic].

View all issues with Tentatively NAD status.

Discussion:

Both add and multiply could sensibly be called with more than two arguments. The variadic template facility makes such declarations simple, and is likely to be frequently wrapped by end users if we do not supply the variant ourselves.

We deliberately ignore divide at this point as it is not transitive. Likewise, subtract places special meaning on the first argument so I do not suggest extending that immediately. Both could be supported with analogous wording to that for add/multiply below.

Note that the proposed resolution is potentially incompatible with that proposed for 921, although the addition of the typedef to ratio would be equally useful.

[ 2009-10-30 Alisdair adds: ]

The consensus of the group when we reviewed this in Santa Cruz was that 921 would proceed to Ready as planned, and the multi-paramater add/multiply templates should be renamed as ratio_sum and ratio_product to avoid the problem mixing template aliases with partial specializations.

It was also suggested to close this issue as NAD Future as it does not correspond directly to any NB comment. NBs are free to submit a specific comment (and re-open) in CD2 though.

Walter Brown also had concerns on better directing the order of evaluation to avoid overflows if we do proceed for 0x rather than TR1, so wording may not be complete yet.

[ Alisdair updates wording. ]

[ 2009-10-30 Howard: ]

Moved to Tentatively NAD Future after 5 positive votes on c++std-lib.

[LEWG Kona 2017]

PR for ratio_product is wrong, uses ratio_add instead of ratio_multiply. Recommend NAD: Doesn't meet the bar for standardization: hasn't been requested again in 7 years, easy to implement yourself.

Rationale:

Does not have sufficient support at this time. May wish to reconsider for a future standard.

Proposed resolution:

Add the following type traits to p3 19.16 [ratio]

// ratio arithmetic
template <class R1, class R2> struct ratio_add;
template <class R1, class R2> struct ratio_subtract;
template <class R1, class R2> struct ratio_multiply;
template <class R1, class R2> struct ratio_divide;
template <class R1, class ... RList> struct ratio_sum;
template <class R1, class ... RList> struct ratio_product;

after 19.16.4 [ratio.arithmetic] p1: add

template <class R1, class ... RList> struct ratio_sum; // declared, never defined

template <class R1> struct ratio_sum<R1> : R1 {};

Requires: R1 is a specialization of class template ratio

template <class R1, class R2, class ... RList> 
 struct ratio_sum<R1, R2, RList...>
   : ratio_add< R1, ratio_sum<R2, RList...>> {
};

Requires: R1 and each element in parmater pack RList is a specialization of class template ratio

after 19.16.4 [ratio.arithmetic] p3: add

template <class R1, class ... RList> struct ratio_product; // declared, never defined

template <class R1> struct ratio_product<R1> : R1 {};

Requires: R1 is a specialization of class template ratio

template <class R1, class R2, class ... RList> 
 struct ratio_sum<R1, R2, RList...>
   : ratio_add< R1, ratio_product<R2, RList...>> {
};

Requires: R1 and each element in parmater pack RList is a specialization of class template ratio


1154(i). complex should accept integral types

Section: 24.5 [complex.numbers] Status: Tentatively NAD Submitter: LWG Opened: 2009-06-28 Last modified: 2018-06-24

Priority: Not Prioritized

View other active issues in [complex.numbers].

View all other issues in [complex.numbers].

View all issues with Tentatively NAD status.

Discussion:

Addresses FR 35

Description

Instantiations of the class template complex<> have to be allowed for integral types, to reflect existing practice and ISO standards (LIA-III).

Suggestion

[ 2009-10-26 Proposed wording in N3002. ]

[ 2010 Pittsburgh: ]

Moved to NAD Future. Rationale added.

[LEWG Kona 2017]

Recommend SG6

[2017-03-03, Kona]

SG6 suggests this issue is a new feature, not a problem with the existing standard, and should therefore be closed NAD. However, SG6 invites papers that bring the proposal up to date with the current standard.

Rationale:

There is no consensus for making this change at this time.

Proposed resolution:

Adopt N3002.


1188(i). Unordered containers should have a minimum load factor as well as a maximum

Section: 21.2.7 [unord.req], 21.5 [unord] Status: Tentatively NAD Submitter: Matt Austern Opened: 2009-08-10 Last modified: 2018-06-21

Priority: Not Prioritized

View other active issues in [unord.req].

View all other issues in [unord.req].

View all issues with Tentatively NAD status.

Discussion:

Unordered associative containers have a notion of a maximum load factor: when the number of elements grows large enough, the containers automatically perform a rehash so that the number of elements per bucket stays below a user-specified bound. This ensures that the hash table's performance characteristics don't change dramatically as the size increases.

For similar reasons, Google has found it useful to specify a minimum load factor: when the number of elements shrinks by a large enough, the containers automatically perform a rehash so that the number of elements per bucket stays above a user-specified bound. This is useful for two reasons. First, it prevents wasting a lot of memory when an unordered associative container grows temporarily. Second, it prevents amortized iteration time from being arbitrarily large; consider the case of a hash table with a billion buckets and only one element. (This was discussed even before TR1 was published; it was TR issue 6.13, which the LWG closed as NAD on the grounds that it was a known design feature. However, the LWG did not consider the approach of a minimum load factor.)

The only interesting question is when shrinking is allowed. In principle the cleanest solution would be shrinking on erase, just as we grow on insert. However, that would be a usability problem; it would break a number of common idioms involving erase. Instead, Google's hash tables only shrink on insert and rehash.

The proposed resolution allows, but does not require, shrinking in rehash, mostly because a postcondition for rehash that involves the minimum load factor would be fairly complicated. (It would probably have to involve a number of special cases and it would probably have to mention yet another parameter, a minimum bucket count.)

The current behavior is equivalent to a minimum load factor of 0. If we specify that 0 is the default, this change will have no impact on backward compatibility.

[ 2010 Rapperswil: ]

This seems to a useful extension, but is too late for 0x. Move to Tentatively NAD Future.

[ Moved to NAD Future at 2010-11 Batavia ]

[LEWG Kona 2017]

Should there be a shrink_to_fit()? Is it too surprising to shrink on insert()? (We understand that shrinking on erase() is not an option.) Maybe make people call rehash(0) to shrink to the min_load_factor? On clear(), the load factor goes to 0 or undefined (0/0), which is likely to violate min_load_factor() min_load_factor(z)'s wording should match max_load_factor(z)'s, e.g. "May change the container’s maximum load factor" Want a paper exploring whether shrink-on-insert has been surprising. From Titus: Google's experience is that maps don't shrink in the way this would help with. NAD, not worth the time. Write a paper if you can demonstrate a need for this.

Proposed resolution:

Add two new rows, and change rehash's postcondition in the unordered associative container requirements table in 21.2.7 [unord.req]:

Table 87 — Unordered associative container requirements (in addition to container)
ExpressionReturn typeAssertion/note pre-/post-condition Complexity
a.min_load_factor() float Returns a non-negative number that the container attempts to keep the load factor greater than or equal to. The container automatically decreases the number of buckets as necessary to keep the load factor above this number. constant
a.min_load_factor(z) void Pre: z shall be non-negative. Changes the container's minimum load factor, using z as a hint. [Footnote: the minimum load factor should be significantly smaller than the maximum. If z is too large, the implementation may reduce it to a more sensible value.] constant
a.rehash(n) void Post: a.bucket_count() >= n, and a.size() <= a.bucket_count() * a.max_load_factor(). [Footnote: It is intentional that the postcondition does not mention the minimum load factor. This member function is primarily intended for cases where the user knows that the container's size will increase soon, in which case the container's load factor will temporarily fall below a.min_load_factor().] a.bucket_cout > a.size() / a.max_load_factor() and a.bucket_count() >= n. Average case linear in a.size(), worst case quadratic.

Add a footnote to 21.2.7 [unord.req] p12:

The insert members shall not affect the validity of references to container elements, but may invalidate all iterators to the container. The erase members shall invalidate only iterators and references to the erased elements.

[A consequence of these requirements is that while insert may change the number of buckets, erase may not. The number of buckets may be reduced on calls to insert or rehash.]

Change paragraph 13:

The insert members shall not affect the validity of iterators if (N+n) < z * B zmin * B <= (N+n) <= zmax * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container's bucket count, zmin is the container's minimum load factor, and zmax is the container's maximum load factor.

Add to the unordered_map class synopsis in section 21.5.4 [unord.map], the unordered_multimap class synopsis in 21.5.5 [unord.multimap], the unordered_set class synopsis in 21.5.6 [unord.set], and the unordered_multiset class synopsis in 21.5.7 [unord.multiset]:


float min_load_factor() const;
void min_load_factor(float z);

In 21.5.4.2 [unord.map.cnstr], 21.5.5.2 [unord.multimap.cnstr], 21.5.6.2 [unord.set.cnstr], and 21.5.7.2 [unord.multiset.cnstr], change:

... max_load_factor() returns 1.0 and min_load_factor() returns 0.


1217(i). Quaternion support

Section: 24.5 [complex.numbers] Status: Tentatively NAD Submitter: Ted Shaneyfelt Opened: 2009-09-26 Last modified: 2018-06-24

Priority: Not Prioritized

View other active issues in [complex.numbers].

View all other issues in [complex.numbers].

View all issues with Tentatively NAD status.

Discussion:

Concerning mathematically proper operation of the type:

complex<complex<T> >

Generally accepted mathematical semantics of such a construct correspond to quaternions through Cayly-Dickson construct

(w+xi) + (y+zi) j

The proper implementation seems straightforward by adding a few declarations like those below. I have included operator definition for combining real scalars and complex types, as well, which seems appropriate, as algebra of complex numbers allows mixing complex and real numbers with operators. It also allows for constructs such as complex<double> i=(0,1), x = 12.34 + 5*i;

Quaternions are often used in areas such as computer graphics, where, for example, they avoid the problem of Gimbal lock when rotating objects in 3D space, and can be more efficient than matrix multiplications, although I am applying them to a different field.

/////////////////////////ALLOW OPERATORS TO COMBINE REAL SCALARS AND COMPLEX VALUES /////////////////////////
template<typename T,typename S> complex<T> operator+(const complex<T> x,const S a) {
    complex<T> result(x.real()+a, x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator+(const S a,const complex<T> x) {
    complex<T> result(a+x.real(), x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator-(const complex<T> x,const S a) {
    complex<T> result(x.real()-a, x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator-(const S a,const complex<T> x) {
    complex<T> result(a-x.real(), x.imag());
    return result;
}
template<typename T,typename S> complex<T> operator*(const complex<T> x,const S a) {
    complex<T> result(x.real()*a, x.imag()*a);
    return result;
}
template<typename T,typename S> complex<T> operator*(const S a,const complex<T> x) {
    complex<T> result(a*x.real(), a*x.imag());
    return result;
}

/////////////////////////PROPERLY IMPLEMENT QUATERNION SEMANTICS/////////////////////////
template<typename T> double normSq(const complex<complex<T> >q) {
    return q.real().real()*q.real().real()
         + q.real().imag()*q.real().imag()
         + q.imag().real()*q.imag().real()
         + q.imag().imag()*q.imag().imag();
}
template<typename T> double norm(const complex<complex<T> >q) {
    return sqrt(normSq(q));
}
/////// Cayley-Dickson Construction
template<typename T> complex<complex<T> > conj(const complex<complex<T> > x) {
    complex<complex<T> > result(conj(x.real()),-x.imag());
    return result;
}
template<typename T> complex<complex<T> > operator*(const complex<complex<T> > ab,const complex<complex<T> > cd) {
    complex<T> re(ab.real()*cd.real()-conj(cd.imag())*ab.imag());
    complex<T> im(cd.imag()*ab.real()+ab.imag()*conj(cd.real()));
    complex<complex<double> > q(re,im);
    return q;
}
//// Quaternion division
template<typename S,typename T> complex<complex<T> > operator/(const complex<complex<T> > q,const S a) {
    return q * (1/a);
}
template<typename S,typename T> complex<complex<T> > operator/(const S a,const complex<complex<T> > q) {
    return a*conj(q)/normSq(q);
}
template<typename T> complex<complex<T> > operator/(const complex<complex<T> > n, const complex<complex<T> > d) {
    return n * (conj(d)/normSq(d));
}

[ 2009-10 Santa Cruz: ]

NAD Future. There is no consensus or time to move this into C++0X.

[LEWG Kona 2017]

Recommend SG6 - We note that complex<complex> is the wrong way to spell this

[2017-03-03, Kona]

SG6 suggests this issue is a new feature, not a problem with the existing standard, and should therefore be closed NAD. However, SG6 invites papers that bring the proposal up to date with the current standard.

Proposed resolution:


1235(i). Issue with C++0x random number proposal

Section: 24.7.2.6 [rand.req.dist] Status: Tentatively NAD Submitter: Matthias Troyer Opened: 2009-10-12 Last modified: 2018-06-21

Priority: Not Prioritized

View all other issues in [rand.req.dist].

View all issues with Tentatively NAD status.

Discussion:

There exist optimized, vectorized vendor libraries for the creation of random number generators, such as Intel's MKL [1] and AMD's ACML [2]. In timing tests we have seen a performance gain of a factor of up to 80 (eighty) compared to a pure C++ implementation (in Boost.Random) when using these generator to generate a sequence of normally distributed random numbers. In codes dominated by the generation of random numbers (we have application codes where random number generation is more than 50% of the CPU time) this factor 80 is very significant.

To make use of these vectorized generators, we use a C++ class modeling the RandomNumberEngine concept and forwarding the generation of random numbers to those optimized generators. For example:

namespace mkl {
 class mt19937 {.... };
}

For the generation of random variates we also want to dispatch to optimized vectorized functions in the MKL or ACML libraries. See this example:

mkl::mt19937 eng;
std::normal_distribution<double> dist;

double n = dist(eng);

Since the variate generation is done through the operator() of the distribution there is no customization point to dispatch to Intel's or AMD's optimized functions to generate normally distributed numbers based on the mt19937 generator. Hence, the performance gain of 80 cannot be achieved.

Contrast this with TR1:

mkl::mt19937 eng;
std::tr1::normal_distribution<double> dist;
std::tr1::variate_generator<mkl::mt19937,std::tr1::normal_distribution<double> > rng(eng,dist);
double n = rng();

This - admittedly much uglier from an aestethic point of view - design allowed optimization by specializing the variate_generator template for mkl::mt19937:

namespace std { namespace tr1 {

template<>
class variate_generator<mkl::mt19937,std::tr1::normal_distribution<double> > { .... };

} }

A similar customization point is missing in the C++0x design and prevents the optimized vectorized version to be used.

Suggested resolution:

Add a customization point to the distribution concept. Instead of the variate_generator template this can be done through a call to a free function generate_variate found by ADL instead of operator() of the distribution:

template <RandomNumberDistribution, class RandomNumberEngine>
typename RandomNumberDistribution ::result_type
generate_variate(RandomNumberDistribution const& dist, RandomNumberEngine& eng);

This function can be overloaded for optimized enginges like mkl::mt19937.

[ 2009-10 Santa Cruz: ]

NAD Future. No time to add this feature for C++0X.

[LEWG Kona 2017]

Recommend NAD: The standard has changed enough that the issue doesn't make sense anymore. Write a paper proposing a way to get this performance as changes to the current library.

Proposed resolution:


1282(i). A proposal to add std::split algorithm

Section: 23 [algorithms] Status: Tentatively NAD Submitter: Igor Semenov Opened: 2009-12-07 Last modified: 2018-06-24

Priority: Not Prioritized

View other active issues in [algorithms].

View all other issues in [algorithms].

View all issues with Tentatively NAD status.

Discussion:

  1. Motivation and Scope

    Splitting strings into parts by some set of delimiters is an often task, but there is no simple and generalized solution in C++ Standard. Usually C++ developers use std::basic_stringstream<> to split string into parts, but there are several inconvenient restrictions:

  2. Impact on the Standard

    This algorithm doesn't interfere with any of current standard algorithms.

  3. Design Decisions

    This algorithm is implemented in terms of input/output iterators. Also, there is one additional wrapper for const CharType * specified delimiters.

  4. Example implementation

    template< class It, class DelimIt, class OutIt >
    void split( It begin, It end, DelimIt d_begin, DelimIt d_end, OutIt out )
    {
       while ( begin != end )
       {
           It it = std::find_first_of( begin, end, d_begin, d_end );
           *out++ = std::make_pair( begin, it );
           begin = std::find_first_of( it, end, d_begin, d_end,
               std::not2( std::equal_to< typename It::value_type >() ) );
       }
    }
    
    template< class It, class CharType, class OutIt >
    void split( It begin, It end, const CharType * delim, OutIt out )
    {
       split( begin, end, delim, delim + std::strlen( delim ), out );
    }
    
  5. Usage

    std::string ss( "word1 word2 word3" );
    std::vector< std::pair< std::string::const_iterator, std::string::const_iterator > > v;
    split( ss.begin(), ss.end(), " ", std::back_inserter( v ) );
    
    for ( int i = 0; i < v.size(); ++i )
    {
       std::cout << std::string( v[ i ].first, v[ i ].second ) << std::endl;
    }
    // word1
    // word2
    // word3
    

[ 2010-01-22 Moved to Tentatively NAD Future after 5 positive votes on c++std-lib. Rationale added below. ]

[LEWG Kona 2017]

Recommend NAD: Paper encouraged. Have papers for this; LEWG259.

Rationale:

The LWG is not considering completely new features for standardization at this time. We would like to revisit this good suggestion for a future TR and/or standard.

Proposed resolution:

Add to the synopsis in 23.1 [algorithms.general]:

template< class ForwardIterator1, class ForwardIterator2, class OutputIterator >
  void split( ForwardIterator1 first, ForwardIterator1 last,
              ForwardIterator2 delimiter_first, ForwardIterator2 delimiter_last,
              OutputIterator result );

template< class ForwardIterator1, class CharType, class OutputIterator >
  void split( ForwardIterator1 first, ForwardIterator1 last,
              const CharType * delimiters, OutputIterator result );

Add a new section [alg.split]:

template< class ForwardIterator1, class ForwardIterator2, class OutputIterator >
  void split( ForwardIterator1 first, ForwardIterator1 last,
              ForwardIterator2 delimiter_first, ForwardIterator2 delimiter_last,
              OutputIterator result );

1. Effects: splits the range [first, last) into parts, using any element of [delimiter_first, delimiter_last) as a delimiter. Results are pushed to output iterator in the form of std::pair<ForwardIterator1, ForwardIterator1>. Each of these pairs specifies a maximal subrange of [first, last) which does not contain a delimiter.

2. Returns: nothing.

3. Complexity: Exactly last - first assignments.

template< class ForwardIterator1, class CharType, class OutputIterator >
  void split( ForwardIterator1 first, ForwardIterator1 last,
              const CharType * delimiters, OutputIterator result );

1. Effects: split the range [first, last) into parts, using any element of delimiters (interpreted as zero-terminated string) as a delimiter. Results are pushed to output iterator in the form of std::pair<ForwardIterator1, ForwardIterator1>. Each of these pairs specifies a maximal subrange of [first, last) which does not contain a delimiter.

2. Returns: nothing.

3. Complexity: Exactly last - first assignments.


1289(i). Generic casting requirements for smart pointers

Section: 19.2 [utility] Status: Tentatively NAD Submitter: Ion Gaztañaga Opened: 2009-12-14 Last modified: 2018-06-21

Priority: Not Prioritized

View all other issues in [utility].

View all issues with Tentatively NAD status.

Discussion:

In section 15.5.3.5 [allocator.requirements], Table 40 — Allocator requirements, the following expression is required for allocator pointers:

Table 40 — Allocator requirements
Expression Return type Assertion/note
pre-/post-condition
Default
static_cast<X::pointer>(w) X::pointer static_cast<X::pointer>(w) == p  

To achieve this expression, a smart pointer writer must introduce an explicit conversion operator from smart_ptr<void> to smart_ptr<T> so that static_cast<pointer>(void_ptr) is a valid expression. Unfortunately this explicit conversion weakens the safety of a smart pointer since the following expression (invalid for raw pointers) would become valid:

smart_ptr<void> smart_v = ...;
smart_ptr<T> smart_t(smart_v);

On the other hand, shared_ptr also defines its own casting functions in 19.11.3.9 [util.smartptr.shared.cast], and although it's unlikely that a programmer will use shared_ptr as allocator::pointer, having two different ways to do the same cast operation does not seem reasonable. A possible solution would be to replace static_cast<X::pointer>(w) expression with a user customizable (via ADL) static_pointer_cast<value_type>(w), and establish the xxx_pointer_cast functions introduced by shared_ptr as the recommended generic casting utilities of the standard.

Unfortunately, we've experienced problems in Boost when trying to establish xxx_pointer_cast as customization points for generic libraries (http://objectmix.com/c/40424-adl-lookup-explicit-template-parameters.html) because these casting functions are called with explicit template parameters and the standard says in 12.9.1 [temp.arg.explicit] p.8 "Explicit template argument specification":

8 ...But when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call. If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply.

So we can do this:

template<class BasePtr>
void generic_ptr_swap(BasePtr p)
{
  //ADL customization point
  swap(p, p);
  //...
}

but not the following:

template<class BasePtr>
void generic_ptr_algo(BasePtr p)
{
  typedef std::pointer_traits<BasePtr>::template
     rebind<Derived> DerivedPtr;
  DerivedPtr dp = static_pointer_cast<Derived>(p);
}

The solution to make static_pointer_cast a customization point is to add a generic declaration (no definition) of static_pointer_cast in a namespace (like std) and apply "using std::static_pointer_cast" declaration to activate ADL:

namespace std{

template<typename U, typename T>
unspecified
static_pointer_cast(T&&) = delete;

}

template<class BasePtr>
void generic_ptr_algo(BasePtr p)
{
  typedef std::pointer_traits<BasePtr>::template
     rebind<Derived> DerivedPtr;

  //ADL applies because static_pointer_cast is made
  //  visible according to [temp.arg.explicit]/8
  using std::static_pointer_cast;

  DerivedPtr dp = static_pointer_cast<Derived>(p);

  //...
}

A complete solution will need also the definition of static_pointer_cast for raw pointers, and this definition has been present in Boost (http://www.boost.org/boost/ pointer_cast.hpp) for years.

[ 2010-03-26 Daniel made editorial adjustments to the proposed wording. ]

[ Moved to NAD Future at 2010-11 Batavia ]

This is a new feature rather than a defect. It can be added later: "this is such a hairy area that people will put up with changes"

[LEWG Kona 2017]

Recommend NAD: NAD. Should bring a paper as a proposal for 2020.

Proposed resolution:

Add to section 19.2 [utility] Utility components, Header <utility> synopsis:

// 20.3.X, generic pointer cast functions

template<typename U, typename T>
unspecified
static_pointer_cast(T&&) = delete;

template<typename U, typename T>
unspecified
dynamic_pointer_cast(T&&) = delete;

template<typename U, typename T>
unspecified
const_pointer_cast(T&&) = delete;

//Overloads for raw pointers
template<typename U, typename T>
auto static_pointer_cast(T* t) -> decltype(static_cast<U*>(t));

template<typename U, typename T>
auto dynamic_pointer_cast(T* t) -> decltype(dynamic_cast<U*>(t));

template<typename U, typename T>
auto const_pointer_cast(T* t) -> decltype(const_cast<U*>(t));

Add to section 19.2 [utility] Utility components, a new subclause 20.3.X Pointer cast utilities [pointer.cast]:

20.3.X Pointer cast utilities [pointer.cast]

1 The library defines generic pointer casting function templates so that template code can explicitly make these names visible and activate argument-dependent lookup for pointer cast calls.

//Generic declarations
template<typename U, typename T>
unspecified
static_pointer_cast(T&&) = delete;

template<typename U, typename T>
unspecified
dynamic_pointer_cast(T&&) = delete;

template<typename U, typename T>
unspecified
const_pointer_cast(T&&) = delete;

2 The library also defines overloads of these functions for raw pointers.

//Overloads for raw pointers
template<typename U, typename T>
auto static_pointer_cast(T* t) -> decltype(static_cast<U*>(t));

Returns: static_cast<U*>(t)

template<typename U, typename T>
auto dynamic_pointer_cast(T* t) -> decltype(dynamic_cast<U*>(t));

Returns: dynamic_cast<U*>(t)

template<typename U, typename T>
auto const_pointer_cast(T* t) -> decltype(const_cast<U*>(t));

Returns: const_cast<U*>(t)

[Example:

#include <utility> //static_pointer_cast
#include <memory>  //pointer_traits

class Base{};
class Derived : public Base{};

template<class BasePtr>
void generic_pointer_code(BasePtr b)
{
   typedef std::pointer_traits<BasePtr>::template
      rebind<Derived> DerivedPtr;

   using std::static_pointer_cast;
   //ADL applies now that static_pointer_cast is visible
   DerivedPtr d = static_pointer_cast<Derived>(b);
}

end example]

Replace in section 15.5.3.5 [allocator.requirements] Table 40 — Allocator requirements, the following table entries for allocator pointers:

Table 40 — Allocator requirements
Expression Return type Assertion/note
pre-/post-condition
Default
static_pointer_cast<X::pointerT>(w) X::pointer static_pointer_cast<X::pointerT>(w) == p  
static_pointer_cast<X::const_pointerconst T>(w) X::const_pointer static_pointer_cast<X::const_pointerconst T>(z) == q  

1317(i). make_hash

Section: 19.14.16 [unord.hash] Status: Tentatively NAD Submitter: Nicolai M. Josuttis Opened: 2010-02-10 Last modified: 2018-06-24

Priority: Not Prioritized

View other active issues in [unord.hash].

View all other issues in [unord.hash].

View all issues with Tentatively NAD status.

Discussion:

Currently, the library lacks a convenient way to provide a hash function that can be used with the provided unordered containers to allow the usage of non trivial element types.

While we can easily declare an

std::unordered_set<int>

or

std::unordered_set<std::string>

we have no easy way to declare an unordered_set for a user defined type. IMO, this is a big obstacle to use unordered containers in practice. Note that in Java, the wide usage of HashMap is based on the fact that there is always a default hash function provided.

Of course, a default hash function implies the risk to provide poor hash functions. But often even poor hash functions are good enough.

While I really would like to see a default hash function, I don't propose it here because this would probably introduce a discussion that's too big for this state of C++0x.

However, I strongly suggest at least to provide a convenience variadic template function make_hash<>() to allow an easy definition of a (possibly poor) hash function.

As a consequence for a user-defined type such as

class Customer {
   friend class CustomerHash;
   private:
     string firstname;
     string lastname;
     long   no;
   ...
 };

would allow to specify:

class CustomerHash : public std::unary_function<Customer, std::size_t>
{
  public:
    std::size_t operator() (const Customer& c) const  {
       return make_hash(c.firstname,c.lastname,c.no);
    }
};

instead of:

class CustomerHash : public std::unary_function<Customer, std::size_t>
{
  public:
    std::size_t operator() (const Customer& c) const  {
       return std::hash<std::string>()(c.firstname) +
              std::hash<std::string>()(c.lastname) +
              std::hash<long>()(c.no);
    }
};

Note that, in principle, we can either specify that

make_hash returns the sum of a call of std::hash<T>()(x) for each argument x of type T

or we can specify that

make_hash provides a hash value for each argument, for which a std::hash() function is provided

with the possible note that the hash value may be poor or only a good hash value if the ranges of all passed arguments is equally distributed.

For my convenience, I propose wording that describes the concrete implementation.

[ 2010 Pittsburgh: Moved to NAD Editorial, rationale added below. ]

[LEWG Kona 2017]

Recommend NAD: Feature? Needs a paper. (This is LEWG21)

Rationale:

There is no consensus to make this change at this time.

Proposed resolution:

In Function objects 19.14 [function.objects] in paragraph 2 at the end of the Header <functional> synopsis insert:

// convenience functions
template <class T>
  size_t make_hash (const T&);
template <class T, class... Types>
  size_t make_hash (const T&, const Types&...);

In Class template hash 19.14.16 [unord.hash] add:

20.7.16.1 Hash creation functions [hash.creation]

template <class T>
  size_t make_hash (const T& val);

Returns: hash<T>()(val);

template <class T, class... Types>
  size_t make_hash (const T& val, const Types&... args);

Returns: hash<T>()(val) + std::make_hash(args...)


1406(i). Support hashing smart-pointers based on owner

Section: 19.11.3 [util.smartptr.shared] Status: Tentatively NAD Submitter: Japan Opened: 2010-08-25 Last modified: 2018-06-21

Priority: Not Prioritized

View other active issues in [util.smartptr.shared].

View all other issues in [util.smartptr.shared].

View all issues with Tentatively NAD status.

Discussion:

Addresses JP-5

Hash support based on ownership sharing should be supplied for shared_ptr and weak_ptr. For two shared_ptr objects p and q, two distinct equivalence relations can be defined. One is based on equivalence of pointer values, which is derived from the expression p.get() == q.get() (hereafter called address based equivalence relation), the other is based on equivalence of ownership sharing, which is derived from the expression !p.owner_before(q) && !q.owner_before(p) (hereafter called ownership-based equivalence relation). These two equivalence relations are independent in general. For example, a shared_ptr object created by the constructor of the signature shared_ptr(shared_ptr<U> const &, T *) could reveal a difference between these two relations. Therefore, hash support based on each equivalence relation should be supplied for shared_ptr. However, while the standard library provides the hash support for address-based one (20.9.11.6 paragraph 2), it lacks the hash support for ownership-based one. In addition, associative containers work well in combination with the shared_ptr's ownership-based comparison but unordered associative containers don't. This is inconsistent.

For the case of weak_ptr, hash support for the ownership based equivalence relation can be safely defined on weak_ptrs, and even on expired ones. The absence of hash support for the ownership-based equivalence relation is fatal, especially for expired weak_ptrs. And the absence of such hash support precludes some quite effective use-cases, e.g. erasing the unordered_map entry of an expired weak_ptr key from a customized deleter supplied to shared_ptrs.

Hash support for the ownership-based equivalence relation cannot be provided by any user-defined manner because information about ownership sharing is not available to users at all. Therefore, the only way to provide ownership-based hash support is to offer it intrusively by the standard library.

As far as we know, such hash support is implementable. Typical implementation of such hash function could return the hash value of the pointer of the counter object that is internally managed by shared_ptr and weak_ptr.

[2010 Rapperswil:]

No consensus to make this change at this time.

[LEWG Kona 2017]

Recommend NAD: Needs a paper. Feature. Exposing an implementation detail (indirectly observable via hash).

Proposed resolution:

Add the following non-static member functions to shared_ptr and weak_ptr class template;

Update [util.smartptr.shared], 20.9.11.2 paragraph 1

namespace std{
template<class T> class shared_ptr {
public:
...
  size_t owner_hash() const;
...
};
}

Update [util.smartptr.weak], 20.9.11.3 paragraph 1

namespace std{
template<class T> class weak_ptr {
public:
...
  size_t owner_hash() const;
...
};
}

These functions satisfy the following requirements. Let p and q be objects of either shared_ptr or weak_ptr, H be a hypothetical function object type that satisfies the hash requirements ([hash.requirements], 20.2.4) and h be an object of the type H. The expression p.owner_hash() behaves as if it were equivalent to the expression h(p). In addition, h(p) == h(q) must become true if p and q share ownership.


1499(i). Condition variables preclude wakeup optimization

Section: 30.5 [thread.condition] Status: Tentatively NAD Submitter: INCITS Opened: 2010-08-25 Last modified: 2018-06-21

Priority: Not Prioritized

View all other issues in [thread.condition].

View all issues with Tentatively NAD status.

Discussion:

Addresses US-193

Condition variables preclude a wakeup optimization.

[ Resolution proposed by ballot comment: ]

Change condition_variable to allow such optimization. See Appendix 1 - Additional Details

[ 2010 Batavia ]

The Concurrency subgroup reviewed the issue, and deemed it an extension to be handled after C++0x.

Rationale:

The LWG does not wish to make the change at this time.

[LEWG Kona 2017]

Recommend NAD: (N4618 numbering) 30.5.1[thread.condition.condvar] p10.3 allows spurious wakeups. This issue is out of date.

[2017-03-01, Kona]

SG1 recommends: Close as NAD

The approach suggested there raises all sorts of issues about thread_locals, etc. It's probably way too late to change this anyway, but this would have required a careful paper.

Proposed resolution:


2226(i). wstring_convert methods do not take allocator instance

Section: D.14.1 [depr.conversions.string] Status: Tentatively NAD Submitter: Glen Fernandes Opened: 2012-12-14 Last modified: 2018-06-24

Priority: Not Prioritized

View other active issues in [depr.conversions.string].

View all other issues in [depr.conversions.string].

View all issues with Tentatively NAD status.

Discussion:

The wstring_convert class template, described in D.14.1 [depr.conversions.string], does not support custom stateful allocators. It only supports custom stateless allocators.

The to_bytes member function returns basic_string<char, char_traits<char>, Byte_alloc> but it does not take an instance of Byte_alloc to pass to the constructor of the basic_string.

Similarly the from_bytes member function returns basic_string<Elem, char_traits<Elem>, Wide_alloc> but it does not take an instance of Wide_alloc to pass to the constructor of the basic_string.

This makes these two member functions and the wstring_convert class template not usable when Wide_alloc or Byte_alloc are stateful allocators.

[2013-01-22, Glen provides wording]

[2013-03-15 Issues Teleconference]

Moved to NAD Future.

This is clearly an extension that the LEWG may want to take a look at, once we have more experience with appropriate use of allocators with the C++11 model.

[LEWG Kona 2017]

Recommend NAD: Does this follow the pattern? Should be discussed as a group. Do we have the experience with the C++11 allocator model to know that this is the addition to make?

Should to_string() also take an allocator? substr()? Any function that returns a string?

This suggests a larger change.

Proposed resolution:

This wording is relative to N3485.

  1. In D.14.1 [depr.conversions.string]/2 and /6 "Class template wstring_convert synopsis" change the overloads of the member function from_bytes() so that all four overloads take an additional parameter which is an instance of Wide_alloc:

    wide_string from_bytes(char byte, const Wide_alloc& alloc = Wide_alloc());
    wide_string from_bytes(const char *ptr, const Wide_alloc& alloc = Wide_alloc());
    wide_string from_bytes(const byte_string& str, const Wide_alloc& alloc = Wide_alloc());
    wide_string from_bytes(const char *first, const char *last, const Wide_alloc& alloc = Wide_alloc());
    
  2. In D.14.1 [depr.conversions.string] /8 specify that this Wide_alloc allocator parameter is used to construct the wide_string object returned from the function:

    -7- Effects: The first member function shall convert the single-element sequence byte to a wide string. The second member function shall convert the null-terminated sequence beginning at ptr to a wide string. The third member function shall convert the sequence stored in str to a wide string. The fourth member function shall convert the sequence defined by the range [first, last) to a wide string.

    -8- In all cases:

  3. In D.14.1 [depr.conversions.string]/2 and /12 "Class template wstring_convert synopsis" change the overloads of the member function to_bytes() so that all four overloads take an additional parameter which is an instance of Byte_alloc:

    byte_string to_bytes(Elem wchar, const Byte_alloc& alloc = Byte_alloc());
    byte_string to_bytes(const Elem *wptr, const Byte_alloc& alloc = Byte_alloc());
    byte_string to_bytes(const wide_string& wstr, const Byte_alloc& alloc = Byte_alloc());
    byte_string to_bytes(const Elem *first, const Elem *last, const Byte_alloc& alloc = Byte_alloc());
    
  4. In D.14.1 [depr.conversions.string] /13 specify that this Byte_alloc allocator parameter is used to construct the byte_string object returned from the function:

    -12- Effects: The first member function shall convert the single-element sequence wchar to a byte string. The second member function shall convert the null-terminated sequence beginning at wptr to a byte string. The third member function shall convert the sequence stored in wstr to a byte string. The fourth member function shall convert the sequence defined by the range [first, last) to a byte string.

    -13- In all cases:


2417(i). [fund.ts.v2] std::experimental::optional::operator< and LessThanComparable requirement

Section: 5.7 [fund.ts.v2::optional.relops], 5.9 [fund.ts.v2::optional.comp_with_t] Status: Tentatively NAD Submitter: Daniel Krügler Opened: 2014-06-20 Last modified: 2018-06-24

Priority: Not Prioritized

View all issues with Tentatively NAD status.

Discussion:

Addresses: fund.ts.v2

Currently, std::experimental::optional::operator== imposes the EqualityComparable requirement which provides two guarantees: It ensures that operator!= can rely on the equivalence-relation property and more importantly, that the BooleanTestable requirements suggested by issue 2114 are automatically implied.

std::experimental::optional::operator< doesn't provide a LessThanComparable requirement, but there was quite an historic set of changes involved with that family of types: As of N3527 this operator was defined in terms of operator< of the contained type T and imposed the LessThanComparable requirement. In the final acceptance step of optional by the committee, the definition was expressed in terms of std::less and the LessThanComparable requirement had been removed.

The inconsistency between operator== and operator< should be removed. One possible course of action would be to add the LessThanComparable to std::experimental::optional::operator<. The EqualityComparable requirement of operator== could also be removed, but in that case both operators would at least need to require the BooleanTestable requirements (see 2114) for the result type of T's operator== and operator<.

Arguably, corresponding operators for pair and tuple do not impose LessThanComparable (nor EqualityComparable), albeit the definition of the "derived" relation functions depend on properties ensured by LessThanComparable. According to the SGI definition, the intention was to imposed both EqualityComparable and LessThanComparable. If this is not intended, the standard should clarify this position.

[2015-02 Cologne]

VV, DK, JY discuss why and when LessThanComparable was removed. AM: Move to LEWG. Please tell LWG when you look at it.

[2016-11-08, Issaquah]

Not adopted during NB comment resolution

[LEWG Kona 2017]

Recommend NAD: We've done a lot of work getting the C++17 semantics we want in this area; we're not going to change them 3 days from DIS or change the TSv2 behavior to be different from '17.

Proposed resolution:


2600(i). ios_base must store inaccessible iostate flags

Section: 27.5.3.5 [ios.base.storage] Status: Tentatively NAD Submitter: David Krauss Opened: 2016-03-14 Last modified: 2018-06-21

Priority: Not Prioritized

View all other issues in [ios.base.storage].

View all issues with Tentatively NAD status.

Discussion:

DR 41, "Ios_base needs clear(), exceptions()" stopped short of providing the interface suggested in its title, but it did require the underlying state to be stored in ios_base. Because rdstate() is also missing, ios_base manipulators relying on iword and pword cannot detect failure. The only safe alternative is to manipulate a derived class, which must be a template.

libc++ already provides the interface as a nonconforming extension. libstdc++ implements the internal state but leaves it frustratingly inaccessible, as specified. Any conforming implementation should be able to provide the interface without ABI problems.

[2016-04, Issues Telecon]

This is really a request for an (feature) API. Passing to LEWG.

[LEWG Kona 2017]

Recommend NAD: iostreams aren't used in this way enough to spend committee time on it. However, a paper could change our minds.

Proposed resolution:


3122(i). __cpp_lib_chrono_udls was accidentally dropped

Section: 16.3.1 [support.limits.general] Status: Tentatively Ready Submitter: Stephan T. Lavavej Opened: 2018-06-14 Last modified: 2018-06-24

Priority: 0

View other active issues in [support.limits.general].

View all other issues in [support.limits.general].

View all issues with Tentatively Ready status.

Discussion:

Between P0941R0 and P0941R1/P0941R2, the feature-test macro __cpp_lib_chrono_udls was dropped. It wasn't mentioned in the changelog, and Jonathan Wakely and I believe that this was unintentional.

[2018-06-23 Moved to Tentatively Ready after 5 positive votes on c++std-lib.]

Proposed resolution:

This wording is relative to the post-Rapperswil 2018 working draft.

In 16.3.1 [support.limits.general], "Table ??? - Standard library feature-test macros", add the following row:

Table ??? — Standard library feature-test macros
Macro name Value Headers
[…]
__cpp_lib_chrono_udls 201304L <chrono>
[…]

3127(i). basic_osyncstream::rdbuf needs a const_cast

Section: 27.10.3.1 [syncstream.osyncstream.overview] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-06-29 Last modified: 2018-07-20

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

The current specification of basic_osyncstream::rdbuf() is

    syncbuf_type* rdbuf() const noexcept { return &sb; }

This is ill-formed because the exposition-only member sb is const inside this const member function, but the return type is a pointer to non-const syncbuf_type. It needs to cast away the constness, consistent with the other streams with embedded stream buffers (such as string and file streams).

[2018-07-20 Status set to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4750.

  1. Change 27.10.3.1 [syncstream.osyncstream.overview], class template basic_osyncstream synopsis, as indicated:

    namespace std {
      template<class charT, class traits, class Allocator>
      class basic_osyncstream : public basic_ostream<charT, traits> {
      public:
        […]
    
        // 27.10.3.4 [syncstream.osyncstream.members], member functions
        void emit();
        streambuf_type* get_wrapped() const noexcept;
        syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(&sb); }
        […]
      };
    }
    

3128(i). strstream::rdbuf needs a const_cast

Section: D.8.5.3 [depr.strstream.oper] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-06-30 Last modified: 2018-07-20

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

strstream::rdbuf has the same issue with a missing const_cast on &sb.

Somewhat amusingly, istrstream::rdbuf and ostrstream::rdbuf got this right, but each with a different style (see issue 252).

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4750.

  1. Change D.8.5.3 [depr.strstream.oper] p1 as indicated:

    strstreambuf* rdbuf() const;
    

    -1- Returns: const_cast<strstreambuf*>(&sb).


3129(i). regex_token_iterator constructor uses wrong pointer arithmetic

Section: 28.12.2.1 [re.tokiter.cnstr] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-06-30 Last modified: 2018-07-20

Priority: 0

View all other issues in [re.tokiter.cnstr].

View all issues with Tentatively Ready status.

Discussion:

The specification of regex_token_iterator for the overload taking a const int (&submatchs)[N] uses the range [&submatches, &submatches + N). This is obviously incorrect; we want to perform pointer arithmetic on a pointer to the first element of that array, not a pointer to the whole array.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4750.

  1. Change 28.12.2.1 [re.tokiter.cnstr] p3 as indicated:

    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                         const regex_type& re,
                         int submatch = 0,
                         regex_constants::match_flag_type m = regex_constants::match_default);
    
    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                         const regex_type& re,
                         const vector<int>& submatches,
                         regex_constants::match_flag_type m = regex_constants::match_default);
    
    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                         const regex_type& re,
                         initializer_list<int> submatches,
                         regex_constants::match_flag_type m = regex_constants::match_default);
    
    template<size_t N>
      regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
                           const regex_type& re,
                           const int (&submatches)[N],
                           regex_constants::match_flag_type m = regex_constants::match_default);
    

    -2- Requires: […]

    -3- Effects: The first constructor initializes the member subs to hold the single value submatch. The second constructor initializes the member subs to hold a copy of the argument submatches. The second, third and fourth constructors initialize the member subs to hold a copy of the sequence of integer values pointed to by the iterator range [submatches.begin(), submatches.end()) and [&submatches, &submatches + N), respectively[begin(submatches), end(submatches)).

    -4- […]


3130(i). §[input.output] needs many addressof

Section: 27 [input.output] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-06-30 Last modified: 2018-07-20

Priority: 0

View other active issues in [input.output].

View all other issues in [input.output].

View all issues with Tentatively Ready status.

Discussion:

There are 27 instances of &sb and one instance of &rhs in Clause 27 [input.output], each of which needs to use addressof because the operand has a user-provided template type parameter as an associated class and so the use of unary & is subject to ADL hijacking.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4750.

  1. Change 27.5.5.3 [basic.ios.members] p16 as indicated:

    basic_ios& copyfmt(const basic_ios& rhs);
    

    -16- Effects: If (this == &addressof(rhs)) does nothing. […]

  2. Change 27.8.3.1 [istringstream.cons] as indicated:

    explicit basic_istringstream(ios_base::openmode which);
    

    -1- Effects: Constructs an object of class basic_istringstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(&addressof(sb)) (27.7.4.1 [istream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(which | ios_base::in) (27.8.2.1 [stringbuf.cons]).

    explicit basic_istringstream(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::in);
    

    -2- Effects: Constructs an object of class basic_istringstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(&addressof(sb)) (27.7.4.1 [istream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(str, which | ios_base::in) (27.8.2.1 [stringbuf.cons]).

    basic_istringstream(basic_istringstream&& rhs);
    

    -3- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_stringbuf. Next basic_istream<charT, traits>::set_rdbuf(&addressof(sb)) is called to install the contained basic_stringbuf.

  3. Change 27.8.3.3 [istringstream.members] p1 as indicated:

    basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
    

    -1- Returns: const_cast<basic_stringbuf<charT, traits, Allocator>*>(&addressof(sb)).

  4. Change 27.8.4.1 [ostringstream.cons] as indicated:

    explicit basic_ostringstream(ios_base::openmode which);
    

    -1- Effects: Constructs an object of class basic_ostringstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(&addressof(sb)) (27.7.5.1 [ostream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(which | ios_base::out) (27.8.2.1 [stringbuf.cons]).

    explicit basic_ostringstream(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::out);
    

    -2- Effects: Constructs an object of class basic_ostringstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(&addressof(sb)) (27.7.5.1 [ostream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(str, which | ios_base::out) (27.8.2.1 [stringbuf.cons]).

    basic_ostringstream(basic_ostringstream&& rhs);
    

    -3- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_stringbuf. Next basic_ostream<charT, traits>::set_rdbuf(&addressof(sb)) is called to install the contained basic_stringbuf.

  5. Change 27.8.4.3 [ostringstream.members] p1 as indicated:

    basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
    

    -1- Returns: const_cast<basic_stringbuf<charT, traits, Allocator>*>(&addressof(sb)).

  6. Change 27.8.5.1 [stringstream.cons] as indicated:

    explicit basic_stringstream(ios_base::openmode which);
    

    -1- Effects: Constructs an object of class basic_stringstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(&addressof(sb)) (27.7.4.6.1 [iostream.cons]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(which).

    explicit basic_stringstream(
      const basic_string<charT, traits, Allocator>& str,
      ios_base::openmode which = ios_base::out | ios_base::in);
    

    -2- Effects: Constructs an object of class basic_stringstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(&addressof(sb)) (27.7.4.6.1 [iostream.cons]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(str, which).

    basic_stringstream(basic_stringstream&& rhs);
    

    -3- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_stringbuf. Next basic_istream<charT, traits>::set_rdbuf(&addressof(sb)) is called to install the contained basic_stringbuf.

  7. Change 27.8.5.3 [stringstream.members] p1 as indicated:

    basic_stringbuf<charT, traits, Allocator>* rdbuf() const;
    

    -1- Returns: const_cast<basic_stringbuf<charT, traits, Allocator>*>(&addressof(sb)).

  8. Change 27.9.3.1 [ifstream.cons] as indicated:

    basic_ifstream();
    

    -1- Effects: Constructs an object of class basic_ifstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(&addressof(sb)) (27.7.4.1.1 [istream.cons]) and initializing sb with basic_filebuf<charT, traits>() (27.9.2.1 [filebuf.cons]).

    explicit basic_ifstream(const char* s,
                            ios_base::openmode mode = ios_base::in);
    explicit basic_ifstream(const filesystem::path::value_type* s,
                            ios_base::openmode mode = ios_base::in);  // wide systems only; see 27.9.1 [fstream.syn]
    

    -2- Effects: Constructs an object of class basic_ifstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(&addressof(sb)) (27.7.4.1.1 [istream.cons]) and initializing sb with basic_filebuf<charT, traits>() (27.9.2.1 [filebuf.cons]), then calls rdbuf()->open(s, mode | ios_base::in). If that function returns a null pointer, calls setstate(failbit).

    […]

    basic_ifstream(basic_ifstream&& rhs);
    

    -4- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_filebuf. Next basic_istream<charT, traits>::set_rdbuf(&addressof(sb)) is called to install the contained basic_filebuf.

  9. Change 27.9.3.3 [ifstream.members] p1 as indicated:

    basic_filebuf<charT, traits>* rdbuf() const;
    

    -1- Returns: const_cast<basic_filebuf<charT, traits>*>(&addressof(sb)).

  10. Change 27.9.4.1 [ofstream.cons] as indicated:

    basic_ofstream();
    

    -1- Effects: Constructs an object of class basic_ofstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(&addressof(sb)) (27.7.5.1.1 [ostream.cons]) and initializing sb with basic_filebuf<charT, traits>() (27.9.2.1 [filebuf.cons]).

    explicit basic_ofstream(const char* s,
                            ios_base::openmode mode = ios_base::out);
    explicit basic_ofstream(const filesystem::path::value_type* s,
                            ios_base::openmode mode = ios_base::out);  // wide systems only; see 27.9.1 [fstream.syn]
    

    -2- Effects: Constructs an object of class basic_ofstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(&addressof(sb)) (27.7.5.1.1 [ostream.cons]) and initializing sb with basic_filebuf<charT, traits>() (27.9.2.1 [filebuf.cons]), then calls rdbuf()->open(s, mode | ios_base::out). If that function returns a null pointer, calls setstate(failbit).

    […]

    basic_ofstream(basic_ofstream&& rhs);
    

    -4- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_filebuf. Next basic_ostream<charT, traits>::set_rdbuf(&addressof(sb)) is called to install the contained basic_filebuf.

  11. Change 27.9.4.3 [ofstream.members] p1 as indicated:

    basic_filebuf<charT, traits>* rdbuf() const;
    

    -1- Returns: const_cast<basic_filebuf<charT, traits>*>(&addressof(sb)).

  12. Change 27.9.5.1 [fstream.cons] as indicated:

    basic_fstream();
    

    -1- Effects: Constructs an object of class basic_fstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(&addressof(sb)) (27.7.4.6.1 [iostream.cons]) and initializing sb with basic_filebuf<charT, traits>().

    explicit basic_fstream(
      const char* s,
      ios_base::openmode mode = ios_base::in | ios_base::out);
    explicit basic_fstream(
      const filesystem::path::value_type* s,
      ios_base::openmode mode = ios_base::in | ios_base::out);  // wide systems only; see 27.9.1 [fstream.syn]
    

    -2- Effects: Constructs an object of class basic_fstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(&addressof(sb)) (27.7.4.6.1 [iostream.cons]) and initializing sb with basic_filebuf<charT, traits>(), then calls rdbuf()->open(s, mode). If that function returns a null pointer, calls setstate(failbit).

    […]

    basic_fstream(basic_fstream&& rhs);
    

    -4- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_filebuf. Next basic_istream<charT, traits>::set_rdbuf(&addressof(sb)) is called to install the contained basic_filebuf.

  13. Change 27.9.5.3 [fstream.members] p1 as indicated:

    basic_filebuf<charT, traits>* rdbuf() const;
    

    -1- Returns: const_cast<basic_filebuf<charT, traits>*>(&addressof(sb)).

  14. Change 27.10.3.1 [syncstream.osyncstream.overview], class template basic_osyncstream synopsis, as indicated:

    [Drafting note: The text shown below assumes the application of the proposed resolution of issue 3127.]

    namespace std {
      template<class charT, class traits, class Allocator>
      class basic_osyncstream : public basic_ostream<charT, traits> {
      public:
        […]
    
        // 27.10.3.4 [syncstream.osyncstream.members], member functions
        void emit();
        streambuf_type* get_wrapped() const noexcept;
        syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(&addressof(sb)); }
        […]
      };
    }
    
  15. Change 27.10.3.2 [syncstream.osyncstream.cons] p1 and p4 as indicated:

    basic_osyncstream(streambuf_type* buf, const Allocator& allocator);
    

    -1- Effects: Initializes sb from buf and allocator. Initializes the base class with basic_ostream<charT, traits>(&addressof(sb)).

    -2- […]

    -3- […]

    basic_osyncstream(basic_osyncstream&& other) noexcept;
    

    -4- Effects: Move constructs the base class and sb from the corresponding subobjects of other, and calls basic_ostream<charT, traits>::set_rdbuf(&addressof(sb)).

    -5- […]


3131(i). addressof all the things

Section: 25.12 [time.parse], 20.3.2.7.1 [string.accessors], 20.4.2 [string.view.template], 21.2.1 [container.requirements.general], 22.2.4 [output.iterators], 22.2.6 [bidirectional.iterators], 28.7 [re.traits], 28.12.1 [re.regiter], 30.4.4.1 [thread.lock.guard] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-06-30 Last modified: 2018-07-20

Priority: 0

View all issues with Tentatively Ready status.

Discussion:

Some additional instances where the library specification applies unary operator & when it should use addressof.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4750.

[Drafting note: Two uses of & in 22.5.1 [reverse.iterators] are not included in the wording below because the entire sentence is slated to be removed by a revision of P0896, the One Ranges Proposal.]

  1. Change 25.12 [time.parse] p4-5 as indicated:

    template<class charT, class traits, class Alloc, class Parsable>
      unspecified
        parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
              basic_string<charT, traits, Alloc>& abbrev);
    

    -4- Remarks: This function shall not participate in overload resolution unless

    from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, &addressof(abbrev))
    

    is a valid expression.

    -5- Returns: A manipulator that, when extracted from a basic_istream<charT, traits> is, calls from_stream(is, fmt.c_str(), tp, &addressof(abbrev)).

  2. Change 25.12 [time.parse] p8-9 as indicated:

    template<class charT, class traits, class Alloc, class Parsable>
      unspecified
        parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
              basic_string<charT, traits, Alloc>& abbrev, minutes& offset);
    

    -8- Remarks: This function shall not participate in overload resolution unless

    from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, &addressof(abbrev), &offset)
    

    is a valid expression.

    -9- Returns: A manipulator that, when extracted from a basic_istream<charT, traits> is, calls from_stream(is, fmt.c_str(), tp, &addressof(abbrev), &offset).

  3. Change 20.3.2.7.1 [string.accessors] p1 and p4 as indicated:

    const charT* c_str() const noexcept;
    const charT* data() const noexcept;
    

    -1- Returns: A pointer p such that p + i == &addressof(operator[](i)) for each i in [0, size()].

    -2- Complexity: Constant time.

    -3- Requires: The program shall not alter any of the values stored in the character array.

    charT* data() noexcept;
    

    -4- Returns: A pointer p such that p + i == &addressof(operator[](i)) for each i in [0, size()].

    -5- Complexity: Constant time.

    -6- Requires: The program shall not alter the value stored at p + size().

  4. Change 20.4.2.2 [string.view.iterators] p4 as indicated:

    constexpr const_iterator begin() const noexcept;
    constexpr const_iterator cbegin() const noexcept;
    

    -4- Returns: An iterator such that

    (4.1) — if !empty(), &addressof(*begin()) == data_,

    (4.2) — otherwise, an unspecified value such that [begin(), end()) is a valid range.

  5. Change 20.4.2.6 [string.view.ops] p21 and p24 as indicated:

    constexpr bool starts_with(charT x) const noexcept;
    

    -21- Effects: Equivalent to: return starts_with(basic_string_view(&addressof(x), 1));

    […]

    constexpr bool ends_with(charT x) const noexcept;
    

    -24- Effects: Equivalent to: return ends_with(basic_string_view(&addressof(x), 1));

  6. Change 20.4.2.7 [string.view.find] p5 as indicated:

    -5- Each member function of the form

    constexpr return-type F(charT c, size_type pos);
    

    is equivalent to return F(basic_string_view(&addressof(c), 1), pos);

  7. Edit 21.2.1 [container.requirements.general], Table 77 — "Container requirements", as indicated:

    Table 77 — Container requirements
    Expression Return type Operational
    semantics
    Assertion/note
    pre/post-condition
    Complexity
    […]
    (&a)->a.~X() void the destructor is applied to every element of a; any memory obtained is deallocated. linear
    […]
  8. Edit 22.2.4 [output.iterators], Table 90 — "Output iterator requirements (in addition to Iterator)", as indicated:

    Table 90 — Output iterator requirements (in addition to Iterator)
    Expression Return type Operational
    semantics
    Assertion/note
    pre/post-condition
    […]
    ++r X& &addressof(r) == &addressof(++r).
    […]
    […]
  9. Edit 22.2.6 [bidirectional.iterators], Table 92 — "Bidirectional iterator requirements (in addition to forward iterator)", as indicated:

    Table 92 — Bidirectional iterator requirements (in addition to forward iterator)
    Expression Return type Operational
    semantics
    Assertion/note
    pre/post-condition
    --r X& […]
    &addressof(r) == &addressof(--r).
    […]
  10. Change 28.7 [re.traits] p6 as indicated:

    template<class ForwardIterator>
      string_type transform(ForwardIterator first, ForwardIterator last) const;
    

    -6- Effects: As if by:

    string_type str(first, last);
    return use_facet<collate<charT>>(
      getloc()).transform(&*str.begindata(), &*str.begindata() + str.length());
    
  11. Change 28.12.1.1 [re.regiter.cnstr] p2 as indicated:

    regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
                   const regex_type& re,
                   regex_constants::match_flag_type m = regex_constants::match_default);
    

    -2- Effects: Initializes begin and end to a and b, respectively, sets pregex to &addressof(re), sets flags to m, then calls regex_search(begin, end, match, *pregex, flags). If this call returns false the constructor sets *this to the end-of-sequence iterator.

  12. Change 28.12.1.3 [re.regiter.deref] p2 as indicated:

    const value_type* operator->() const;
    

    -2- Returns: &addressof(match).

  13. Change 30.4.4.1 [thread.lock.guard] p2-7 as indicated:

    explicit lock_guard(mutex_type& m);
    

    -2- Requires: If mutex_type is not a recursive mutex, the calling thread does not own the mutex m.

    -3- Effects: As if byInitializes pm with m. Calls m.lock().

    -4- Postconditions: &pm == &m

    lock_guard(mutex_type& m, adopt_lock_t);
    

    -5- Requires: The calling thread owns the mutex m.

    -6- Postconditions: &pm == &mEffects: Initializes pm with m.

    -7- Throws: Nothing.


3132(i). Library needs to ban macros named expects or ensures

Section: 15.5.4.3.2 [macro.names] Status: Tentatively Ready Submitter: Tim Song Opened: 2018-06-30 Last modified: 2018-07-20

Priority: 0

View all other issues in [macro.names].

View all issues with Tentatively Ready status.

Discussion:

expects and ensures are not technically described as attribute-tokens when used in a contract-attribute-specifier, so the existing prohibition in 15.5.4.3.2 [macro.names] doesn't apply to them.

The remaining special identifiers used by the contract attributes are all already covered by existing wording: assert is also a library name so falls under p1, default is a keyword, and both axiom and audit were added to Table 4.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4750.

  1. Change 15.5.4.3.2 [macro.names] p2 as indicated:

    -2- A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 4, or to the attribute-tokens described in 9.11 [dcl.attr], or to the identifiers expects or ensures.


3134(i). [fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961

Section: 3.3.1 [fund.ts.v3::meta.type.synop] Status: Tentatively Ready Submitter: Thomas Köppe Opened: 2018-07-02 Last modified: 2018-07-20

Priority: 0

View other active issues in [fund.ts.v3::meta.type.synop].

View all other issues in [fund.ts.v3::meta.type.synop].

View all issues with Tentatively Ready status.

Discussion:

Addresses: fund.ts.v3

The LFTSv3 prospective-working-paper N4758 lists a large number of type trait variable templates in [meta.type.synop] that are duplicates of corresponding ones in C++17. The paper P0996R1 that was meant to rebase the LFTS on C++17 appears to have missed them.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4758.

  1. Delete from 3.3.1 [fund.ts.v3::meta.type.synop] all variable templates starting at is_void_v up to and including is_convertible_v as indicated:

    #include <type_traits>
    
    namespace std::experimental {
    inline namespace fundamentals_v3 {
    
      // See C++17 §23.15.4.1, primary type categories
      template <class T> constexpr bool is_void_v
        = is_void<T>::value;
      […]
      template <class From, class To> constexpr bool is_convertible_v
        = is_convertible<From, To>::value;
    
      // 3.3.2, Other type transformations
      template <class> class invocation_type; // not defined
      […]
    } // inline namespace fundamentals_v3
    } // namespace std::experimental
    

3137(i). Header for __cpp_lib_to_chars

Section: 16.3.1 [support.limits.general] Status: Tentatively Ready Submitter: S. B.Tam Opened: 2018-07-03 Last modified: 2018-07-20

Priority: 0

View other active issues in [support.limits.general].

View all other issues in [support.limits.general].

View all issues with Tentatively Ready status.

Discussion:

After acceptance of P0941R2 into the working draft, in [support.limits.general], __cpp_lib_to_chars is required to be in <utility>. Since the relevant feature (std::to_chars and std::from_chars) is now in the header <charconv>, should the macro be defined in <charconv> instead of <utility>?

[Marshall provides P/R and context]

std::to_chars, etc were originally proposed for the header <utility> and SD-6 reflected that. Somewhere along the way, they was put into their own header <charconv>, but the document was never updated to reflect that.

When these macros were added to the standard, the (now incorrect) value was copied as well.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

Proposed resolution:

This wording is relative to (the Rapperswil post-mailing standard).

Change 16.3.1 [support.limits.general] (Table 35) as indicated:

Macro nameValueHeader(s)
__cpp_lib_to_chars201611L<charconvutility>