revise LockCond and its friends to satisfy the concepts of their
counterparts in C++ standard library, so they can used as drop-in
replacements of them.
and use std::mutex, std::condition_variables, std::shared_mutex
if NDEBUG is defined for better performance.
the reason i specialize LockMutex<LockPolicy::MUTEX> to offer the
alias of std::mutex instead inheriting from it as SharedMutex,
is that, std::condition_variable::wait() requires
`std::unique_lock<std::mutex>&`, not
`std::unique_lock<subclass_of_mutex>&` as its parameter.