Document number: N3157=10-0147
Date: 2010-10-14
J. Daniel Garcia
Project: Programming Language C++, Library Working Group
Reply To: josedaniel.garcia@uc3m.es

N3157 - More on noexcept for the General Utilities Library

During the Rapperswil meeting the Library Working Group decided to revise the library in terms of no except. This paper presents proposed wording for some of these changes. The paper addresses National Body comments CH 16 and GB 60.

This paper poposes additional changes to those presented in N3148 and N3149. Changes in this paper are restricted to chapter 20 (general utilities library).

Discussion

Allocators requirement impact

According to Allocator requirements, the following members should not throw: This affects to: Besides in scoped_allocator member functions inner_allocator and outer_allocator cannot throw as they return references to allocators.

Utility components

The generic relational operators may throw only if operators they are based on (== and <) may throw. This paper makes them conditionally noexcept.

Function swap() is not able to throw if the corresponding move construction is not able to throw. This paper makes it conditionally noexcept. The array specialization of swap() can be made noexcept in the cases where individual swap() does not throw.

Functions forward() and move() essentially perform type transformations and therefore cannot throw. The same can be applied

Class pair and associated functions has been revised in detail as its noexceptspecifications depends on its parts. The same has been done for class tuple.

Bitset

Some constructors of bitset cannot throw. This is the case of the following constructors:
constexpr bitset();
constexpr bitset(unsigned long long val);

Many bitset members do not need to throw. For example, setting a bit should not throw. However, those member functions did not have a throw() specification. The proposal is to make all of them noexcept. This also affects to some free operators (&, | and ^).

However, some operators (<<, >>, <<= and >>=) remain noexcept(false) as the specification does not have any requires elements, and the intro says that generally bound violations may throw exceptions.

Function objects

Arithmetic operations, comparisons, logical operations and bitwise operations are exception free if the operator they are based on is also exception free. As this can easily expressed with noexcept clausus of the form noexcept(noexcept(x op y)), those specs have been added. This has also been done for negators.

For the polymorphic function wrapper the following changes have been made:

Memory

For allocator traits, all the operations are defined in terms of the corresponding operation in the allocator. For every operation, the noexcept spec has been defined in terms of the corresponding allocator operation spec. However when the allocator requirements at 20.2.5 specifies an operation as non-throwing, the operation has been made noexcept(true)

Destroying trhough an allocator can only throw if the corresponding class has a throwing destrcutor. The destroy member function has been made conditionally noexceptin allocator traits and allocators.

Getting the address of a reference through an allocator (allocator<T>::address()) does not throw. Not that it does not make use of operator& which avoids the activation of a user-defined unary operator& which could throw. Thus, address() operation has been made noexcept.

Operations in class raw_storage_iterator should not throw (except assignment). All its members have been made noexcept. For the particular case of assignment it has been made conditionally noexcept. This operation may throw only if T's assignmet throws.

Temporary buffers management functions do not throw. Instead get_temporary_buffer returns a pair of 0 values if not successful. They have been maded noexcept.

Uninitialized copy algorithms can throw only if the constructor of the iterator value type can throw. This is derived from 29.9.9/1 (the formal template parameter Input Iterator is required to have the property that no exceptions are thrown from increment, assignment, comparison, or dereference of valid iterators. Those algorithms have been made conditionally noexcept.

Default deleters do not need to throw on construction. Besides, operator() is specified to invoke delete on the received ptr. That could throw only if the destructor throws.

operator* for unique_ptr and operator[] for array specialization of unique_ptr both are based on get() which does not throw. So both operators have been made noexcept. The same is applied to sepcializations of swap() algorithm (based on non-throwing swap() member function).

Relational operators on unique_ptr may throw if the corresponding operator on pointer types may throw. Thus, these operators have been made conditionally noexcept.

In shared_ptr, assignment operators are based on non-throwing swap(). However, only those versions based on non-throwing constructors may be made noexcept. The same can be applied to the first version of reset().

For weak_ptr member function reset() does not throw as it is based on non-throwing swap().

Some functions for atomic access to shared_ptrs (the non-explicit) ones have been made noexcept as they rest on the explicit versions, which are already non-throwing.

Function align does not throw because on failure it does nothing.

Scoped allocator

Because an scoped allocator must meet allocator requirements, its constructors cannot throw. Every constructor has been made noexcept.

Member functions for accessing inner and outer allocators all return references to the required allocator. They have been made noexcept.

Member function deallocate() must be non-throwing because of allocator requirements. It has been made noexcept.

Construction member functions will not throw if the corresponding constructor does not throw. That is expressed by means of contidional noexcept spec. The same is applied to the destruction member function.

Time utilities

All this section has been detailed reworked to include noexcept specs.

Open points

Acknowledgments

I am very grateful to Daniel Krügler and Pablo Halpern for their review and suggestions.

Proposed Wording

20.2.5 Allocator requirements

After p. 5
template <class Tp>
struct SimpleAllocator {
  typedef Tp value_type;
  SimpleAllocator(ctor args);

  template <class T> SimpleAllocator(const SimpleAllocator<T>& other) noexcept;

  Tp *allocate(std::size_t n);
  void deallocate(Tp *p, std::size_t n) noexcept;
};

20.3 Utility components

After p. 1
#include <initializer_list>
namespace std {
  // 20.3.1, operators:
  namespace rel_ops {
    template<class T> bool operator!=(const T&, const T&) noexcept(noexcept(x == y));
    template<class T> bool operator> (const T&, const T&) noexcept(noexcept(y < x));
    template<class T> bool operator<=(const T&, const T&) noexcept(noexcept(y < x));
    template<class T> bool operator>=(const T&, const T&) noexcept(noexcept(x < y));
  }

  // 20.3.2, swap:
  template<class T> void swap(T& a, T& b) noexcept(see below);
  template<class T, size_t N> void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a,*b)));
...
  // 20.3.3, forward/move:
  template <class T, class U> T&& forward(U&&) noexcept;
  template <class T> typename remove_reference<T>::type&& move(T&&) noexcept;
  template <class T> typename conditional<
    !has_nothrow_move_constructor<T>::value && has_copy_constructor<T>::value,
    const T&, T&&>::type move_if_noexcept(T& x) noexcept;
...
  // 20.3.5.3, pair specialized algorithms:
  template <class T1, class T2>
    bool operator==(const pair<T1,T2>&, const pair<T1,T2>&)
      noexcept(noexcept(x.first == y.first) &&
               noexcept(x.second == y.second));
  template <class T1, class T2>
    bool operator< (const pair<T1,T2>&, const pair<T1,T2>&)
      noexcept(noexcept(x.first < y.first) &&
               noexcept(y.first < x.first) &&
               noexcept(x.second < y.second));
  template <class T1, class T2>
    bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&)
      noexcept(noexcept(x == y));
  template <class T1, class T2>
    bool operator> (const pair<T1,T2>&, const pair<T1,T2>&)
      noexcept(noexcept(y < x));
  template <class T1, class T2>
    bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&)
      noexcept(noexcept(x < y));
  template <class T1, class T2>
    bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
      noexcept(noexcept(y < x));
  template <class T1, class T2>
    void swap(pair<T1,T2>&, pair<T1,T2>&)
      noexcept(noexcept(x.swap(y)));
  template <class T1, class T2>
    see below make_pair(T1&&, T2&&) noexcept(see below);

  // 20.3.5.4, tuple-like access to pair:
  ...
  template<size_t I, class T1, class T2>
    typename tuple_element<I, std::pair<T1, T2> >::type& get(std::pair<T1, T2>&)noexcept;
  template<size_t I, class T1, class T2> const
    typename const tuple_element<I, std::pair<T1, T2> >::type& get(const std::pair<T1, T2>&)noexcept;
