| Index: src/plugin/Placeholder.h |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/src/plugin/Placeholder.h |
| @@ -0,0 +1,78 @@ |
| +/* |
| + * This file is part of Adblock Plus <https://adblockplus.org/>, |
| + * Copyright (C) 2006-2015 Eyeo GmbH |
| + * |
| + * Adblock Plus is free software: you can redistribute it and/or modify |
| + * it under the terms of the GNU General Public License version 3 as |
| + * published by the Free Software Foundation. |
| + * |
| + * Adblock Plus is distributed in the hope that it will be useful, |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + * GNU General Public License for more details. |
| + * |
| + * You should have received a copy of the GNU General Public License |
| + * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| + */ |
| + |
| +/** |
| + * Allows construction of an object in one block and usage in another. |
| + * |
| + * Splitting construction and usage is not necessary in all cases, |
| + * but there are many when it is. |
| + * In any relevant case it's necessary to define something in a context that contains both blocks. |
| + * One is when the class is not default-constructible. |
| + * You might be able to construct an initial value if you know the class, |
| + * but that's not the case in general for templates. |
| + * Another is when there's no copy assignment available, |
| + * such as std::unique_ptr. |
| + * |
| + * A 'Placeholder' can be initialized with either a copy or move constructor. |
| + * We can't use assignment to initialize, because (in general) assignment assumes |
| + * that the lvalue target is already initialized. |
| + */ |
| +template<class T> |
| +class Placeholder |
| +{ |
| + /** |
| + * We 'allocate' memory for the object in the instance itself; |
| + * there's no use of the heap. |
| + * |
| + * Note that it's a normative standard that sizeof(char)==1 |
| + */ |
| + char storage[sizeof(T)]; |
| + |
| +public: |
| + /** |
| + * Initialize by copying a glvalue into our private storage. |
| + */ |
| + void Construct(const T& x) |
| + { |
| + /* |
| + * We use placement-new syntax to use our private storage. |
| + * The constructor expression invokes the copy constructor. |
| + */ |
| + new (&storage[0]) T(x); |
| + } |
| + |
| + /** |
| + * Initialize by moving an rvalue into our private storage. |
| + */ |
| + void Construct(T&& x) |
| + { |
| + /* |
| + * We use placement-new syntax to use our private storage. |
| + * We explicitly cast to an rvalue to ensure use of the move constructor. |
| + */ |
| + new (&storage[0]) T(std::move(x)); |
| + } |
| + |
| + /** |
| + * Access the object in storage. |
| + */ |
| + T& Object() |
| + { |
| + return *reinterpret_cast<T *>(&storage[0]); |
| + } |
| +}; |
| + |