proxygen
/facebook/proxygen/proxygen/folly/folly/lang/RValueReferenceWrapper.h

Create a folly::rvalue_reference_wrapper. Analogous to std::ref().

Warning: folly::rvalue_reference_wrappers are potentially dangerous, because they can easily be used to capture references to temporary values. Users must ensure that the target object outlives the reference wrapper.

class Object {}; void f(Object&&); // BAD void g() { auto ref = folly::rref(Object{}); // create reference to temporary f(std::move(ref)); // pass dangling reference } // GOOD void h() { Object o; auto ref = folly::rref(std::move(o)); f(std::move(ref)); }

/*
* Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cassert>
#include <memory>
#include <utility>
namespace folly {
template <class T>
class rvalue_reference_wrapper {
public:
using type = T;
: ptr_(std::addressof(ref)) {}
explicit rvalue_reference_wrapper(T&) noexcept = delete;
rvalue_reference_wrapper(rvalue_reference_wrapper<T>&& other) noexcept
: ptr_(other.ptr_) {
other.ptr_ = nullptr;
}
ptr_ = other.ptr_;
other.ptr_ = nullptr;
return *this;
}
/* implicit */ operator T &&() && noexcept {
return static_cast<rvalue_reference_wrapper&&>(*this).get();
}
T&& get() && noexcept {
assert(valid());
T& ref = *ptr_;
ptr_ = nullptr;
return static_cast<T&&>(ref);
}
template <class... Args>
decltype(auto) operator()(Args&&... args) &&
noexcept(noexcept(std::declval<T>()(std::forward<Args>(args)...))) {
return static_cast<rvalue_reference_wrapper&&>(*this).get()(
std::forward<Args>(args)...);
}
bool valid() const noexcept {
return ptr_ != nullptr;
}
private:
// Disallow copy construction and copy assignment, to make it harder to
// accidentally use an rvalue reference multiple times.
T* ptr_;
};
template <typename T>
rvalue_reference_wrapper<T> rref(T&& value) noexcept {
return rvalue_reference_wrapper<T>(std::move(value));
}
template <typename T>
rvalue_reference_wrapper<T> rref(T&) noexcept = delete;
} // namespace folly