...
}

20.3.1 Operators

After p. 1
template <class T> bool operator!=(const T& x, const T& y) noexcept(noexcept(x == y));
After p. 3
template <class T> bool operator>(const T& x, const T& y) noexcept(noexcept(y < x));
After p. 5
template <class T> bool operator<=(const T& x, const T& y) noexcept(noexcept(y < x));
After p. 7
template <class T> bool operator>=(const T& x, const T& y) noexcept(noexcept(x < y));

20.3.2 swap

Before p. 1
template<class T> void swap(T& a, T& b) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T,T&&>::value
Before p. 3
template<class T, size_t N>
  void swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a,*b)));

20.3.3 forward/move helpers

After p. 1
template <class T, class U> T&& forward(U&& u) noexcept;
After p. 5
template <class T> typename remove_reference<T>::type&& move(T&& t) noexcept;
After p. 8
template <class T> typename conditional<
  !has_nothrow_move_constructor<T>::value && has_copy_constructor<T>::value,
  const T&, T&&>::type move_if_noexcept(T& x) noexcept;

20.3.5.2 Class template pair

Before p. 1
namespace std {
  template <class T1, class T2>
  struct pair {
    typedef T1 first_type;
    typedef T2 second_type;

    T1 first;
    T2 second;
    pair(const pair&) = default;
    constexpr pair() noexcept(see below);
    pair(const T1& x, const T2& y) noexcept(see below);
    template<class U, class V> pair(U&& x, V&& y) noexcept(see below);
    template<class U, class V> pair(const pair<U, V>& p) noexcept(see below);
    template<class U, class V> pair(pair<U, V>&& p) noexcept(see below);
    template <class... Args1, class... Args2>
      pair(piecewise_construct_t,
	   tuple<Args1...> first_args, tuple<Args2...> second_args) noexcept(see below);

    template<class U, class V> pair& operator=(const pair<U, V>& p) noexcept(see below);
      pair& operator=(pair&& p);
    template<class U, class V> pair& operator=(pair<U, V>&& p) noexcept(see below);

    void swap(pair& p)
      noexcept(noexcept(swap(first, p.first)) &&
	       noexcept(swap(second, p.second)));
  };
}
constexpr pair() noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1>::value &&
  is_nothrow_constructible<T2>::value
Before p. 2
pair(const T1& x, const T2& y) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, const T1&>::value &&
  is_nothrow_constructible<T2, const T2&>::value
Before p. 3
template<class U, class V> pair(U&& x, V&& y) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, U&&>::value &&
  is_nothrow_constructible<T2, V&&>::value
Before p. 5
template<class U, class V> pair(const pair<U, V>& p) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, const U&>::value &&
  is_nothrow_constructible<T2, const V&>::value
Before p. 6
template<class U, class V> pair(pair<U, V>&& p) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, U&&>::value &&
  is_nothrow_constructible<T2, V&&>::value
Before p. 7
template<class... Args1, class... Args2>
  pair(piecewise_construct_t,
       tuple<Args1...> first_args, tuple<Args2...> second_args)noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, Args1&&...>::value &&
  is_nothrow_constructible<T2, Args2&&...>::value
Before p. 9
template<class U, class V> pair& operator=(const pair<U, V>& p) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(declval<T1&>() = declval<const U&>()) &&
  noexcept(declval<T2&>() = declval<const V&>())
Before p. 12
pair& operator=(pair&& p) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(declval<T1&>() = declval<T1&&>()) &&
  noexcept(declval<T2&>() = declval<T2&&>())
Before p. 14
template<class U, class V> pair& operator=(pair<U, V>&& p) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(declval<T1&>() = declval<U&&>()) &&
  noexcept(declval<T2&>() = declval<V&&>())
Before p. 16
void swap(pair& p)
  noexcept(noexcept(swap(first, p.first)) &&
	   noexcept(swap(second, p.second)));

20.3.5.3 Specialized algorithms

Before p. 1
template <class T1, class T2>
  bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y)
    noexcept(noexcept(x.first==y.first) &&
             noexcept(x.second==y.second));
After p. 1
template <class T1, class T2>
  bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
    noexcept(noexcept(x.first < y.first) &&
             noexcept(y.first < x.first) &&
             noexcept(x.second < y.second));
After p. 2
template <class T1, class T2>
  bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y)
    noexcept(noexcept(x == y));
After p. 3
template <class T1, class T2>
  bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y)
    noexcept(noexcept(y < x));
After p. 4
template <class T1, class T2>
  bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y)
    noexcept(noexcept(x < y));
After p. 5
template <class T1, class T2>
  bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y)
    noexcept(noexcept(y < x));
After p. 6
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
  noexcept(noexcept(x.swap(y)));
After p. 7
template <class T1, class T2>
  pair<V1, V2> make_pair(T1&&, T2&&) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<V1, T1&&>::value &&
  is_nothrow_constructible<V2, T2&&>::value

20.3.5.4 Tuple-like access to pair

After p. 4
template<size_t I, class T1, class T2>
  typename tuple_element<I, std::pair<T1, T2> >::type& get(pair<T1, T2>&) noexcept;
template<size_t I, class T1, class T2>
  const typename tuple_element<I, std::pair<T1, T2> >::type& get(const pair<T1, T2>&) noexcept;

20.4.1 In general

After p. 2
namespace std {
...
  // 20.4.2.4, tuple creation functions:
  const unspecified ignore;
  template <class... Types>
    tuple<VTypes...> make_tuple(Types&&...) noexcept(see below);
  template <class... Types>
    tuple<ATypes...> pack_arguments forward_as_tuple(Types&&...) noexcept;
  template<class... Types>
    tuple<Types&...> tie(Types&...) noexcept;
  template <class... TTypes, class... UTypes>
    tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(see below);
  template <class... TTypes, class... UTypes>
    tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&&, const tuple<UTypes...>&) noexcept(see below);
  template <class... TTypes, class... UTypes>
    tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>&, tuple<UTypes...>&&) noexcept(see below);
  template <class... TTypes, class... UTypes>
    tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&&, tuple<UTypes...>&&) noexcept(see below);
  ...
  // 20.4.2.6, element access:
  template <size_t I, class... Types>
    typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&) noexcept(see below);
  template <size_t I, class ... types>
    typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>&) noexcept(see below);
  
  // 20.4.2.7, relational operators:
  template<class... TTypes, class... UTypes>
    bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(see below);
  template<class... TTypes, class... UTypes>
    bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(see below);
  template<class... TTypes, class... UTypes>
    bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(t == u);
  template<class... TTypes, class... UTypes>
    bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(u < t);
  template<class... TTypes, class... UTypes>
    bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(u < t);
  template<class... TTypes, class... UTypes>
    bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&) noexcept(t < u);
  ...
  // 20.4.2.9, specialized algorithms:
  template <class... Types>
    void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
}

20.4.2 Class template tuple

Before p. 1
namespace std {
  template <class... Types>
  class tuple {
  public:

    // 20.4.2.1, tuple construction
    constexpr tuple() noexcept(see below);
    explicit tuple(const Types&...) noexcept(see below);
    template <class... UTypes>
      explicit tuple(UTypes&&...) noexcept(see below);
  
