namespace std {
class mutex;
class recursive_mutex;
class timed_mutex;
class recursive_timed_mutex;
struct defer_lock_t { explicit defer_lock_t() = default; };
struct try_to_lock_t { explicit try_to_lock_t() = default; };
struct adopt_lock_t { explicit adopt_lock_t() = default; };
inline constexpr defer_lock_t defer_lock { };
inline constexpr try_to_lock_t try_to_lock { };
inline constexpr adopt_lock_t adopt_lock { };
template<class Mutex> class lock_guard;
template<class... MutexTypes> class scoped_lock;
template<class Mutex> class unique_lock;
template<class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
struct once_flag;
template<class Callable, class... Args>
void call_once(once_flag& flag, Callable&& func, Args&&... args);
}
namespace std {
class mutex {
public:
constexpr mutex() noexcept;
~mutex();
mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;
void lock();
bool try_lock();
void unlock();
using native_handle_type = implementation-defined; // see [thread.req.native]
native_handle_type native_handle(); // see [thread.req.native]
};
}
namespace std {
class recursive_mutex {
public:
recursive_mutex();
~recursive_mutex();
recursive_mutex(const recursive_mutex&) = delete;
recursive_mutex& operator=(const recursive_mutex&) = delete;
void lock();
bool try_lock() noexcept;
void unlock();
using native_handle_type = implementation-defined; // see [thread.req.native]
native_handle_type native_handle(); // see [thread.req.native]
};
}
namespace std {
class timed_mutex {
public:
timed_mutex();
~timed_mutex();
timed_mutex(const timed_mutex&) = delete;
timed_mutex& operator=(const timed_mutex&) = delete;
void lock(); // blocking
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();
using native_handle_type = implementation-defined; // see [thread.req.native]
native_handle_type native_handle(); // see [thread.req.native]
};
}
namespace std {
class recursive_timed_mutex {
public:
recursive_timed_mutex();
~recursive_timed_mutex();
recursive_timed_mutex(const recursive_timed_mutex&) = delete;
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
void lock(); // blocking
bool try_lock() noexcept;
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();
using native_handle_type = implementation-defined; // see [thread.req.native]
native_handle_type native_handle(); // see [thread.req.native]
};
}
namespace std {
struct defer_lock_t { }; // do not acquire ownership of the mutex
struct try_to_lock_t { }; // try to acquire ownership of the mutex
// without blocking
struct adopt_lock_t { }; // assume the calling thread has already
// obtained mutex ownership and manage it
inline constexpr defer_lock_t defer_lock { };
inline constexpr try_to_lock_t try_to_lock { };
inline constexpr adopt_lock_t adopt_lock { };
}
namespace std {
template<class Mutex>
class lock_guard {
public:
using mutex_type = Mutex;
explicit lock_guard(mutex_type& m);
lock_guard(mutex_type& m, adopt_lock_t);
~lock_guard();
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
private:
mutex_type& pm; // exposition only
};
}explicit lock_guard(mutex_type& m);
lock_guard(mutex_type& m, adopt_lock_t);
~lock_guard();
namespace std {
template<class... MutexTypes>
class scoped_lock {
public:
using mutex_type = Mutex; // If MutexTypes... consists of the single type Mutex
explicit scoped_lock(MutexTypes&... m);
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
~scoped_lock();
scoped_lock(const scoped_lock&) = delete;
scoped_lock& operator=(const scoped_lock&) = delete;
private:
tuple<MutexTypes&...> pm; // exposition only
};
}explicit scoped_lock(MutexTypes&... m);
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
~scoped_lock();
namespace std {
template<class Mutex>
class unique_lock {
public:
using mutex_type = Mutex;
// [thread.lock.unique.cons], construct/copy/destroy
unique_lock() noexcept;
explicit unique_lock(mutex_type& m);
unique_lock(mutex_type& m, defer_lock_t) noexcept;
unique_lock(mutex_type& m, try_to_lock_t);
unique_lock(mutex_type& m, adopt_lock_t);
template<class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
~unique_lock();
unique_lock(const unique_lock&) = delete;
unique_lock& operator=(const unique_lock&) = delete;
unique_lock(unique_lock&& u) noexcept;
unique_lock& operator=(unique_lock&& u);
// [thread.lock.unique.locking], locking
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();
// [thread.lock.unique.mod], modifiers
void swap(unique_lock& u) noexcept;
mutex_type* release() noexcept;
// [thread.lock.unique.obs], observers
bool owns_lock() const noexcept;
explicit operator bool () const noexcept;
mutex_type* mutex() const noexcept;
private:
mutex_type* pm; // exposition only
bool owns; // exposition only
};
template<class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
}unique_lock() noexcept;
explicit unique_lock(mutex_type& m);
unique_lock(mutex_type& m, defer_lock_t) noexcept;
unique_lock(mutex_type& m, try_to_lock_t);
unique_lock(mutex_type& m, adopt_lock_t);
template<class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
unique_lock(unique_lock&& u) noexcept;
unique_lock& operator=(unique_lock&& u);
~unique_lock();
void lock();
bool try_lock();
template<class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
void unlock();
void swap(unique_lock& u) noexcept;
mutex_type* release() noexcept;
template<class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
namespace std {
struct once_flag {
constexpr once_flag() noexcept;
once_flag(const once_flag&) = delete;
once_flag& operator=(const once_flag&) = delete;
};
}constexpr once_flag() noexcept;
template<class Callable, class... Args>
void call_once(once_flag& flag, Callable&& func, Args&&... args);
INVOKE(std::forward<Callable>(func), std::forward<Args>(args)...)
(see [func.require]) shall be a valid expression.// global flag, regular function void init(); std::once_flag flag; void f() { std::call_once(flag, init); } // function static flag, function object struct initializer { void operator()(); }; void g() { static std::once_flag flag2; std::call_once(flag2, initializer()); } // object flag, member function class information { std::once_flag verified; void verifier(); public: void verify() { std::call_once(verified, &information::verifier, *this); } };— end example