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 \