    tuple(const tuple&) = default noexcept(see below);
    tuple(tuple&&) noexcept(see below);
  
    template <class... UTypes>
      tuple(const tuple<UTypes...>&) noexcept(see below);
    template <class... UTypes>
      tuple(tuple<UTypes...>&&) noexcept(see below);
  
    template <class U1, class U2>
      tuple(const pair<U1, U2>&) noexcept(see below); // iff sizeof...(Types) == 2
    template <class U1, class U2>
      tuple(pair<U1, U2>&&) noexcept(see below); // iff sizeof...(Types) == 2
  
    // allocator-extended constructors
    template <class Alloc>
      tuple(allocator_arg_t, const Alloc& a) noexcept(see below);
    template <class Alloc>
      tuple(allocator_arg_t, const Alloc& a, const Types&...) noexcept(see below);
    template <class Alloc, class... UTypes>
      tuple(allocator_arg_t, const Alloc& a, const UTypes&&...) noexcept(see below);
    template <class Alloc>
      tuple(allocator_arg_t, const Alloc& a, const tuple&) noexcept(see below);
    template <class Alloc>
      tuple(allocator_arg_t, const Alloc& a, tuple&&) noexcept(see below);
    template <class Alloc, class... UTypes>
      tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&) noexcept(see below);
    template <class Alloc, class... UTypes>
      tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&) noexcept(see below);
    template <class Alloc, class U1, class U2>
      tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&) noexcept(see below);
    template <class Alloc, class U1, class U2>
      tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&) noexcept(see below);
  
    // 20.4.2.2, tuple assignment
    tuple& operator=(const tuple&) noexcept(see below);
    tuple& operator=(tuple&&) noexcept(see below);
  
    template <class... UTypes>
      tuple& operator=(const tuple<UTypes...>&) noexcept(see below);
    template <class... UTypes>
      tuple& operator=(tuple<UTypes...>&&) noexcept(see below);
  
    template <class U1, class U2>
      tuple& operator=(const pair<U1, U2>&) noexcept(see below); // iff sizeof...(Types) == 2
    template <class U1, class U2>
      tuple& operator=(pair<U1, U2>&&) noexcept(see below); // iff sizeof...(Types) == 2
  
    // 20.4.2.3, tuple swap
    void swap(tuple&) noexcept(declval<tuple<Types...>&>().swap(declval<tuple<Types...>&>()));

  };
}

20.4.2.1 Construction

1 For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception.

Before p. 2
constexpr tuple() noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti>::value

where Ti is the i-th type in Types

Before p. 4
explicit tuple(const Types&...) noexceptsee below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, const Ti&>::value

where Ti is the i-th type in Types.

