Merge pull request #13288 from ncteisen/inheritance-in-core
Support Manually Constructed Virtual Functions in C Corepull/13483/head
commit
9c26f6866a
17 changed files with 421 additions and 1 deletions
@ -0,0 +1,29 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2017 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_SUPPORT_ABSTRACT_H |
||||||
|
#define GRPC_CORE_LIB_SUPPORT_ABSTRACT_H |
||||||
|
|
||||||
|
// This is needed to support abstract base classes in the c core. Since gRPC
|
||||||
|
// doesn't have a c++ runtime, it will hit a linker error on delete unless
|
||||||
|
// we define a virtual operator delete. See this blog for more info:
|
||||||
|
// https://eli.thegreenplace.net/2015/c-deleting-destructors-and-virtual-operator-delete/
|
||||||
|
#define GRPC_ABSTRACT_BASE_CLASS \ |
||||||
|
static void operator delete(void* p) { abort(); } |
||||||
|
|
||||||
|
#endif /* GRPC_CORE_LIB_SUPPORT_ABSTRACT_H */ |
@ -0,0 +1,99 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2017 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. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Test of gpr synchronization support. */ |
||||||
|
|
||||||
|
#include "src/core/lib/support/manual_constructor.h" |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/sync.h> |
||||||
|
#include <grpc/support/thd.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <cstring> |
||||||
|
#include "src/core/lib/support/abstract.h" |
||||||
|
#include "test/core/util/test_config.h" |
||||||
|
|
||||||
|
class A { |
||||||
|
public: |
||||||
|
A() {} |
||||||
|
virtual ~A() {} |
||||||
|
virtual const char* foo() { return "A_foo"; } |
||||||
|
virtual const char* bar() { return "A_bar"; } |
||||||
|
GRPC_ABSTRACT_BASE_CLASS |
||||||
|
}; |
||||||
|
|
||||||
|
class B : public A { |
||||||
|
public: |
||||||
|
B() {} |
||||||
|
~B() {} |
||||||
|
const char* foo() override { return "B_foo"; } |
||||||
|
char get_junk() { return junk[0]; } |
||||||
|
|
||||||
|
private: |
||||||
|
char junk[1000]; |
||||||
|
}; |
||||||
|
|
||||||
|
class C : public B { |
||||||
|
public: |
||||||
|
C() {} |
||||||
|
~C() {} |
||||||
|
virtual const char* bar() { return "C_bar"; } |
||||||
|
char get_more_junk() { return more_junk[0]; } |
||||||
|
|
||||||
|
private: |
||||||
|
char more_junk[1000]; |
||||||
|
}; |
||||||
|
|
||||||
|
class D : public A { |
||||||
|
public: |
||||||
|
virtual const char* bar() { return "D_bar"; } |
||||||
|
}; |
||||||
|
|
||||||
|
static void basic_test() { |
||||||
|
grpc_core::PolymorphicManualConstructor<A, B> poly; |
||||||
|
poly.Init<B>(); |
||||||
|
GPR_ASSERT(!strcmp(poly->foo(), "B_foo")); |
||||||
|
GPR_ASSERT(!strcmp(poly->bar(), "A_bar")); |
||||||
|
} |
||||||
|
|
||||||
|
static void complex_test() { |
||||||
|
grpc_core::PolymorphicManualConstructor<A, B, C, D> polyB; |
||||||
|
polyB.Init<B>(); |
||||||
|
GPR_ASSERT(!strcmp(polyB->foo(), "B_foo")); |
||||||
|
GPR_ASSERT(!strcmp(polyB->bar(), "A_bar")); |
||||||
|
|
||||||
|
grpc_core::PolymorphicManualConstructor<A, B, C, D> polyC; |
||||||
|
polyC.Init<C>(); |
||||||
|
GPR_ASSERT(!strcmp(polyC->foo(), "B_foo")); |
||||||
|
GPR_ASSERT(!strcmp(polyC->bar(), "C_bar")); |
||||||
|
|
||||||
|
grpc_core::PolymorphicManualConstructor<A, B, C, D> polyD; |
||||||
|
polyD.Init<D>(); |
||||||
|
GPR_ASSERT(!strcmp(polyD->foo(), "A_foo")); |
||||||
|
GPR_ASSERT(!strcmp(polyD->bar(), "D_bar")); |
||||||
|
} |
||||||
|
|
||||||
|
/* ------------------------------------------------- */ |
||||||
|
|
||||||
|
int main(int argc, char* argv[]) { |
||||||
|
grpc_test_init(argc, argv); |
||||||
|
basic_test(); |
||||||
|
complex_test(); |
||||||
|
return 0; |
||||||
|
} |
Loading…
Reference in new issue