From 722ef0f35202ba2451bb9f2fa7ae6faba06f7d4a Mon Sep 17 00:00:00 2001 From: Dave Watson Date: Fri, 25 Oct 2013 12:35:25 -0700 Subject: [PATCH] move MoveWrapper to folly Summary: Add MoveWrapper to folly. @override-unit-failures Test Plan: arc unit Reviewed By: hans@fb.com FB internal diff: D1030005 --- folly/MoveWrapper.h | 71 ++++++++++++++++++++++++++++++++++ folly/test/MoveWrapperTest.cpp | 37 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 folly/MoveWrapper.h create mode 100644 folly/test/MoveWrapperTest.cpp diff --git a/folly/MoveWrapper.h b/folly/MoveWrapper.h new file mode 100644 index 00000000..bbdca228 --- /dev/null +++ b/folly/MoveWrapper.h @@ -0,0 +1,71 @@ +/* + * Copyright 2013 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 + +namespace folly { + +/** C++11 closures don't support move-in capture. Nor does std::bind. + facepalm. + + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3610.html + + "[...] a work-around that should make people's stomach crawl: + write a wrapper that performs move-on-copy, much like the deprecated + auto_ptr" + + Unlike auto_ptr, this doesn't require a heap allocation. + */ +template +class MoveWrapper { + public: + /** If value can be default-constructed, why not? + Then we don't have to move it in */ + MoveWrapper() = default; + + /// Move a value in. + explicit + MoveWrapper(T&& t) : value(std::move(t)) {} + + /// copy is move + MoveWrapper(MoveWrapper& other) : value(std::move(other.value)) {} + + /// move is also move + MoveWrapper(MoveWrapper&& other) : value(std::move(other.value)) {} + + const T& operator*() const { return value; } + T& operator*() { return value; } + + const T* operator->() const { return &value; } + T* operator->() { return &value; } + + // If you want these you're probably doing it wrong, though they'd be + // easy enough to implement + MoveWrapper& operator=(MoveWrapper const&) = delete; + MoveWrapper& operator=(MoveWrapper&&) = delete; + + private: + T value; +}; + +template +MoveWrapper makeMoveWrapper(T&& t) { + return MoveWrapper(std::forward(t)); +} + +} // namespace diff --git a/folly/test/MoveWrapperTest.cpp b/folly/test/MoveWrapperTest.cpp new file mode 100644 index 00000000..4eb4bcba --- /dev/null +++ b/folly/test/MoveWrapperTest.cpp @@ -0,0 +1,37 @@ +/* + * Copyright 2013 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. + */ + +#include + +#include "folly/MoveWrapper.h" +#include + +namespace folly { + +TEST(makeMoveWrapper, Empty) { + // checks for crashes + auto p = makeMoveWrapper(std::unique_ptr()); +} + +TEST(makeMoveWrapper, NonEmpty) { + auto u = std::unique_ptr(new int(5)); + EXPECT_EQ(*u, 5); + auto p = makeMoveWrapper(std::move(u)); + EXPECT_TRUE(!u); + EXPECT_EQ(**p, 5); +} + +} // namespace -- 2.34.1