Before p. 6
template <class... UTypes>
  explicit tuple(UTypes&&... u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, Ui&&>::value

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

Before p. 10
tuple(tuple&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, Ti&&>::value

where Ti is the i-th type in Types.

Before p. 12
template <class... UTypes> tuple(const tuple<UTypes...>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, const Ui&>::value

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

Before p. 15
template <class... UTypes> tuple(tuple<UTypes...>&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, Ui&&>::value

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

Before p. 17
template <class U1, class U2> tuple(const pair<U1, U2>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, const U1&>::value &&
  is_nothrow_constructible<T2, const U2&>::value

where Ti is the i-th type in Types.

Before p. 19
template <class U1, class U2> tuple(pair<U1, U2>&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, U1&&>::value &&
  is_nothrow_constructible<T2, U2&&>::value

where Ti is the i-th type in Types.

Before p. 21
template <class Alloc>
  tuple(allocator_arg_t, const Alloc& a) noexcept(see below);
template <class Alloc>
  tuple(allocator_arg_t, const Alloc& a, const Types&...) noexcept(see below);
template <class Alloc, class... UTypes>
  tuple(allocator_arg_t, const Alloc& a, const UTypes&&...) noexcept(see below);
template <class Alloc>
  tuple(allocator_arg_t, const Alloc& a, const tuple&) noexcept(see below);
template <class Alloc>
  tuple(allocator_arg_t, const Alloc& a, tuple&&) noexcept(see below);
template <class Alloc, class... UTypes>
  tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&) noexcept(see below);
template <class Alloc, class... UTypes>
  tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&) noexcept(see below);
template <class Alloc, class U1, class U2>
  tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&) noexcept(see below);
template <class Alloc, class U1, class U2>
  tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the one in the preceding corresponding constructor.

20.4.2.2 Assignment

1 For each tuple assignment operator, an exception is thrown only if the assignment of one of the types in Types throws an exception

Before p. 2
tuple& operator=(const tuple& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(declval<Ti&>() = declval<const Ti&>())

where Ti is the i-th type in Types.

Before p. 5
tuple& operator=(tuple&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(declval<Ti&>() = declval<Ti&&>())

where Ti is the i-th type in Types.

Before p. 8
template <class... UTypes>
  tuple& operator=(const tuple<UTypes...>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(declval<Ti&>() = declval<const Ui&>())

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

Before p. 11
template <class... UTypes>
  tuple& operator=(tuple<UTypes...>&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(declval<Ti&>() = declval<Ui&&>())

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

Before p. 14
template <class U1, class U2> tuple& operator=(const pair<U1, U2>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  nothrow(declval<T1&>() = declval<const U1&>()) &&
  nothrow(declval<T2&>() = declval<const U2&>())

where Ti is the i-th type in Types.

Before p. 18
template <class U1, class U2> tuple& operator=(pair<U1, U2>&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  nothrow(declval<T1&>() = declval<U1&&>()) &&
  nothrow(declval<T2&>() = declval<U2&&>())

where Ti is the i-th type in Types.

20.4.2.3 swap

Before p. 1
void swap(tuple& rhs) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(swap(declval<Ti&>, declval<Ti&>))

where Ti is the i-th type in Types.

20.4.2.4 Tuple creation functions

Before p. 1
template<class... Types>
  tuple<VTypes...> make_tuple(Types&&... t) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Vi, Ti&&>::value

where Vi is the i-th type in VTypes and Ti is the i-th type in Types.

Before p. 4
template<class... Types>
  tuple<Types&&...>forward_as_tuple(Types&&... t) noexcept;
Before p. 6
template<class... Types>
  tuple<Types&...> tie(Types&... t) noexcept;
Before p. 8
template <class... TTypes, class... UTypes>
  tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, const Ti&>::value

where Ti is the i-th type in TTypes, and the logical and of the following expressions:

  is_nothrow_constructible<Ui, const Ui&>::value

where Ui is the i-th type in UTypes.

Before p. 10
template <class... TTypes, class... UTypes>
  tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&& t, const tuple<UTypes...>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, Ti&&>::value

where Ti is the i-th type in TTypes, and the logical and of the following expressions:

  is_nothrow_constructible<Ui, const Ui&>::value

where Ui is the i-th type in UTypes.

Before p. 12
template <class... TTypes, class... UTypes>
  tuple<TTypes..., UTypes...> tuple_cat(const tuple<TTypes...>& t, tuple<UTypes...>&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, const Ti&>::value

where Ti is the i-th type in TTypes, and the logical and of the following expressions:

  is_nothrow_constructible<Ui, Ui&&>::value

where Ui is the i-th type in UTypes.

Before p. 14
template <class... TTypes, class... UTypes>
  tuple<TTypes..., UTypes...> tuple_cat(tuple<TTypes...>&& t, tuple<UTypes...>&& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  is_nothrow_constructible<Ti, Ti&&>::value

where Ti is the i-th type in TTypes, and the logical and of the following expressions:

  is_nothrow_constructible<Ui, Ui&&>::value

where Ui is the i-th type in UTypes.

20.4.2.7 Relational operators

Before p. 1
template<class... TTypes, class... UTypes>
  bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(declval<const Ti &>() == declval<const Ui&>())

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

Before p. 4
template<class... TTypes, class... UTypes>
  bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:

  noexcept(declval<const Ti&>() < declval<const Ui&>())
  noexcept(declval<const Ui&>() < declval<const Ti&>())

where Ti is the i-th type in Types and Ui is the i-th type in UTypes.

After p. 4
template<class... TTypes, class... UTypes>
  bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(noexcept(t == u));
After p. 5
template<class... TTypes, class... UTypes>
  bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(noexcept(u < t));
After p. 6
template<class... TTypes, class... UTypes>
  bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(noexcept(u < t));
After p. 7
template<class... TTypes, class... UTypes>
  bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u) noexcept(noexcept(t < u));

20.4.2.9 Tuple specialized algorithms

Before p. 1
template <class... Types>
  void swap(tuple<Types...>& x, tuple<Types...>& y)
    noexcept(declval<tuple<Types...>&>().swap(declval<tuple<Types...>&>()));

20.5 Class template bitset

Before p. 1
#include <string>
#include <iosfwd> // for istream, ostream
namespace std {
  template <size_t N> class bitset;

  // 20.5.4 bitset operators:
  template <size_t N>
    bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;
  template <size_t N>
    bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;
  template <size_t N>
    bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;
  template <class charT, class traits, size_t N>
    basic_istream<charT, traits>&
    operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
  template <class charT, class traits, size_t N>
    basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
}
After p. 1
namespace std {
  template<size_t N> class bitset {
  public:
    // bit reference:
    class reference {
      friend class bitset;
      reference();
    public:
      ~reference();
      reference& operator=(bool x); // for b[i] = x;
      reference& operator=(const reference&); // for b[i] = b[j];
      bool operator~() const; // flips the bit
      operator bool() const; // for x = b[i];
      reference& flip(); // for b[i].flip();
    };

    // 20.5.1 constructors:
    constexpr bitset() noexcept;
    constexpr bitset(unsigned long long val) noexcept;
    template<class charT, class traits, class Allocator>
      explicit bitset(
        const basic_string<charT,traits,Allocator>& str,
        typename basic_string<charT,traits,Allocator>::size_type pos = 0,
        typename basic_string<charT,traits,Allocator>::size_type n =
          basic_string<charT,traits,Allocator>::npos,
          charT zero = charT(’0’), charT one = charT(’1’));
    explicit bitset(const char *str);

    // 20.5.2 bitset operations:
    bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
    bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
...
    bitset<N>& set() noexcept;
    bitset<N>& set(size_t pos, bool val = true);
    bitset<N>& reset() noexcept;
    bitset<N>& reset(size_t pos);
    bitset<N> operator~() const noexcept;
    bitset<N>& flip() noexcept;
    bitset<N>& flip(size_t pos);

    // element access:
    constexpr bool operator[](size_t pos) const; // for b[i];
    reference operator[](size_t pos); // for b[i];

    unsigned long to_ulong() const;
    unsigned long long to_ullong() const;
    template <class charT = char,
        class traits = char_traits<charT>,
        class Allocator = allocator<charT> >
      basic_string<charT, traits, Allocator>
      to_string(charT zero = charT(’0’), charT one = charT(’1’)) const;
    size_t count() const noexcept;
    constexpr size_t size() noexcept;
    bool operator==(const bitset<N>& rhs) const noexcept;
    bool operator!=(const bitset<N>& rhs) const noexcept;
    bool test(size_t pos);
    bool all() const noexcept;
    bool any() const noexcept;
    bool none() const noexcept;
...
  };

  // 20.5.3 Hash support
  template <class T> struct hash;
  template <size_t N> struct hash<bitset<N> >;
}

20.5.1 bitset constructors

Before p. 1
constexpr bitset() noexcept;
After p. 1
constexpr bitset(unsigned long long val) noexcept;

20.5.2 bitset members

Before p. 1
bitset<N>& operator&=(const bitset<N>& rhs) noexcept;
After p. 2
bitset<N>& operator|=(const bitset<N>& rhs) noexcept;
After p. 4
bitset<N>& operator^=(const bitset<N>& rhs) noexcept;
After p. 6
bitset<N>& operator<<=(size_t pos) noexcept;
After p. 8
bitset<N>& operator>>=(size_t pos) noexcept;
After p. 10
bitset<N>& set() noexcept;
After p. 16
bitset<N>& reset() noexcept;
After p. 22
bitset<N> operator~() const noexcept;
After p. 24
bitset<N>& flip() noexcept;
After p. 36
size_t count() const noexcept;
After p. 37
constexpr size_t size() noexcept;
After p. 38
bool operator==(const bitset<N>& rhs) const noexcept;
After p. 39
bool operator!=(const bitset<N>& rhs) const noexcept;
After p. 43
bool all() const noexcept;
After p. 44
bool any() const noexcept;
After p. 45
bool none() const noexcept;
After p. 46
bitset<N> operator<<(size_t pos) const noexcept;
After p. 47
bitset<N> operator>>(size_t pos) const noexcept;

20.5.4 bitset operators

Before p. 1
bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
After p. 1
bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;
After p. 2
bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs) noexcept;

20.8.5 Arithmetic operations

After p. 1
template <class T> struct plus : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x + y));
};
After p. 2
template <class T> struct minus : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x - y));
};
After p. 3
template <class T> struct multiplies : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x + y));
};
After p. 4
template <class T> struct divides : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x / y));
};
After p. 5
template <class T> struct modulus : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x % y));
};
After p. 6
template <class T> struct negate : unary_function<T,T> {
  T operator()(const T& x) const noexcept(noexcept(-x));
};

20.8.6 Comparisons

After p. 1
template <class T> struct equal_to : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x == y));
};
After p. 2
template <class T> struct not_equal_to : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x != y));
};
After p. 3
template <class T> struct greater : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x > y));
};
After p. 4
template <class T> struct less : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x < y));
};
After p. 5
template <class T> struct greater_equal : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x >= y));
};
After p. 6
template <class T> struct less_equal : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x <= y));
};

20.8.7 Logical operations

After p. 1
template <class T> struct logical_and : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x && y));
};
After p. 2
template <class T> struct logical_or : binary_function<T,T,bool> {
  bool operator()(const T& x, const T& y) const noexcept(noexcept(x || y));
};
After p. 3
template <class T> struct logical_not : unary_function<T,bool> {
  bool operator()(const T& x) const noexcept(noexcept(!x));
};

20.8.8 Bitwise operations

After p. 1
template <class T> struct bit_and : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x & y));
};
After p. 2
template <class T> struct bit_or : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x | y));
};
After p. 3
template <class T> struct bit_xor : binary_function<T,T,T> {
  T operator()(const T& x, const T& y) const noexcept(noexcept(x ^ y));
};

20.8.9 Negators

