exchange() utility function, revision 2Revises N3511 by adding a default template argument.
Atomic objects provide an atomic_exchange function
    ([atomics.types.operations.req]p18) that assigns a new value to the object
    and returns the old value.  This operation is also useful on non-atomic
    objects, and this paper proposes adding it to the library.  The benefit
    isn't huge, but neither is the specification cost.
template<typename T, typename U=T>
T exchange(T& obj, U&& new_val) {
  T old_val = std::move(obj);
  obj = std::forward<U>(new_val);
  return old_val;
}
For primitive types, this is equivalent to the obvious implementation, while for more complex types, this definition
I chose the name for symmetry with atomic_exchange, since
    they behave the same except for this function not being atomic.
We could consider defaulting new_val to T{},
    which makes null'ing out a pointer even simpler, but I think that makes the
    name less good, so I'm not proposing it.
c++std-ext-13750 mentions a use case for post-increment on
    bool, which this function would replace.  This proposal comes
    from my message c++std-lib-33183 on that thread.
auto operator << (std::ostream& os, section_num const & sn) -> std::ostream & {
   if (!sn.prefix.empty()) { os << sn.prefix << " "; }
   bool use_period{false};
   for (auto sub : sn.num ) {
      if(use_period++) {  // <-- deprecated check to omit some code on the first time through the loop
         os << '.';
      }
      if (sub >= 100) {
         os << char(sub - 100 + 'A');
      }
      else {
         os << sub;
      }
   }
   return os;
}becomes:
auto operator << (std::ostream& os, section_num const & sn) -> std::ostream & {
   if (!sn.prefix.empty()) { os << sn.prefix << " "; }
   bool use_period{false};
   for (auto sub : sn.num ) {
      if(std::exchange(use_period, true)) {
         os << '.';
      }
      if (sub >= 100) {
         os << char(sub - 100 + 'A');
      }
      else {
         os << sub;
      }
   }
   return os;
}Implementations of std::unique_ptr can also benefit:
template<typename T, typename D>
void unique_ptr<T, D>::reset(pointer p = pointer()) {
  pointer old = ptr_;
  ptr_ = p;
  if (old)
    deleter_(old);
}becomes:
template<typename T, typename D>
void unique_ptr<T, D>::reset(pointer p = pointer()) {
  if (pointer old = std::exchange(ptr_, p))
    deleter_(old);
}Giving the second template argument a default value fixes the following two cases:
DefaultConstructible x = ...;
if (exchange(x, {})) { ... }int (*fp)(int);
int f(int);
double f(double);
/*...*/ exchange(fp, &f) /*...*/Wording is relative to N3485.
// [utility.exchange] exchange:
template <class T, class U=T> T exchange(T& obj, U&& new_val);template <class T, class U=T> T exchange(T& obj, U&& new_val);Effects: Equivalent to:
T old_val = move(obj);
obj = forward<U>(new_val);
return old_val;