mirror of
https://github.com/zebrajr/pytorch.git
synced 2025-12-07 12:21:27 +01:00
… all instances of std::result_of and std:result_of_t are conditionally replaced by std::invoke_result and std::invoke_result_t if __cpp_lib_is_invocable >= 201703L. std::invoke_result was only introduced in c++17, so it should probably not be required yet. Fixes #71657 and a small part of #69290 Tested on Centos 7 / gcc11 + a private project that requires cpp20. I think the main questions to check by a maintainer are, - whether my choices of preprocessor blocks are appropriate - whether there are any very subtle differences between std::result_of and std::invoke_result that I have missed - whether in any of the replacements the 'new' side can/should be simplified further Pull Request resolved: https://github.com/pytorch/pytorch/pull/79985 Approved by: https://github.com/ezyang
64 lines
1.9 KiB
C++
64 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <mutex>
|
|
|
|
#include <c10/util/C++17.h>
|
|
|
|
namespace c10 {
|
|
|
|
/**
|
|
* A very simple Synchronization class for error-free use of data
|
|
* in a multi-threaded context. See folly/docs/Synchronized.md for
|
|
* the inspiration of this class.
|
|
*
|
|
* Full URL:
|
|
* https://github.com/facebook/folly/blob/main/folly/docs/Synchronized.md
|
|
*
|
|
* This class implements a small subset of the generic functionality
|
|
* implemented by folly:Synchronized<T>. Specifically, only withLock<T>
|
|
* is implemeted here since it's the smallest possible API that is
|
|
* able to cover a large surface area of functionality offered by
|
|
* folly::Synchronized<T>.
|
|
*/
|
|
template <typename T>
|
|
class Synchronized final {
|
|
mutable std::mutex mutex_;
|
|
T data_;
|
|
|
|
public:
|
|
Synchronized() = default;
|
|
Synchronized(T const& data) : data_(data) {}
|
|
Synchronized(T&& data) : data_(data) {}
|
|
|
|
// Don't permit copy construction, move, assignment, or
|
|
// move assignment, since the underlying std::mutex
|
|
// isn't necessarily copyable/moveable.
|
|
Synchronized(Synchronized const&) = delete;
|
|
Synchronized(Synchronized&&) = delete;
|
|
Synchronized operator=(Synchronized const&) = delete;
|
|
Synchronized operator=(Synchronized&&) = delete;
|
|
|
|
/**
|
|
* To use, call withLock<T> with a callback that accepts T either
|
|
* by copy or by reference. Use the protected variable in the
|
|
* provided callback safely.
|
|
*/
|
|
template <typename CB>
|
|
typename c10::invoke_result_t<CB, T&> withLock(CB cb) {
|
|
std::lock_guard<std::mutex> guard(this->mutex_);
|
|
return cb(this->data_);
|
|
}
|
|
|
|
/**
|
|
* To use, call withLock<T> with a callback that accepts T either
|
|
* by copy or by const reference. Use the protected variable in
|
|
* the provided callback safely.
|
|
*/
|
|
template <typename CB>
|
|
typename c10::invoke_result_t<CB, T const&> withLock(CB cb) const {
|
|
std::lock_guard<std::mutex> guard(this->mutex_);
|
|
return cb(this->data_);
|
|
}
|
|
};
|
|
} // end namespace c10
|