[gprpp] Implement down_cast - a debug-time checked down cast (#35548)
Closes #35548
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35548 from ctiller:down_cast cd7501dadd
PiperOrigin-RevId: 599176414
This commit is contained in:
parent
e36025d3d2
commit
c77ba326e9
|
|
@ -1009,6 +1009,7 @@ if(gRPC_BUILD_TESTS)
|
|||
add_dependencies(buildtests_cxx disappearing_server_test)
|
||||
add_dependencies(buildtests_cxx dns_resolver_cooldown_test)
|
||||
add_dependencies(buildtests_cxx dns_resolver_test)
|
||||
add_dependencies(buildtests_cxx down_cast_test)
|
||||
add_dependencies(buildtests_cxx dual_ref_counted_test)
|
||||
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
|
||||
add_dependencies(buildtests_cxx dualstack_socket_test)
|
||||
|
|
@ -11917,6 +11918,40 @@ target_link_libraries(dns_resolver_test
|
|||
)
|
||||
|
||||
|
||||
endif()
|
||||
if(gRPC_BUILD_TESTS)
|
||||
|
||||
add_executable(down_cast_test
|
||||
test/core/gprpp/down_cast_test.cc
|
||||
)
|
||||
target_compile_features(down_cast_test PUBLIC cxx_std_14)
|
||||
target_include_directories(down_cast_test
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
|
||||
${_gRPC_RE2_INCLUDE_DIR}
|
||||
${_gRPC_SSL_INCLUDE_DIR}
|
||||
${_gRPC_UPB_GENERATED_DIR}
|
||||
${_gRPC_UPB_GRPC_GENERATED_DIR}
|
||||
${_gRPC_UPB_INCLUDE_DIR}
|
||||
${_gRPC_XXHASH_INCLUDE_DIR}
|
||||
${_gRPC_ZLIB_INCLUDE_DIR}
|
||||
third_party/googletest/googletest/include
|
||||
third_party/googletest/googletest
|
||||
third_party/googletest/googlemock/include
|
||||
third_party/googletest/googlemock
|
||||
${_gRPC_PROTO_GENS_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(down_cast_test
|
||||
${_gRPC_ALLTARGETS_LIBRARIES}
|
||||
gtest
|
||||
absl::config
|
||||
gpr
|
||||
)
|
||||
|
||||
|
||||
endif()
|
||||
if(gRPC_BUILD_TESTS)
|
||||
|
||||
|
|
|
|||
|
|
@ -7990,6 +7990,19 @@ targets:
|
|||
deps:
|
||||
- gtest
|
||||
- grpc_test_util
|
||||
- name: down_cast_test
|
||||
gtest: true
|
||||
build: test
|
||||
language: c++
|
||||
headers:
|
||||
- src/core/lib/gprpp/down_cast.h
|
||||
src:
|
||||
- test/core/gprpp/down_cast_test.cc
|
||||
deps:
|
||||
- gtest
|
||||
- absl/base:config
|
||||
- gpr
|
||||
uses_polling: false
|
||||
- name: dual_ref_counted_test
|
||||
gtest: true
|
||||
build: test
|
||||
|
|
|
|||
|
|
@ -5085,6 +5085,13 @@ grpc_cc_library(
|
|||
],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "down_cast",
|
||||
hdrs = ["lib/gprpp/down_cast.h"],
|
||||
external_deps = ["absl/base:config"],
|
||||
deps = ["//:gpr"],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "status_conversion",
|
||||
srcs = ["lib/transport/status_conversion.cc"],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2024 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_SRC_CORE_LIB_GPRPP_DOWN_CAST_H
|
||||
#define GRPC_SRC_CORE_LIB_GPRPP_DOWN_CAST_H
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
template <typename To, typename From>
|
||||
inline To down_cast(From* f) {
|
||||
static_assert(
|
||||
std::is_base_of<From, typename std::remove_pointer<To>::type>::value,
|
||||
"down_cast requires a base-to-derived relationship");
|
||||
// If we have RTTI & we're in debug, assert that the cast is legal.
|
||||
#if ABSL_INTERNAL_HAS_RTTI
|
||||
#ifndef NDEBUG
|
||||
if (f != nullptr) GPR_ASSERT(dynamic_cast<To>(f) != nullptr);
|
||||
#endif
|
||||
#endif
|
||||
return static_cast<To>(f);
|
||||
}
|
||||
|
||||
template <typename To, typename From>
|
||||
inline To down_cast(From& f) {
|
||||
return *down_cast<typename std::remove_reference<To>::type*>(&f);
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_GPRPP_DOWN_CAST_H
|
||||
|
|
@ -135,6 +135,18 @@ grpc_cc_test(
|
|||
],
|
||||
)
|
||||
|
||||
grpc_cc_test(
|
||||
name = "down_cast_test",
|
||||
srcs = ["down_cast_test.cc"],
|
||||
external_deps = ["gtest"],
|
||||
language = "C++",
|
||||
uses_event_engine = False,
|
||||
uses_polling = False,
|
||||
deps = [
|
||||
"//src/core:down_cast",
|
||||
],
|
||||
)
|
||||
|
||||
grpc_cc_test(
|
||||
name = "table_test",
|
||||
srcs = ["table_test.cc"],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2024 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.
|
||||
|
||||
#include "src/core/lib/gprpp/down_cast.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
||||
class Base {
|
||||
public:
|
||||
virtual ~Base() = default;
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
public:
|
||||
int i = 3;
|
||||
};
|
||||
|
||||
TEST(DownCastTest, DownCast) {
|
||||
Derived d;
|
||||
Base* b = &d;
|
||||
EXPECT_EQ(down_cast<Derived*>(b)->i, 3);
|
||||
EXPECT_EQ(down_cast<Derived&>(*b).i, 3);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ EXTERNAL_DEPS = {
|
|||
"absl/algorithm/container.h": "absl/algorithm:container",
|
||||
"absl/base/attributes.h": "absl/base:core_headers",
|
||||
"absl/base/call_once.h": "absl/base",
|
||||
"absl/base/config.h": "absl/base:config",
|
||||
# TODO(ctiller) remove this
|
||||
"absl/base/internal/endian.h": "absl/base:endian",
|
||||
"absl/base/thread_annotations.h": "absl/base:core_headers",
|
||||
|
|
|
|||
|
|
@ -2899,6 +2899,30 @@
|
|||
],
|
||||
"uses_polling": true
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"benchmark": false,
|
||||
"ci_platforms": [
|
||||
"linux",
|
||||
"mac",
|
||||
"posix",
|
||||
"windows"
|
||||
],
|
||||
"cpu_cost": 1.0,
|
||||
"exclude_configs": [],
|
||||
"exclude_iomgrs": [],
|
||||
"flaky": false,
|
||||
"gtest": true,
|
||||
"language": "c++",
|
||||
"name": "down_cast_test",
|
||||
"platforms": [
|
||||
"linux",
|
||||
"mac",
|
||||
"posix",
|
||||
"windows"
|
||||
],
|
||||
"uses_polling": false
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"benchmark": false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue