/* * Copyright 2018 Google LLC * * 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. */ #ifndef FCP_BASE_MOVE_TO_LAMBDA_H_ #define FCP_BASE_MOVE_TO_LAMBDA_H_ #include namespace fcp { /** * Copyable wrapper for a move-only value. See MoveToLambda. * The value is accessible with the * and -> operators. * * You must be careful to avoid accidnetal copies of this type. Copies are * destructive (by design), so accidental copies might lead to using a */ template class MoveToLambdaWrapper { public: explicit MoveToLambdaWrapper(T t) : value_(std::move(t)) {} // The copy and move constructors are intentionally non-const. MoveToLambdaWrapper(MoveToLambdaWrapper const& other) : value_(std::move(other.value_)) {} MoveToLambdaWrapper& operator=(MoveToLambdaWrapper const& other) { value_ = std::move(other.value_); return *this; } // We respect const-ness of the wrapper when dereferencing, so that 'mutable' // is required on the lambda depending on usage of the value; changes // to a captured value persist across calls to the lambda, which is rarely // desired. T const& operator*() const & { return value_; } T const* operator->() const & { return &value_; } T& operator*() & { return value_; } T* operator->() & { return &value_; } private: mutable T value_; }; /** * Allows capturing a value into a lambda 'by move', before C++14. This is * implemented by a copyable wrapper, which actually moves its value. * * auto moving = MoveToLambda(value); * DoSometing([moving]{ V const& v = *moving; ... }); */ template MoveToLambdaWrapper> MoveToLambda(T&& value) { static_assert( std::is_rvalue_reference::value, "Expected an rvalue: If the value is copied anyway (to this function), " "you might as well put it in the lambda-capture list directly."); return MoveToLambdaWrapper>( std::forward(value)); } } // namespace fcp #endif // FCP_BASE_MOVE_TO_LAMBDA_H_