diff --git a/src/sinqAxis.cpp b/src/sinqAxis.cpp index 83ab0d3..b7c7a58 100644 --- a/src/sinqAxis.cpp +++ b/src/sinqAxis.cpp @@ -10,6 +10,8 @@ #include #include +#define getControllerMethod pController + struct sinqAxisImpl { // Internal variables used in the movement timeout watchdog time_t expectedArrivalTime; @@ -29,9 +31,9 @@ struct sinqAxisImpl { }; // Generic fallback - if the compiler tries to compile this function, it fails. -template -asynStatus setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), T writeValue, +template +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T writeValue, const char *callerFunctionName, int lineNumber) { static_assert( sizeof(T) == 0, @@ -39,10 +41,11 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName, return asynError; } -template <> -asynStatus setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), int writeValue, - const char *callerFunctionName, int lineNumber) { +template ::value, int> = 0> +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T writeValue, + const char *callerFunctionName, int lineNumber) { int indexValue = (axis->pController()->*func)(); asynStatus status = axis->setIntegerParam(indexValue, writeValue); if (status != asynSuccess) { @@ -52,19 +55,20 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName, return asynSuccess; } -template <> -asynStatus setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), bool writeValue, - const char *callerFunctionName, int lineNumber) { +template ::value, bool> = 0> +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T writeValue, + const char *callerFunctionName, int lineNumber) { return setAxisParam(axis, indexName, func, static_cast(writeValue), callerFunctionName, lineNumber); } -template <> -asynStatus -setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), double writeValue, - const char *callerFunctionName, int lineNumber) { +template ::value, double> = 0> +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (sinqController::*func)(), T writeValue, + const char *callerFunctionName, int lineNumber) { int indexValue = (axis->pController()->*func)(); asynStatus status = axis->setDoubleParam(indexValue, writeValue); if (status != asynSuccess) { @@ -74,11 +78,11 @@ setAxisParam(sinqAxis *axis, const char *indexName, return asynSuccess; } -template <> -asynStatus setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), char *writeValue, - const char *callerFunctionName, - int lineNumber) { +template ::value, char *> = 0> +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T writeValue, + const char *callerFunctionName, int lineNumber) { int indexValue = (axis->pController()->*func)(); asynStatus status = axis->setStringParam(indexValue, writeValue); if (status != asynSuccess) { @@ -88,12 +92,12 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName, return asynSuccess; } -template <> -asynStatus setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), - const char *writeValue, - const char *callerFunctionName, - int lineNumber) { +template < + typename A, typename C, typename T, + std::enable_if_t::value, const char *> = 0> +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T writeValue, + const char *callerFunctionName, int lineNumber) { int indexValue = (axis->pController()->*func)(); asynStatus status = axis->setStringParam(indexValue, writeValue); if (status != asynSuccess) { @@ -104,9 +108,9 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName, } // Generic fallback - if the compiler tries to compile this function, it fails. -template -asynStatus getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), T *readValue, +template +asynStatus getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T *readValue, const char *callerFunctionName, int lineNumber) { static_assert( sizeof(T) == 0, @@ -114,9 +118,10 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName, return asynError; } -template <> -asynStatus getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), int *readValue, +template ::value, int> = 0> +asynStatus getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T *readValue, const char *callerFunctionName, int lineNumber) { int indexValue = (axis->pController()->*func)(); asynStatus status = axis->pController()->getIntegerParam( @@ -128,19 +133,21 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName, return asynSuccess; } -template <> -asynStatus getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), bool *readValue, +template ::value, bool> = 0> +asynStatus getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T *readValue, const char *callerFunctionName, int lineNumber) { return getAxisParam(axis, indexName, func, (int *)readValue, callerFunctionName, lineNumber); } -template <> -asynStatus -getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), double *readValue, - const char *callerFunctionName, int lineNumber) { +template ::value, double> = 0> +asynStatus getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T *readValue, + const char *callerFunctionName, + int lineNumber) { int indexValue = (axis->pController()->*func)(); asynStatus status = axis->pController()->getDoubleParam( axis->axisNo(), indexValue, readValue); @@ -151,9 +158,10 @@ getAxisParam(sinqAxis *axis, const char *indexName, return asynSuccess; } -template <> -asynStatus getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), char *readValue, +template ::value, char> = 0> +asynStatus getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T *readValue, const char *callerFunctionName, int lineNumber) { int maxChars = 200; @@ -168,20 +176,21 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName, return asynSuccess; } -template -asynStatus getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), char (&readValue)[N], +template ::value, char> = 0, size_t N> +asynStatus getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T (&readValue)[N], const char *callerFunctionName, int lineNumber) { // Decay the array to char* - return getAxisParam(axis, indexName, func, + return getAxisParam(axis, controller, indexName, func, static_cast(readValue), callerFunctionName, lineNumber); } -template <> +template asynStatus -getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), std::string *readValue, +getAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), std::string *readValue, const char *callerFunctionName, int lineNumber) { int indexValue = (axis->pController()->*func)(); diff --git a/src/sinqAxis.h b/src/sinqAxis.h index 1f741f4..17f140d 100644 --- a/src/sinqAxis.h +++ b/src/sinqAxis.h @@ -365,9 +365,22 @@ class epicsShareClass sinqAxis : public asynMotorAxis { asynStatus assertConnected(); /** - * @brief Return a pointer to the axis controller + * @brief Return a pointer to the axis controller. + * + * This function should be overriden in derived classes using the `override` + * keyword so the macros `getAxisParamChecked` and `setAxisParamChecked` + * work correctly: + * + * ``` + * class mySpecialAxis : public sinqAxis { + public: + mySpecialController* getControllerMethod() override { + return mySpecialControllerPtr; + } + }; + * ``` */ - sinqController *pController() { return pC_; }; + virtual sinqController *pController() { return pC_; }; /** * @brief Returns true, if the axis was moving in the last poll cycle, and @@ -423,9 +436,9 @@ class epicsShareClass sinqAxis : public asynMotorAxis { * @param lineNumber * @return asynStatus */ -template -asynStatus setAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), T writeValue, +template +asynStatus setAxisParam(A *axis, C *controller, const char *indexName, + int (C::*func)(), T writeValue, const char *callerFunctionName, int lineNumber); /** @@ -457,7 +470,7 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName, #define setAxisParamChecked(axis, indexGetterFunction, writeValue) \ { \ asynStatus setStatus = setAxisParam( \ - axis, #indexGetterFunction, \ + axis, axis->pController(), #indexGetterFunction, \ &std::remove_pointer< \ decltype(axis->pController())>::type::indexGetterFunction, \ writeValue, __PRETTY_FUNCTION__, __LINE__); \ @@ -488,17 +501,17 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName, * to. * @return asynStatus */ -template -asynStatus getAxisParam(sinqAxis *axis, const char *indexName, - int (sinqController::*func)(), T *readValue, - const char *callerFunctionName, int lineNumber); +template +asynStatus getAxisParam(A *axis, const char *indexName, int (C::*func)(), + T *readValue, const char *callerFunctionName, + int lineNumber); /** * @brief Macro to get an paramLib parameter and error checking the return value * * This macro is a wrapper around `getIntegerParam` / `getDoubleParam` / * `getStringParam` which checks if the operation was successfull. If it wasn't, - * it returns by calling the paramLibAccessFailed function. + * it returns by calling the paramLibAccessFailed function. In order * * For example, the following input: * ``` @@ -522,7 +535,7 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName, #define getAxisParamChecked(axis, indexGetterFunction, readValue) \ { \ asynStatus getStatus = getAxisParam( \ - axis, #indexGetterFunction, \ + axis, axis->pController(), #indexGetterFunction, \ &std::remove_pointer< \ decltype(axis->pController())>::type::indexGetterFunction, \ readValue, __PRETTY_FUNCTION__, __LINE__); \