]> git.sesse.net Git - casparcg/blob - dependencies64/cef/include/base/cef_move.h
* Merged html producer and updated to latest CEF version (does not have satisfactory...
[casparcg] / dependencies64 / cef / include / base / cef_move.h
1 // Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2012
2 // Google Inc. All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //    * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //    * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //    * Neither the name of Google Inc. nor the name Chromium Embedded
15 // Framework nor the names of its contributors may be used to endorse
16 // or promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #ifndef CEF_INCLUDE_BASE_CEF_MOVE_H_
32 #define CEF_INCLUDE_BASE_CEF_MOVE_H_
33
34 #if defined(MOVE_ONLY_TYPE_FOR_CPP_03)
35 // Do nothing if the macro in this header has already been defined.
36 // This can happen in cases where Chromium code is used directly by the
37 // client application. When using Chromium code directly always include
38 // the Chromium header first to avoid type conflicts.
39 #elif defined(BUILDING_CEF_SHARED)
40 // When building CEF include the Chromium header directly.
41 #include "base/move.h"
42 #else  // !BUILDING_CEF_SHARED
43 // The following is substantially similar to the Chromium implementation.
44 // If the Chromium implementation diverges the below implementation should be
45 // updated to match.
46
47 // Macro with the boilerplate that makes a type move-only in C++03.
48 //
49 // USAGE
50 //
51 // This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create
52 // a "move-only" type.  Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be
53 // the first line in a class declaration.
54 //
55 // A class using this macro must call .Pass() (or somehow be an r-value already)
56 // before it can be:
57 //
58 //   * Passed as a function argument
59 //   * Used as the right-hand side of an assignment
60 //   * Returned from a function
61 //
62 // Each class will still need to define their own "move constructor" and "move
63 // operator=" to make this useful.  Here's an example of the macro, the move
64 // constructor, and the move operator= from the scoped_ptr class:
65 //
66 //  template <typename T>
67 //  class scoped_ptr {
68 //     MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
69 //   public:
70 //    scoped_ptr(RValue& other) : ptr_(other.release()) { }
71 //    scoped_ptr& operator=(RValue& other) {
72 //      swap(other);
73 //      return *this;
74 //    }
75 //  };
76 //
77 // Note that the constructor must NOT be marked explicit.
78 //
79 // For consistency, the second parameter to the macro should always be RValue
80 // unless you have a strong reason to do otherwise.  It is only exposed as a
81 // macro parameter so that the move constructor and move operator= don't look
82 // like they're using a phantom type.
83 //
84 //
85 // HOW THIS WORKS
86 //
87 // For a thorough explanation of this technique, see:
88 //
89 //   http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor
90 //
91 // The summary is that we take advantage of 2 properties:
92 //
93 //   1) non-const references will not bind to r-values.
94 //   2) C++ can apply one user-defined conversion when initializing a
95 //      variable.
96 //
97 // The first lets us disable the copy constructor and assignment operator
98 // by declaring private version of them with a non-const reference parameter.
99 //
100 // For l-values, direct initialization still fails like in
101 // DISALLOW_COPY_AND_ASSIGN because the copy constructor and assignment
102 // operators are private.
103 //
104 // For r-values, the situation is different. The copy constructor and
105 // assignment operator are not viable due to (1), so we are trying to call
106 // a non-existent constructor and non-existing operator= rather than a private
107 // one.  Since we have not committed an error quite yet, we can provide an
108 // alternate conversion sequence and a constructor.  We add
109 //
110 //   * a private struct named "RValue"
111 //   * a user-defined conversion "operator RValue()"
112 //   * a "move constructor" and "move operator=" that take the RValue& as
113 //     their sole parameter.
114 //
115 // Only r-values will trigger this sequence and execute our "move constructor"
116 // or "move operator=."  L-values will match the private copy constructor and
117 // operator= first giving a "private in this context" error.  This combination
118 // gives us a move-only type.
119 //
120 // For signaling a destructive transfer of data from an l-value, we provide a
121 // method named Pass() which creates an r-value for the current instance
122 // triggering the move constructor or move operator=.
123 //
124 // Other ways to get r-values is to use the result of an expression like a
125 // function call.
126 //
127 // Here's an example with comments explaining what gets triggered where:
128 //
129 //    class Foo {
130 //      MOVE_ONLY_TYPE_FOR_CPP_03(Foo, RValue);
131 //
132 //     public:
133 //       ... API ...
134 //       Foo(RValue other);           // Move constructor.
135 //       Foo& operator=(RValue rhs);  // Move operator=
136 //    };
137 //
138 //    Foo MakeFoo();  // Function that returns a Foo.
139 //
140 //    Foo f;
141 //    Foo f_copy(f);  // ERROR: Foo(Foo&) is private in this context.
142 //    Foo f_assign;
143 //    f_assign = f;   // ERROR: operator=(Foo&) is private in this context.
144 //
145 //
146 //    Foo f(MakeFoo());      // R-value so alternate conversion executed.
147 //    Foo f_copy(f.Pass());  // R-value so alternate conversion executed.
148 //    f = f_copy.Pass();     // R-value so alternate conversion executed.
149 //
150 //
151 // IMPLEMENTATION SUBTLETIES WITH RValue
152 //
153 // The RValue struct is just a container for a pointer back to the original
154 // object. It should only ever be created as a temporary, and no external
155 // class should ever declare it or use it in a parameter.
156 //
157 // It is tempting to want to use the RValue type in function parameters, but
158 // excluding the limited usage here for the move constructor and move
159 // operator=, doing so would mean that the function could take both r-values
160 // and l-values equially which is unexpected.  See COMPARED To Boost.Move for
161 // more details.
162 //
163 // An alternate, and incorrect, implementation of the RValue class used by
164 // Boost.Move makes RValue a fieldless child of the move-only type. RValue&
165 // is then used in place of RValue in the various operators.  The RValue& is
166 // "created" by doing *reinterpret_cast<RValue*>(this).  This has the appeal
167 // of never creating a temporary RValue struct even with optimizations
168 // disabled.  Also, by virtue of inheritance you can treat the RValue
169 // reference as if it were the move-only type itself.  Unfortunately,
170 // using the result of this reinterpret_cast<> is actually undefined behavior
171 // due to C++98 5.2.10.7. In certain compilers (e.g., NaCl) the optimizer
172 // will generate non-working code.
173 //
174 // In optimized builds, both implementations generate the same assembly so we
175 // choose the one that adheres to the standard.
176 //
177 //
178 // WHY HAVE typedef void MoveOnlyTypeForCPP03
179 //
180 // Callback<>/Bind() needs to understand movable-but-not-copyable semantics
181 // to call .Pass() appropriately when it is expected to transfer the value.
182 // The cryptic typedef MoveOnlyTypeForCPP03 is added to make this check
183 // easy and automatic in helper templates for Callback<>/Bind().
184 // See IsMoveOnlyType template and its usage in base/callback_internal.h
185 // for more details.
186 //
187 //
188 // COMPARED TO C++11
189 //
190 // In C++11, you would implement this functionality using an r-value reference
191 // and our .Pass() method would be replaced with a call to std::move().
192 //
193 // This emulation also has a deficiency where it uses up the single
194 // user-defined conversion allowed by C++ during initialization.  This can
195 // cause problems in some API edge cases.  For instance, in scoped_ptr, it is
196 // impossible to make a function "void Foo(scoped_ptr<Parent> p)" accept a
197 // value of type scoped_ptr<Child> even if you add a constructor to
198 // scoped_ptr<> that would make it look like it should work.  C++11 does not
199 // have this deficiency.
200 //
201 //
202 // COMPARED TO Boost.Move
203 //
204 // Our implementation similar to Boost.Move, but we keep the RValue struct
205 // private to the move-only type, and we don't use the reinterpret_cast<> hack.
206 //
207 // In Boost.Move, RValue is the boost::rv<> template.  This type can be used
208 // when writing APIs like:
209 //
210 //   void MyFunc(boost::rv<Foo>& f)
211 //
212 // that can take advantage of rv<> to avoid extra copies of a type.  However you
213 // would still be able to call this version of MyFunc with an l-value:
214 //
215 //   Foo f;
216 //   MyFunc(f);  // Uh oh, we probably just destroyed |f| w/o calling Pass().
217 //
218 // unless someone is very careful to also declare a parallel override like:
219 //
220 //   void MyFunc(const Foo& f)
221 //
222 // that would catch the l-values first.  This was declared unsafe in C++11 and
223 // a C++11 compiler will explicitly fail MyFunc(f).  Unfortunately, we cannot
224 // ensure this in C++03.
225 //
226 // Since we have no need for writing such APIs yet, our implementation keeps
227 // RValue private and uses a .Pass() method to do the conversion instead of
228 // trying to write a version of "std::move()." Writing an API like std::move()
229 // would require the RValue struct to be public.
230 //
231 //
232 // CAVEATS
233 //
234 // If you include a move-only type as a field inside a class that does not
235 // explicitly declare a copy constructor, the containing class's implicit
236 // copy constructor will change from Containing(const Containing&) to
237 // Containing(Containing&).  This can cause some unexpected errors.
238 //
239 //   http://llvm.org/bugs/show_bug.cgi?id=11528
240 //
241 // The workaround is to explicitly declare your copy constructor.
242 //
243 #define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
244  private: \
245   struct rvalue_type { \
246     explicit rvalue_type(type* object) : object(object) {} \
247     type* object; \
248   }; \
249   type(type&); \
250   void operator=(type&); \
251  public: \
252   operator rvalue_type() { return rvalue_type(this); } \
253   type Pass() { return type(rvalue_type(this)); } \
254   typedef void MoveOnlyTypeForCPP03; \
255  private:
256  
257 #endif  // !BUILDING_CEF_SHARED
258
259 #endif  // CEF_INCLUDE_BASE_CEF_MOVE_H_