ChimeraTK-DeviceAccess  03.18.00
VirtualFunctionTemplate.h
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 #pragma once
4 
5 #include <boost/bind/bind.hpp>
6 #include <boost/function.hpp>
7 #include <boost/fusion/include/at_key.hpp>
8 #include <boost/fusion/include/for_each.hpp>
9 
42 #define DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(functionName, ...) \
43  template<typename T> \
44  class functionName##_functionSignature : public boost::function<__VA_ARGS__> { \
45  public: \
46  functionName##_functionSignature& operator=(const boost::function<__VA_ARGS__>& rhs) { \
47  boost::function<__VA_ARGS__>::operator=(rhs); \
48  return *this; \
49  } \
50  }; \
51  TemplateUserTypeMap<functionName##_functionSignature> functionName##_vtable
52 
58 #define DEFINE_VIRTUAL_FUNCTION_OVERRIDE_VTABLE(BaseClass, functionName, ...) \
59  DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(BaseClass##functionName, __VA_ARGS__)
60 
70 #define CALL_VIRTUAL_FUNCTION_TEMPLATE(functionName, templateArgument, ...) \
71  boost::fusion::at_key<templateArgument>(functionName##_vtable.table)(__VA_ARGS__)
72 
78 #define CALL_BASE_FUNCTION_TEMPLATE(BaseClass, functionName, templateArgument, ...) \
79  boost::fusion::at_key<templateArgument>(BaseClass##functionName##_vtable.table)(__VA_ARGS__)
80 
84 #define FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(functionName) \
85  ChimeraTK::for_each(this->functionName##_vtable.table, [this](auto& pair) { \
86  typedef typename std::remove_reference<decltype(pair)>::type::first_type VTableFillerUserType; \
87  pair.second = [this](auto... args) { return this->functionName<VTableFillerUserType>(args...); }; \
88  })
89 
93 #define OVERRIDE_VIRTUAL_FUNCTION_TEMPLATE(BaseClass, functionName) \
94  do { \
95  /* Copy the old vtable into _base before filling it with the new implementation */ \
96  ChimeraTK::for_each(BaseClass##functionName##_vtable.table, [&](auto& pair) { \
97  typedef typename std::remove_reference<decltype(pair)>::type::first_type VTableFillerUserType; \
98  pair.second = (boost::fusion::at_key<VTableFillerUserType>(functionName##_vtable.table)); \
99  }); \
100  FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(functionName); \
101  } while(false)
102 
104 #define FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE_STANDALONE(functionName, numberOfArguments) \
105  FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(functionName)
106 
108 #define DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE_FILLER(className, functionName, numberOfArguments) \
109  class UslessVTableFillerClass##functionName {}