After p. 1
template <class Predicate>
  class unary_negate
    : public unary_function<typename Predicate::argument_type,bool> {
  public:
    explicit unary_negate(const Predicate& pred);
    bool operator()(const typename Predicate::argument_type& x) const noexcept(noexcept(!pred(x));
};
After p. 3
template <class Predicate>
  class binary_negate
    : public binary_function<typename Predicate::first_argument_type,
        typename Predicate::second_argument_type, bool> {
  public:
    explicit binary_negate(const Predicate& pred);
    bool operator()(const typename Predicate::first_argument_type& x,
		    const typename Predicate::second_argument_type& y) const
       noexcept(noexcept(!pred(x,y));
  };

20.8.14.1 Class bad_function_call

After p. 1
namespace std {
  class bad_function_call : public std::exception {
  public:
    // 20.8.14.1.1, constructor:
    bad_function_call() noexcept;
  };
} // namespace std

20.8.14.1.1 bad_function_call constructor

Before p. 1
bad_function_call() noexcept;

20.8.14.2 Class template function

Before p. 1
namespace std {
  template<class> class function; // undefined

  template<class R, class... ArgTypes>
  class function<R(ArgTypes...)>
    : public unary_function<T1, R> // iff sizeof...(ArgTypes) == 1 and ArgTypes contains T1
    : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and ArgTypes contains T1 and T2
  {
  public:
...
    function(function&&) noexcept;
...
    template<class A> 
      function(allocator_arg_t, const A&, function&&) noexcept;
...
    function& operator=(function&&) noexcept;
    function& operator=(nullptr_t) noexcept;
    template<class F> function& operator=(F&&) noexcept;
    template<class F> function& operator=(reference_wrapper<F>);

    ~function() noexcept;

    // 20.8.14.2.2, function modifiers:
...
    template<class F, class A> void assign(F&&, const A&) noexcept;
  };
...
  template <class R, class... ArgTypes>
    void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
...
}

20.8.14.2.1 function construct/copy/destroy

After p. 7
function(function&& f) noexcept;
template <class A> function(allocator_arg_t, const A& a, function&& f) noexcept;
After p. 14
function& operator=(function&& f) noexcept;
After p. 16
function& operator=(nullptr_t) noexcept;
After p. 19
template<class F> function& operator=(F&& f)noexcept;
After p. 24
~function() noexcept;

20.8.14.2.2 function modifiers

After p. 2
template<class F, class A>
  void assign(F&& f, const A& a) noexcept;

20.8.14.2.7 specialized algorithms

Before p. 1
template<class R, class... ArgTypes>
  void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>& f2) noexcept;

20.9 Memory

After p. 1
namespace std {
...
  // 20.9.8, temporary buffers:
  template <class T>
    pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
  template <class T>
    void return_temporary_buffer(T* p) noexcept;
...
  // 20.9.9, specialized algorithms:
...
  template <class InputIterator, class ForwardIterator>
    ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
				       ForwardIterator result) noexcept(see below);
  template <class InputIterator, class Size, class ForwardIterator>
    ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
					 ForwardIterator result) noexcept(see below);
  template <class ForwardIterator, class T>
    void uninitialized_fill(ForwardIterator first, ForwardIterator last,
			    const T& x) noexcept(see below);
  template <class ForwardIterator, class Size, class T>
    void uninitialized_fill_n(ForwardIterator first, Size n, const T& x) noexcept(see below);
...
    // 20.9.11.5, shared_ptr atomic access:
...
    template<class T>
      shared_ptr<T> atomic_load(const shared_ptr<T>* p) noexcept;
...
    template<class T>
      void atomic_store(shared_ptr<T>* p, shared_ptr<T> r) noexcept;
...
    template<class T>
      shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r) noexcept;
...
    template<class T>
      bool atomic_compare_exchange_weak(
        shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w) noexcept;
    template<class T>
      bool atomic_compare_exchange_strong(
        shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w) noexcept;
...
}

20.9.4 Allocator traits

After p. 1
namespace std {
  template <class Alloc> struct allocator_traits {
...
  static void deallocate(Alloc& a, pointer p, size_type n) noexcept;

  template <class T, class... Args>
    static void construct(Alloc& a, T* p, Args&&... args)
      noexcept(noexcept(a.construct(p,std::forward<Args>(args)...)));

  template <class T>
    static void destroy(Alloc& a, T* p) noexcept(noexcept(a.destroy(p)));
...
  };
}

20.9.4.2 Allocator traits static member functions

After p. 2
static void deallocate(Alloc& a, pointer p, size_type n) noexcept;
After p. 3
template <class T, class... Args>
  static void construct(Alloc& a, T* p, Args&&... args) 
    noexcept(noexcept(a.construct(p,std::forward<Args>(args)...)));
After p. 4
template <class T>
  static void destroy(Alloc& a, T* p) noexcept(noexcept(a.destroy(p)));

20.9.5 The default allocator

Before p. 1
namespace std {
  template <class T> class allocator;
...
  template <class T> class allocator {
  public:
...
    pointer address(reference x) const noexcept;
    const_pointer address(const_reference x) const noexcept;
...
    void deallocate(pointer p, size_type n) noexcept;
...
    template<class U, class... Args>
      void construct(U* p, Args&&... args) noexcept(see below);

    template <class U>
      void destroy(U* p) noexcept(noexcept(p->~U()));
...
  };
}

20.9.5.1 allocator members

After p. 1
pointer address(reference x) const noexcept;
After p. 2
const_pointer address(const_reference x) const noexcept;
After p. 7
void deallocate(pointer p, size_type n) noexcept;
After p. 11
template <class U, class... Args>
  void construct(U* p, Args&&... args) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<U,Args&&...>::value
After p. 12
template <class U>
  void destroy(U* p) noexcept(noexcept(p->~U()));

20.9.7 Raw storage iterator

After p. 1
namespace std {
  template <class OutputIterator, class T>
  class raw_storage_iterator
    : public iterator<output_iterator_tag,void,void,void,void> {
  public:
    explicit raw_storage_iterator(OutputIterator x) noexcept;

    raw_storage_iterator<OutputIterator,T>& operator*() noexcept;
    raw_storage_iterator<OutputIterator,T>& operator=(const T& element) noexcept(see below);
    raw_storage_iterator<OutputIterator,T>& operator++() noexcept;
    raw_storage_iterator<OutputIterator,T> operator++(int) noexcept;
  };
}
Before p. 2
raw_storage_iterator(OutputIterator x) noexcept;
After p. 2
raw_storage_iterator<OutputIterator,T>& operator*() noexcept;
After p. 3
raw_storage_iterator<OutputIterator,T>& operator=(const T& element) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T, const T&>::value
After p. 5
raw_storage_iterator<OutputIterator,T>& operator++() noexcept;
After p. 6
raw_storage_iterator<OutputIterator,T> operator++(int) noexcept;

20.9.8 Temporary buffers

Before p. 1
template <class T>
  pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
After p. 2
template <class T> void return_temporary_buffer(T* p) noexcept;

20.9.9.2 uninitialized_copy

Before p. 1
template <class InputIterator, class ForwardIterator>
  ForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
				     ForwardIterator result) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<decltype(*result),decltype(*first)>::value
After p. 2
template <class InputIterator, class Size, class ForwardIterator>
  ForwardIterator uninitialized_copy_n(InputIterator first, Size n,
                                       ForwardIterator result) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<decltype(*result),decltype(*first)>::value

20.9.9.3 uninitialized_fill

Before p. 1
template <class ForwardIterator, class T>
  void uninitialized_fill(ForwardIterator first, ForwardIterator last,
			  const T& x) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<decltype(*first),decltype(x)>::value

20.9.9.4 uninitialized_fill_n

