diff --git a/BUILD b/BUILD index 14aeb859b04..e76b7d680cb 100644 --- a/BUILD +++ b/BUILD @@ -709,6 +709,7 @@ grpc_cc_library( public_hdrs = GPR_PUBLIC_HDRS, visibility = ["@grpc:alt_gpr_base_legacy"], deps = [ + "construct_destruct", "debug_location", "google_api_upb", "gpr_codegen", @@ -716,6 +717,12 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "construct_destruct", + language = "c++", + public_hdrs = ["src/core/lib/gprpp/construct_destruct.h"], +) + grpc_cc_library( name = "gpr_codegen", language = "c++", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index ad84be70b90..abeed2db4a4 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -316,6 +316,7 @@ libs: - src/core/lib/gpr/useful.h - src/core/lib/gprpp/arena.h - src/core/lib/gprpp/atomic.h + - src/core/lib/gprpp/construct_destruct.h - src/core/lib/gprpp/debug_location.h - src/core/lib/gprpp/examine_stack.h - src/core/lib/gprpp/fork.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 1bcd8c40aa3..074dd1f2bbe 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -545,6 +545,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', + 'src/core/lib/gprpp/construct_destruct.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.h', @@ -1207,6 +1208,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', + 'src/core/lib/gprpp/construct_destruct.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1bfba46ee75..c5321f30154 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -917,6 +917,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', + 'src/core/lib/gprpp/construct_destruct.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.cc', @@ -1795,6 +1796,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', + 'src/core/lib/gprpp/construct_destruct.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.h', diff --git a/grpc.gemspec b/grpc.gemspec index d84c0aef717..1ce4dbcd54d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -831,6 +831,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/arena.h ) s.files += %w( src/core/lib/gprpp/atomic.h ) + s.files += %w( src/core/lib/gprpp/construct_destruct.h ) s.files += %w( src/core/lib/gprpp/debug_location.h ) s.files += %w( src/core/lib/gprpp/dual_ref_counted.h ) s.files += %w( src/core/lib/gprpp/examine_stack.cc ) diff --git a/package.xml b/package.xml index 2be1e39a18a..58df4f03929 100644 --- a/package.xml +++ b/package.xml @@ -811,6 +811,7 @@ + diff --git a/src/core/lib/gprpp/construct_destruct.h b/src/core/lib/gprpp/construct_destruct.h new file mode 100644 index 00000000000..ad1949f1939 --- /dev/null +++ b/src/core/lib/gprpp/construct_destruct.h @@ -0,0 +1,39 @@ +// Copyright 2021 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. + +#ifndef GRPC_CORE_LIB_GPRPP_CONSTRUCT_DESTRUCT_H +#define GRPC_CORE_LIB_GPRPP_CONSTRUCT_DESTRUCT_H + +#include + +#include + +namespace grpc_core { + +// Call the destructor of p without having to name the type of p. +template +void Destruct(T* p) { + p->~T(); +} + +// Call the constructor of p without having to name the type of p and forward +// any arguments +template +void Construct(T* p, Args&&... args) { + new (p) T(std::forward(args)...); +} + +} // namespace grpc_core + +#endif // GRPC_CORE_LIB_GPRPP_CONSTRUCT_DESTRUCT_H diff --git a/src/core/lib/gprpp/manual_constructor.h b/src/core/lib/gprpp/manual_constructor.h index 48ab231e339..dd98a330e13 100644 --- a/src/core/lib/gprpp/manual_constructor.h +++ b/src/core/lib/gprpp/manual_constructor.h @@ -31,6 +31,8 @@ #include +#include "src/core/lib/gprpp/construct_destruct.h" + namespace grpc_core { // this contains templated helpers needed to implement the ManualConstructors @@ -182,7 +184,7 @@ class ManualConstructor { Type& operator*() { return *get(); } const Type& operator*() const { return *get(); } - void Init() { new (&space_) Type; } + void Init() { Construct(get()); } // Init() constructs the Type instance using the given arguments // (which are forwarded to Type's constructor). @@ -192,17 +194,17 @@ class ManualConstructor { // "new Type();"), so it will leave non-class types uninitialized. template void Init(Ts&&... args) { - new (&space_) Type(std::forward(args)...); + Construct(get(), std::forward(args)...); } // Init() that is equivalent to copy and move construction. // Enables usage like this: // ManualConstructor> 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 Init(const Type& x) { Construct(get(), x); } + void Init(Type&& x) { Construct(get(), std::forward(x)); } - void Destroy() { get()->~Type(); } + void Destroy() { Destruct(get()); } private: typename std::aligned_storage::type space_; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 13687f0884c..dbf92f23352 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1764,6 +1764,7 @@ src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/arena.h \ src/core/lib/gprpp/atomic.h \ +src/core/lib/gprpp/construct_destruct.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/dual_ref_counted.h \ src/core/lib/gprpp/examine_stack.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 72bb37c3706..f2aaa3dbd54 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1603,6 +1603,7 @@ src/core/lib/gprpp/README.md \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/arena.h \ src/core/lib/gprpp/atomic.h \ +src/core/lib/gprpp/construct_destruct.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/dual_ref_counted.h \ src/core/lib/gprpp/examine_stack.cc \