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.
This can be dangerous as it refers to a temporary, and GCC 9.0 warns about
its use. Instead add std::initializer_list overloads to common places it
was used in an initializer_list sense.
* Update MSVC arguments
* Fix json allocator
* Fix simulation diamond
* Bump gtest
* Remove empty varargs in unit tests
* Replace test case with test suite
* Remove deprecation warning in optional
* Remove need for NOMIXMAX to be defined in wpilib headers
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 allows the called function to pass along the promise to another
asynchronous callback.
To avoid memory allocations, add a home-rolled, simplified, non-allocating
version of std::promise and std::future as wpi::promise and wpi::future.
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.