mirror of https://github.com/grpc/grpc.git
parent
313f36fd06
commit
922260656a
20 changed files with 243 additions and 165 deletions
@ -0,0 +1,71 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
// manually construct a region of memory with some type
|
||||
|
||||
#include <stddef.h> |
||||
#include <new> |
||||
#include <type_traits> |
||||
#include <utility> |
||||
|
||||
namespace grpc_core { |
||||
|
||||
template <typename Type> |
||||
class ManualConstructor { |
||||
public: |
||||
// No constructor or destructor because one of the most useful uses of
|
||||
// this class is as part of a union, and members of a union could not have
|
||||
// constructors or destructors till C++11. And, anyway, the whole point of
|
||||
// this class is to bypass constructor and destructor.
|
||||
|
||||
Type* get() { return reinterpret_cast<Type*>(&space_); } |
||||
const Type* get() const { return reinterpret_cast<const Type*>(&space_); } |
||||
|
||||
Type* operator->() { return get(); } |
||||
const Type* operator->() const { return get(); } |
||||
|
||||
Type& operator*() { return *get(); } |
||||
const Type& operator*() const { return *get(); } |
||||
|
||||
void Init() { new (&space_) Type; } |
||||
|
||||
// Init() constructs the Type instance using the given arguments
|
||||
// (which are forwarded to Type's constructor).
|
||||
//
|
||||
// Note that Init() with no arguments performs default-initialization,
|
||||
// not zero-initialization (i.e it behaves the same as "new Type;", not
|
||||
// "new Type();"), so it will leave non-class types uninitialized.
|
||||
template <typename... Ts> |
||||
void Init(Ts&&... args) { |
||||
new (&space_) Type(std::forward<Ts>(args)...); |
||||
} |
||||
|
||||
// Init() that is equivalent to copy and move construction.
|
||||
// Enables usage like this:
|
||||
// ManualConstructor<std::vector<int>> v;
|
||||
// v.Init({1, 2, 3});
|
||||
void Init(const Type& x) { new (&space_) Type(x); } |
||||
void Init(Type&& x) { new (&space_) Type(std::move(x)); } |
||||
|
||||
void Destroy() { get()->~Type(); } |
||||
|
||||
private: |
||||
typename std::aligned_storage<sizeof(Type), alignof(Type)>::type space_; |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
Loading…
Reference in new issue