33 Thread support library [thread]
namespace std {
  template <class Mutex>
  class shared_lock {
  public:
    using mutex_type = Mutex;
        shared_lock() noexcept;
    explicit shared_lock(mutex_type& m);      shared_lock(mutex_type& m, defer_lock_t) noexcept;
    shared_lock(mutex_type& m, try_to_lock_t);
    shared_lock(mutex_type& m, adopt_lock_t);
    template <class Clock, class Duration>
      shared_lock(mutex_type& m,
                  const chrono::time_point<Clock, Duration>& abs_time);
    template <class Rep, class Period>
      shared_lock(mutex_type& m,
                const chrono::duration<Rep, Period>& rel_time);
    ~shared_lock();
    shared_lock(const shared_lock&) = delete;
    shared_lock& operator=(const shared_lock&) = delete;
    shared_lock(shared_lock&& u) noexcept;
    shared_lock& operator=(shared_lock&& u) noexcept;
        void lock();      bool try_lock();
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();
        void swap(shared_lock& u) noexcept;
    mutex_type* release() noexcept;
        bool owns_lock() const noexcept;
    explicit operator bool () const noexcept;
    mutex_type* mutex() const noexcept;
  private:
    mutex_type* pm;     bool owns;        };
  template<class Mutex> shared_lock(shared_lock<Mutex>) -> shared_lock<Mutex>;
  template <class Mutex>
    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}An object of type 
shared_lock controls the shared ownership of a
lockable object within a scope
.  Shared ownership of the lockable object may be
acquired at construction or after construction, and may be transferred, after
acquisition, to another 
shared_lock object
.  Objects of type
shared_lock are not copyable but are movable
.  The behavior of a program
is undefined if the contained pointer 
pm is not null and the lockable
object pointed to by 
pm does not exist for the entire remaining
lifetime (
[basic.life]) of the 
shared_lock object
.  Effects: Constructs an object of type 
shared_lock. Postconditions: pm == nullptr and 
owns == false. explicit shared_lock(mutex_type& m);
Requires: The calling thread does not own the mutex for any ownership mode
. Effects: Constructs an object of type 
shared_lock and calls 
m.lock_shared(). Postconditions: pm == addressof(m) and 
owns == true. shared_lock(mutex_type& m, defer_lock_t) noexcept;
Effects: Constructs an object of type 
shared_lock. Postconditions: pm == addressof(m) and 
owns == false. shared_lock(mutex_type& m, try_to_lock_t);
Requires: The calling thread does not own the mutex for any ownership mode
. Effects: Constructs an object of type 
shared_lock and calls 
m.try_lock_shared(). Postconditions: pm == addressof(m) and 
owns == res
where 
res is the
value returned by the call to 
m.try_lock_shared(). shared_lock(mutex_type& m, adopt_lock_t);
Requires: The calling thread has shared ownership of the mutex
. Effects: Constructs an object of type 
shared_lock. Postconditions: pm == addressof(m) and 
owns == true. template <class Clock, class Duration>
  shared_lock(mutex_type& m,
              const chrono::time_point<Clock, Duration>& abs_time);
Requires: The calling thread does not own the mutex for any ownership mode
. Effects: Constructs an object of type 
shared_lock and calls
m.try_lock_shared_until(abs_time). Postconditions: pm == addressof(m) and 
owns == res
where 
res
is the value returned by the call to 
m.try_lock_shared_until(abs_time). template <class Rep, class Period>
  shared_lock(mutex_type& m,
              const chrono::duration<Rep, Period>& rel_time);
Requires: The calling thread does not own the mutex for any ownership mode
. Effects: Constructs an object of type 
shared_lock and calls
m.try_lock_shared_for(rel_time). Postconditions: pm == addressof(m) and 
owns == res
where 
res is
the value returned by the call to 
m.try_lock_shared_for(rel_time). Effects: If 
owns calls 
pm->unlock_shared(). shared_lock(shared_lock&& sl) noexcept;
Postconditions: pm == sl_p.pm and 
owns == sl_p.owns (where
sl_p is the state of 
sl just prior to this construction),
sl.pm == nullptr and 
sl.owns == false. shared_lock& operator=(shared_lock&& sl) noexcept;
Effects: If 
owns calls 
pm->unlock_shared(). Postconditions: pm == sl_p.pm and 
owns == sl_p.owns (where
sl_p is the state of 
sl just prior to this assignment),
sl.pm == nullptr and 
sl.owns == false. Effects: As if by 
pm->lock_shared(). Postconditions: owns == true. Throws: Any exception thrown by 
pm->lock_shared().  Error conditions:
operation_not_permitted — if 
pm is 
nullptr. resource_deadlock_would_occur — if on entry 
owns is
true. 
 Effects: As if by 
pm->try_lock_shared(). Returns: The value returned by the call to 
pm->try_lock_shared(). Postconditions: owns == res, where 
res is the value returned by
the call to 
pm->try_lock_shared(). Throws: Any exception thrown by 
pm->try_lock_shared().  Error conditions:
operation_not_permitted — if 
pm is 
nullptr. resource_deadlock_would_occur — if on entry 
owns is
true. 
 template <class Clock, class Duration>
  bool
  try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
Effects: As if by 
pm->try_lock_shared_until(abs_time). Returns: The value returned by the call to
pm->try_lock_shared_until(abs_time). Postconditions: owns == res, where 
res is the value returned by
the call to 
pm->try_lock_shared_until(abs_time). Throws: Any exception thrown by 
pm->try_lock_shared_until(abs_time).  Error conditions:
operation_not_permitted — if 
pm is 
nullptr. resource_deadlock_would_occur — if on entry 
owns is
true. 
 template <class Rep, class Period>
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
Effects: As if by 
pm->try_lock_shared_for(rel_time). Returns: The value returned by the call to 
pm->try_lock_shared_for(rel_time). Postconditions: owns == res, where 
res is the value returned by the call to 
pm->try_lock_shared_for(rel_time). Throws: Any exception thrown by 
pm->try_lock_shared_for(rel_time).  Error conditions:
operation_not_permitted — if 
pm is 
nullptr. resource_deadlock_would_occur — if on entry 
owns is
true. 
 Effects: As if by 
pm->unlock_shared(). Postconditions: owns == false. Error conditions:
operation_not_permitted — if on entry 
owns is
false. 
 void swap(shared_lock& sl) noexcept;
Effects: Swaps the data members of 
*this and 
sl. mutex_type* release() noexcept;
Returns: The previous value of 
pm. Postconditions: pm == nullptr and 
owns == false. template <class Mutex>
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
Effects: As if by 
x.swap(y). bool owns_lock() const noexcept;
explicit operator bool() const noexcept;
mutex_type* mutex() const noexcept;