ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
testVirtualFunctionTemplate.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#define BOOST_TEST_DYN_LINK
5#define BOOST_TEST_MODULE VirtualFunctionTemplateTest
6#include <boost/test/unit_test.hpp>
7using namespace boost::unit_test_framework;
8
11
12namespace ChimeraTK {
13 class Base {
14 public:
16 template<typename T>
17 std::string getValue(T& base) {
18 return CALL_VIRTUAL_FUNCTION_TEMPLATE(getValue_impl, T, base);
19 }
20
21 DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(getValue_impl, std::string(T&));
22
23 private:
24 template<typename T>
25 std::string getValue_impl(T& /*base*/) {
26 return std::string("Base: ") + typeid(T).name();
27 }
28 };
29
30 class Derived1 : public Base {
31 public:
33 DEFINE_VIRTUAL_FUNCTION_OVERRIDE_VTABLE(Base, getValue_impl, std::string(T&));
34
35 private:
36 template<typename T>
37 std::string getValue_impl(T& base) {
38 if constexpr(std::is_same_v<std::string, T>) {
39 return CALL_BASE_FUNCTION_TEMPLATE(Base, getValue_impl, T, base);
40 }
41 return std::string("Derived1: ") + typeid(T).name();
42 }
43 };
44
45 class Derived2 : public Derived1 {
46 public:
48 DEFINE_VIRTUAL_FUNCTION_OVERRIDE_VTABLE(Derived1, getValue_impl, std::string(T&));
49
50 private:
51 template<typename T>
52 std::string getValue_impl(T& base) {
53 if constexpr(std::is_same_v<float, T>) {
54 return CALL_BASE_FUNCTION_TEMPLATE(Derived1, getValue_impl, T, base);
55 }
56 else if constexpr(std::is_same_v<double, T>) {
57 return CALL_BASE_FUNCTION_TEMPLATE(Base, getValue_impl, T, base);
58 }
59 return std::string("Derived2: ") + typeid(T).name();
60 }
61 };
62
63} // namespace ChimeraTK
64
65BOOST_AUTO_TEST_CASE(testBaseClass) {
66 ChimeraTK::Base base;
68
69 ChimeraTK::for_each(typeMap, [&](auto& pair) {
70 typedef typename std::remove_reference<decltype(pair)>::type::first_type T;
71 T argument;
72 BOOST_TEST(base.getValue<T>(argument) == std::string("Base: ") + typeid(T).name());
73 });
74}
75
76BOOST_AUTO_TEST_CASE(testDerived1Class) {
79
80 ChimeraTK::for_each(typeMap, [&](auto& pair) {
81 typedef typename std::remove_reference<decltype(pair)>::type::first_type T;
82 T argument;
83 if constexpr(std::is_same_v<T, std::string>) {
84 BOOST_TEST(base.getValue<T>(argument) == std::string("Base: ") + typeid(T).name());
85 }
86 else {
87 BOOST_TEST(base.getValue<T>(argument) == std::string("Derived1: ") + typeid(T).name());
88 }
89 });
90}
91
92BOOST_AUTO_TEST_CASE(testDerived2Class) {
95
96 ChimeraTK::for_each(typeMap, [&](auto& pair) {
97 typedef typename std::remove_reference<decltype(pair)>::type::first_type T;
98 T argument;
99 if constexpr(std::is_same_v<T, double>) {
100 BOOST_TEST(base.getValue<T>(argument) == std::string("Base: ") + typeid(T).name());
101 }
102 else if constexpr(std::is_same_v<T, float>) {
103 BOOST_TEST(base.getValue<T>(argument) == std::string("Derived1: ") + typeid(T).name());
104 }
105 else {
106 BOOST_TEST(base.getValue<T>(argument) == std::string("Derived2: ") + typeid(T).name());
107 }
108 });
109}
#define OVERRIDE_VIRTUAL_FUNCTION_TEMPLATE(BaseClass, functionName)
Save the old vtable to be accessible by CALL_BASE_FUNCTION_TEMPLATE and overwrite it with the new imp...
#define CALL_BASE_FUNCTION_TEMPLATE(BaseClass, functionName, templateArgument,...)
Execute the virtual function template call to the base implementation of the function.
#define CALL_VIRTUAL_FUNCTION_TEMPLATE(functionName, templateArgument,...)
Execute the virtual function template call using the vtable defined with the DEFINE_VIRTUAL_FUNCTION_...
#define FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(functionName)
Fill the vtable of a virtual function template defined with DEFINE_VIRTUAL_FUNCTION_TEMPLATE.
std::string getValue(T &base)
DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(getValue_impl, std::string(T &))
DEFINE_VIRTUAL_FUNCTION_OVERRIDE_VTABLE(Base, getValue_impl, std::string(T &))
DEFINE_VIRTUAL_FUNCTION_OVERRIDE_VTABLE(Derived1, getValue_impl, std::string(T &))
boost::fusion::map< boost::fusion::pair< int8_t, int8_t >, boost::fusion::pair< uint8_t, uint8_t >, boost::fusion::pair< int16_t, int16_t >, boost::fusion::pair< uint16_t, uint16_t >, boost::fusion::pair< int32_t, int32_t >, boost::fusion::pair< uint32_t, uint32_t >, boost::fusion::pair< int64_t, int64_t >, boost::fusion::pair< uint64_t, uint64_t >, boost::fusion::pair< float, float >, boost::fusion::pair< double, double >, boost::fusion::pair< std::string, std::string >, boost::fusion::pair< Boolean, Boolean >, boost::fusion::pair< Void, Void > > userTypeMap
Map of UserType to value of the UserType.
void for_each(MAPTYPE &map, const LAMBDATYPE &lambda)
Variant of boost::fusion::for_each() to iterate a boost::fusion::map, which accepts a lambda instead ...
BOOST_AUTO_TEST_CASE(testBaseClass)