Before p. 1
template <class ForwardIterator, class Size, class T>
  void uninitialized_fill_n(ForwardIterator first, Size n, const T& x) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<decltype(*first),decltype(x)>::value

20.9.10 Class template unique_ptr

After p. 6
namespace std {
  template<class T> struct default_delete;
  template<class T> struct default_delete<T[]>;

  template<class T, class D = default_delete<T>> class unique_ptr;
  template<class T, class D> class unique_ptr<T[], D>;

  template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) neoxcept;

  template<class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
      noexcept(declval<const unique_ptr<T1, D1>::pointer&>() == declval<const unique_ptr<T2, D2>::pointer&>());
  template<class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
      noexcept(declval<const unique_ptr<T1, D1>::pointer&>() != declval<const unique_ptr<T2, D2>::pointer&>());
  template<class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
      noexcept(declval<const unique_ptr<T1, D1>::pointer&>() < declval<const unique_ptr<T2, D2>::pointer&>());
  template<class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
      noexcept(declval<const unique_ptr<T1, D1>::pointer&>() <= declval<const unique_ptr<T2, D2>::pointer&>());
  template<class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
      noexcept(declval<const unique_ptr<T1, D1>::pointer&>() > declval<const unique_ptr<T2, D2>::pointer&>());
  template<class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
      noexcept(declval<const unique_ptr<T1, D1>::pointer&>() >= declval<const unique_ptr<T2, D2>::pointer&>());
}

20.9.10.1.2 default_delete

Before p. 1
namespace std {
  template <class T> struct default_delete {
    constexpr default_delete() noexcept;
    template <class U> default_delete(const default_delete<U>&) noexcept;
    void operator()(T* ptr) const noexcept(noexcept(ptr->~T()));
  };
}

constexpr default_delete() noexcept;
After p. 1
template <class U> default_delete(const default_delete<U>& other) noexcept;
After p. 3
void operator()(T *ptr) const noexcept(noexcept(ptr->~T()));

20.9.10.1.3 default_delete<T[]>

Before p. 1
namespace std {
  template <class T> struct default_delete<T[]> {
    constexpr default_delete() noexcept;
    void operator()(T* ptr) const noexcept(noexcept(ptr->~T()));
    template  void operator()(U*) const = delete;
  };
}
void operator()(T* ptr) const noexcept(noexcept(ptr->~T()));

20.9.10.2 unique_ptr for single objects

Before p. 1
namespace std {
  template <class T, class D = default_delete<T>> class unique_ptr {
  public:
...
    // observers
    typename add_lvalue_reference<T>::type operator*() const noexcept;
...
  };
}

20.9.10.2.4 unique_ptr observers

Before p. 1
typename add_lvalue_reference<T>::type operator*() const noexcept;

20.9.10.3 unique_ptr for array objects with a runtime length

Before p. 1
namespace std {
  template <class T, class D> class unique_ptr<T[], D> {
  public:
...
    T& operator[](size_t i) const noexcept;
...
  };
}

20.9.10.3.2 unique_ptr observers

Before p. 1
T& operator[](size_t i) const noexcept;

20.9.10.4 unique_ptr specialized algorithms

Before p. 1
template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
After p. 1
template <class T1, class D1, class T2, class D2>
  bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
    noexcept(declval<const unique_ptr<T1, D1>::pointer&>() == declval<const unique_ptr<T2, D2>::pointer&>());
After p. 2
template <class T1, class D1, class T2, class D2>
  bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
    noexcept(declval<const unique_ptr<T1, D1>::pointer&>() != declval<const unique_ptr<T2, D2>::pointer&>());
After p. 3
template <class T1, class D1, class T2, class D2>
  bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
    noexcept(declval<const unique_ptr<T1, D1>::pointer&>() < declval<const unique_ptr<T2, D2>::pointer&>());
After p. 4
template <class T1, class D1, class T2, class D2>
  bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
    noexcept(declval<const unique_ptr<T1, D1>::pointer&>() <= declval<const unique_ptr<T2, D2>::pointer&>());
After p. 5
template <class T1, class D1, class T2, class D2>
  bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
    noexcept(declval<const unique_ptr<T1, D1>::pointer&>() > declval<const unique_ptr<T2, D2>::pointer&>());
After p. 6
template <class T1, class D1, class T2, class D2>
  bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
    noexcept(declval<const unique_ptr<T1, D1>::pointer&>() >= declval<const unique_ptr<T2, D2>::pointer&>());

20.9.11.2 Class template shared_ptr

After p. 1
namespace std {
  template<class T> class shared_ptr {
  public:
...
    // 20.9.11.2.3, assignment:
    shared_ptr& operator=(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    shared_ptr& operator=(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
...
    void reset() noexcept;
...
  };
...
}

20.9.11.2.3 shared_ptr assignment

Before p. 1
shared_ptr& operator=(const shared_ptr& r) noexcept;
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
After p. 3
shared_ptr& operator=(shared_ptr&& r) noexcept;
template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;

20.9.11.2.4 shared_ptr modifiers

After p. 2
void reset() noexcept;

20.9.11.3 Class template weak_ptr

After p. 1
namespace std {
  template<class T> class weak_ptr {
  public:
...
    void reset() noexcept;
...
  };
}

20.9.11.3.4 weak_ptr modifiers

After p. 2
void reset() noexcept;

20.9.11.5 shared_ptr atomic access

After p. 5
template<class T>
  shared_ptr<T> atomic_load(const shared_ptr<T>* p) noexcept;
After p. 11
template<class T>
  void atomic_store(shared_ptr<T>* p, shared_ptr<T> r) noexcept;
After p. 17
template<class T>
shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r) noexcept;
After p. 23
template<class T>
  bool atomic_compare_exchange_weak(
    shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w) noexcept;
After p. 25
template<class T>
  bool atomic_compare_exchange_strong(
    shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w) noexcept;

20.9.13 Align

Before p. 1
void *align(std::size_t alignment, std::size_t size,
  void *&ptr, std::size_t& space) noexcept;

20.10 Class scoped_allocator

Modify p. 1
// scoped allocator adaptor
template <class OuterAlloc, class... InnerAlloc>
  class scoped_allocator_adaptor;
template <class OuterA1, class OuterA2, class... InnerAllocs>
  bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,)
		  const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
template <class OuterA1, class OuterA2, class... InnerAllocs>
  bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,)
		  const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
After p. 2
namespace std {
  template <class OuterAlloc, class... InnerAllocs>
    class scoped_allocator_adaptor : public OuterAlloc {
...
    scoped_allocator_adaptor() noexcept;
    template <class OuterA2>}
      scoped_allocator_adaptor(OuterA2&& outerAlloc,
                               const InnerAllocs&... innerAllocs) noexcept;
    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
    template <class OuterA2>
      scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
    template <class OuterA2>
      scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
...
    inner_allocator_type& inner_allocator() noexcept;
    const inner_allocator_type& inner_allocator() const noexcept;
    outer_allocator_type& outer_allocator() noexcept;
    const outer_allocator_type& outer_allocator() const noexcept;
...
    void deallocate(pointer p, size_type n) noexcept;
...
    template <class T, class... Args>
      void construct(T* p, Args&& args) noexcept(see below);
    template <class T1, class T2, class... Args1, class... Args2>
      void construct(pair<T1, T2>* p, piecewise_construct t,
                     tuple<Args1...> x, tuple<Args2...> y) noexcept(see below);
    template <class T1, class T2>
      void construct(pair<T1, T2>* p) noexcept(see below);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, U&& x, V&& y) noexcept(see below);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, const pair<U, V>& x) noexcept(see below);
    template <class T1, class T2, class U, class V>
      void construct(pair<T1, T2>* p, pair<U, V>&& x) noexcept(see below);

    template <class T>
      void destroy(T* p) noexcept(noexcept(p->~T()));

  };
