This makes code easier to read and more consistent between C++ and Java.
Also update clang-format settings to always add a line break (even if no braces are used).
std::scoped_lock was introduced in C++17 and is strictly better than
std::lock_guard as it supports locking any number of mutexes safely.
It's also easier to use than std::lock for locking multiple mutexes at
once.
Other handles can only be used within the loop itself, but Async is intended
to be used from another thread. This introduces the possibility of a race
condition between the loop being destroyed and the Async being destroyed.
Change Async to keep a weak reference to a loop and check it before performing
libuv operations.
This is a breaking change as it makes Async a template (e.g. Async<> must
be used instead of just Async). When data parameters are provided, an
internal mutex and vector is used to hold the parameter packs until the loop
runs.