blob: fe0517eb363105727b4ea6c9d1775359ce5abf23 [file] [log] [blame]
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_MOVE_H_
6#define BASE_MOVE_H_
7
vmpstr63170562015-11-17 08:10:31 +09008#include <utility>
9
bratell5088ec92015-04-15 06:44:34 +090010#include "base/compiler_specific.h"
11
dcheng8e5e0e62015-12-01 21:09:52 +090012// Macro with the boilerplate that makes a type move-only in C++11.
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090013//
14// USAGE
15//
16// This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create
17// a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be
18// the first line in a class declaration.
19//
20// A class using this macro must call .Pass() (or somehow be an r-value already)
21// before it can be:
22//
23// * Passed as a function argument
24// * Used as the right-hand side of an assignment
jhawkins@chromium.orgf8659b72012-03-06 11:13:10 +090025// * Returned from a function
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090026//
dcheng8e5e0e62015-12-01 21:09:52 +090027// Each class will still need to define their own move constructor and move
28// operator= to make this useful. Here's an example of the macro, the move
29// constructor, and the move operator= from a hypothetical scoped_ptr class:
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090030//
31// template <typename T>
32// class scoped_ptr {
dcheng8e5e0e62015-12-01 21:09:52 +090033// MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type);
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090034// public:
dcheng8e5e0e62015-12-01 21:09:52 +090035// scoped_ptr(scoped_ptr&& other) : ptr_(other.release()) { }
36// scoped_ptr& operator=(scoped_ptr&& other) {
37// reset(other.release());
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090038// return *this;
39// }
40// };
41//
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090042//
kinuko@chromium.org288f27a2013-10-22 18:18:20 +090043// WHY HAVE typedef void MoveOnlyTypeForCPP03
44//
45// Callback<>/Bind() needs to understand movable-but-not-copyable semantics
46// to call .Pass() appropriately when it is expected to transfer the value.
47// The cryptic typedef MoveOnlyTypeForCPP03 is added to make this check
48// easy and automatic in helper templates for Callback<>/Bind().
49// See IsMoveOnlyType template and its usage in base/callback_internal.h
50// for more details.
danakj16ca5a82014-10-07 04:34:20 +090051
dcheng8e5e0e62015-12-01 21:09:52 +090052#define MOVE_ONLY_TYPE_FOR_CPP_03(type) \
53 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type)
54
55#define MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
56 private: \
57 type(const type&) = delete; \
58 void operator=(const type&) = delete; \
59 \
60 public: \
vmpstr63170562015-11-17 08:10:31 +090061 type&& Pass() WARN_UNUSED_RESULT { return std::move(*this); } \
dcheng8e5e0e62015-12-01 21:09:52 +090062 typedef void MoveOnlyTypeForCPP03; \
63 \
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090064 private:
65
kkimlabs56bcfba2015-04-14 05:49:43 +090066#define TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
67 public: \
vmpstr63170562015-11-17 08:10:31 +090068 type&& Pass() WARN_UNUSED_RESULT { return std::move(*this); } \
kkimlabs56bcfba2015-04-14 05:49:43 +090069 private:
70
ajwong@chromium.org59f1fbb2012-01-20 09:03:45 +090071#endif // BASE_MOVE_H_