template <class OuterA1, class OuterA2, class... InnerAllocs>
  bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                  const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
template <class OuterA1, class OuterA2, class... InnerAllocs>
  bool operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
                  const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
}

20.10.2 Scoped allocator adaptor constructors

Before p. 1
scoped_allocator_adaptor() noexcept;
After p. 1
template <class OuterA2>
  scoped_allocator_adaptor(OuterA2&& outerAlloc,
                           const InnerAllocs&... innerAllocs) noexcept;
After p. 3
scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
After p. 4
template <class OuterA2>
  scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2,
			   InnerAllocs...>& other) noexcept;
After p. 6
template <class OuterA2>
  scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2,
			   InnerAllocs...>&& other) noexcept;

20.10.3 Scoped allocator adaptor members

After p. 1
inner_allocator_type& inner_allocator() noexcept;
const inner_allocator_type& inner_allocator() const noexcept;
After p. 2
outer_allocator_type& outer_allocator() noexcept;
After p. 3
const outer_allocator_type& outer_allocator() const noexcept;
After p. 6
void deallocate(pointer p, size_type n) noexcept;
After p. 8
template <class T, class... Args>
  void construct(T* p, Args&&... args) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to one of the following:

        is_nothrow_constructible<T,Args&&...>:value
        is_nothrow_constructible<T,allocator_arg_t, inner_allocator_type, Args&&...>:value
        is_nothrow_constructible<T, Args&&..., inner_allocator_type>:value
After p. 9
template <class T1, class T2, class... Args1, class... Args2>
  void construct(pair* p,piecewise_construct_t,
		 tuple x, tuple y) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to one of the following:

        is_nothrow_constructible<T1, Args1...>:value
        is_nothrow_constructible<T1, allocator_arg_t, inner_allocator_type, Args1...>:value &&
        noexcept(tuple_cat(tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator_type()), x)
        is_nothrow_constructible<T1, Args1..., inner_allocator_type>:value &&
        noexcept(tuple_cat(x, tuple<inner_allocator_type&>(inner_allocator_type()))

and one of the following:

        is_nothrow_constructible<T2, Args2...>:value
        is_nothrow_constructible<T2, allocator_arg_t, inner_allocator_type, Args2...>:value &&
        noexcept(tuple_cat(tuple<allocator_arg_t, inner_allocator_type&>(allocator_arg, inner_allocator_type()), y)
        is_nothrow_constructible<T2, Args2..., inner_allocator_type>:value &&
        noexcept(tuple_cat(y, tuple<inner_allocator_type&>(inner_allocator_type()))
After p. 11
template <class T1, class T2>
  void construct(pair<T1, T2>* p) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1>::value &&
  is_nothrow_constructible<T2>::value
After p. 12
template <class T1, class T2, class U, class V>
  void construct(pair<T1, T2>* p, U&& x, V&& y) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, U&&>::value &&
  is_nothrow_constructible<T2, V&&>::value
After p. 13
template <class T1, class T2, class U, class V>
  void construct(pair<T1, T2>* p, const pair<U, V>& x) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, const U&>::value &&
  is_nothrow_constructible<T2, const V&>::value
After p. 14
template <class T1, class T2, class U, class V>
  void construct(pair<T1, T2>* p, pair<U, V>&& x) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<T1, U&&>::value &&
  is_nothrow_constructible<T2, V&&>::value
After p. 15
template <class T>
  void destroy(T* p) noexcept(noexcept(p->~T()));

20.11.2.2 duration_values

Before p. 1
template <class Rep>
struct duration_values {
public:
  static constexpr Rep zero() noexcept(seee below);;
  static constexpr Rep min() noexcept(seee below);;
  static constexpr Rep max() noexcept(seee below);;
};
After p. 1
static constexpr Rep zero() noexcept(seee below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(Rep(0)) &&
  is_nothrow_constructible<Rep, const Rep&>::value
After p. 3
static constexpr Rep min() noexcept(seee below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(numeric_limits<Rep>::lowest()) &&
  is_nothrow_constructible<Rep, const Rep&>::value
After p. 5
static constexpr Rep max() noexcept(seee below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(numeric_limits<Rep>::max()) &&
  is_nothrow_constructible<Rep, const Rep&>::value

20.11.3.1 duration constructors

Before p. 1
template <class Rep2>
  constexpr explicit duration(const Rep2& r) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<Rep, const Rep2&>::value
After p. 3
template <class Rep2, class Period2>
  constexpr duration(const duration<Rep2, Period2>& d)  noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<Rep, const Rep2&>::value &&
  noexcept(duration_cast<duration>(d))

20.11.3.2 duration observer

Before p. 1
constexpr rep count() const noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<Rep, const Rep&>::value

20.11.3.3 duration arithmetic

Before p. 1
constexpr duration operator+() const noexcept;
After p. 1
constexpr duration operator-() const noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(-rep_) &&
  is_nothrow_constructible<Rep, const Rep&>::value
After p. 2
duration& operator++() noexcept(noexcept(++rep_));
After p. 4
duration operator++(int) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(rep_++) &&
  is_nothrow_constructible<Rep, const Rep&>::value
After p. 5
duration& operator--() noexcept(noexcept(--rep_));
After p. 7
duration operator--(int) noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(rep_--) &&
  is_nothrow_constructible<Rep, const Rep&>::value
After p. 8
duration& operator+=(const duration& d)noexcept(noexcept(rep_+=d.count()));
After p. 10
duration& operator-=(const duration& d)noexcept(noexcept(rep_-=d.count()));
After p. 12
duration& operator*=(const rep& rhs)noexcept(noexcept(rep_*=rhs));
After p. 14
duration& operator/=(const rep& rhs)noexcept(noexcept(rep_/=rhs));
After p. 16
duration& operator%=(const rep& rhs)noexcept(noexcept(rep_%=rhs));
After p. 18
duration& operator%=(const duration& d)noexcept(noexcept(rep_%=d.count()));

20.11.3.4 duration special values

Before p. 1
static constexpr duration zero() noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(duration_values<rep>::zero()) &&
  is_nothrow_constructible<duration, const Rep&>::value
After p. 1
static constexpr duration min() noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(duration_values<rep>::min()) &&
  is_nothrow_constructible<duration, const Rep&>::value
After p. 2
static constexpr duration max() noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(duration_values<rep>::max()) &&
  is_nothrow_constructible<duration, const Rep&>::value

20.11.3.5 duration non-member arithmetic

After p. 1
template <class Rep1, class Period1, class Rep2, class Period2>
  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>{>}::type
  operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CD,decltype(lhs)>::value &&
  noexcept(declval<CD&>()+=rhs) &&
  is_nothrow_constructible<CD,const CD&>::value
template <class Rep1, class Period1, class Rep2, class Period2>
  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>{>}::type
  operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CD,lhs>::value &&
  noexcept(declval<CD&>()-=rhs) &&
  is_nothrow_constructible<CD,const CD&>::value
template <class Rep1, class Period, class Rep2>
  duration<typename common_type<Rep1, Rep2>::type, Period>
  operator*(const duration<Rep1, Period>& d, const Rep2& s)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CD,d>::value &&
  noexcept(declval<CD&>() *= s) &&
  std::ins_nothrow_constructible<CD,const CD&>::value
template <class Rep1, class Period, class Rep2>
  duration<typename common_type<Rep1, Rep2>::type, Period>
  operator*(const Rep1& s, const duration<Rep2, Period>& d)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  std:is_nothrow_constructible<Rep1,CR(Rep1,Rep2);>::value &&
  noexcept(d * s) &&
  is_nothrow_constructible<CD,CR(Rep1,Rep2),Period>::value
template <class Rep1, class Period, class Rep2>
  duration<typename common_type<Rep1, Rep2>::type, Period>
  operator/(const duration<Rep1, Period>& d, const Rep2& s)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  std:is_nothrow_constructible<CD,decltype(d)>::value &&
  noexcept(declval<CD&>() /= s) &&
  is_nothrow_constructible<CD,const CD&>::value
template <class Rep1, class Period1, class Rep2, class Period2>
  typename common_type<Rep1, Rep2>::type
  operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(declval<CD>()/declval<CD>()) &&
  is_nothrow_constructible<CD,const CD&>::value
template <class Rep1, class Period, class Rep2>
  duration<typename common_type<Rep1, Rep2>::type, Period>
  operator%(const duration<Rep1, Period>& d, const Rep2& s)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CD,decltype(d);>::value &&
  noexcept(declval<CD&>() %= s) &&
  is_nothrow_constructible<CD,const CD&>::value
template <class Rep1, class Period1, class Rep2, class Period2>
  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
  operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CD,decltype(lhs)>::value &&
  noexcept(declval<CD&>() %= rhs) &&
  is_nothrow_constructible<CD,const CD&>::value

20.11.3.6 duration comparisons

After p. 1
template <class Rep1, class Period1, class Rep2, class Period2>
  bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CT,decltype(lhs)>::value &&
  is_nothrow_constructible<CT, decltype(rhs)>::value &&
  noexcept(declval<const CT&>().count()) &&
  noexcept(declval<const CT::Rep&>() == declval<const CT::Rep&>())
template <class Rep1, class Period1, class Rep2, class Period2>
  bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(noexcept(lhs==rhs));
template <class Rep1, class Period1, class Rep2, class Period2>
  bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CT,decltype(lhs)>::value &&
  is_nothrow_constructible<CT, decltype(rhs)>::value &&
  noexcept(declval<const CT&>().count()) &&
  noexcept(declval<const CT::Rep&>() < declval<const CT::Rep&>())
template <class Rep1, class Period1, class Rep2, class Period2>
  bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(noexcept(rhs < lhs));
template <class Rep1, class Period1, class Rep2, class Period2>
  bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(noexcept(rhs < lhs));
template <class Rep1, class Period1, class Rep2, class Period2>
  bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(noexcept(lhs < rhs));

20.11.3.7 duration_cast

Before p. 1
template <class ToDuration, class Rep, class Period>
  ToDuration duration_cast(const duration<Rep, Period>& d)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

20.11.4.1 time_point constructors

Before p. 1
time_point()
  noexcept(noexcep(duration::zero()) && 
           noexcept(is_nothrow_constructible<duration, duration&&>::value));
After p. 1
time_point(const duration& d)
  noexcept(is_nothrow_constructible<duration, duration&&>::value));
After p. 2
template <class Duration2>
  time_point(const time_point<clock, Duration2>& t)
    noexcept(noexcept(t.time_since_epoch()));

20.11.4.2 time_point observer

Before p. 1
duration time_since_epoch() const
  noexcept(see below);

1 Remarks: true unless any of the following expression is met:

20.11.4.3 time_point arithmetic

Before p. 1
time_point& operator+=(const duration& d) noexcept(noexcept(d_ += d));
After p. 2
time_point& operator-=(const duration& d) noexcept(noexcept(d_ -= d));

20.11.4.4 time_point special values

Before p. 1
static constexpr time_point min() noexcept(see below);

1 Remarks: true unless any of the following expression is met:

Before p. 2
static constexpr time_point max() noexcept(see below);

2 Remarks: true unless any of the following expression is met:

20.11.4.5 time_point non-member arithmetic

template <class Clock, class Duration1, class Rep2, class Period2>
  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
  operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  is_nothrow_constructible<CT,decltype(lhs)>::value &&
  noexcept(declval<const CT&>() += rhs) &&
  is_nothrow_constructible<CT,CT&&>::value

where CT is the type fo the return value.

template <class Rep1, class Period1, class Clock, class Duration2>
  time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
  operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(rhs + lhs) &&
  is_nothrow_constructible<CT,CT&&>::value

where CT is the type fo the return value.

template <class Clock, class Duration1, class Rep2, class Period2>
  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
  operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(-rhs) &&
  noexcept(lhs + rhs) &&
  is_nothrow_constructible<CT,CT&&>::value

where CT is the type fo the return value.

template <class Clock, class Duration1, class Duration2>
  typename common_type<Duration1, Duration2>::type
  operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(lhs.time_since_epoch()) &&
  noexcept(rhs.time_since_epoch()) &&
  noexcept(declval<const Duration1&>() - declval<const Duration2&>()) &&
  is_nothrow_constructible<CT,CT&&>::value

where CT is the type fo the return value.

20.11.4.6 time_point comparisons

Before p. 1
template <class Clock, class Duration1, class Duration2>
  bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(noexcept(lhs.time_since_epoch()) &&
             noexcept(rhs.time_since_epoch()) &&
             noexcept(declval<const Duration1&>() == declval<const Duration2&>());
After p. 1
template <class Clock, class Duration1, class Duration2>
  bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(noexcept(lhs == rhs));
After p. 2
template <class Clock, class Duration1, class Duration2>
  bool operator<(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(noexcept(lhs.time_since_epoch()) &&
             noexcept(rhs.time_since_epoch()) &&
             noexcept(declval<const Duration1&>() < declval<const Duration2&>());
After p. 3
template <class Clock, class Duration1, class Duration2>
  bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(noexcept(rhs < lhs));
After p. 4
template <class Clock, class Duration1, class Duration2>
  bool operator>(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(noexcept(rhs < lhs));
After p. 5
template <class Clock, class Duration1, class Duration2>
  bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs)
    noexcept(noexcept(lhs < rhs));

20.11.4.7 time_point_cast

Before p. 1
template <class ToDuration, class Clock, class Duration>
  time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t)
    noexcept(see below);

Remarks: The expression inside noexcept is equivalent to:

  noexcept(t.time_since_epoch()) &&
  noexcept(duration_cast<ToDuration>(declval<const Duration&>())) &&
  is_nothrow_constructible<time_point<Clock,ToDuration>,ToDuration>::value &&
  is_nothrow_constructible<time_point<Clock,ToDuration>,time_point<Clock,ToDuration>&&>::value

20.13.3 type_index members

Before p. 1
type_index(const type_info& rhs) noexcept;
After p. 1
bool operator==(const type_index& rhs) const noexcept;
After p. 2
bool operator!=(const type_index& rhs) const noexcept;
After p. 3
bool operator<(const type_index& rhs) const noexcept;
After p. 4
bool operator<=(const type_index& rhs) const noexcept;
After p. 5
bool operator>(const type_index& rhs) const noexcept;
After p. 6
bool operator>=(const type_index& rhs) const noexcept;