From: coderhyme Date: Mon, 22 Jun 2015 07:29:01 +0000 (+0900) Subject: Add helper methods to invoke OC methods safely X-Git-Tag: 1.2.0+RC1~1430^2~113 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0e0c23c109f1a9924e593c056c057755c08b4f18;p=platform%2Fupstream%2Fiotivity.git Add helper methods to invoke OC methods safely Change-Id: I94b4310f39530587003c5c153cf6feb870f924d2 Signed-off-by: coderhyme Reviewed-on: https://gerrit.iotivity.org/gerrit/1376 Tested-by: jenkins-iotivity Reviewed-by: Uze Choi --- diff --git a/service/basis/common/primitiveResource/include/internal/AssertUtils.h b/service/basis/common/primitiveResource/include/internal/AssertUtils.h index 40d286e..d8f5244 100644 --- a/service/basis/common/primitiveResource/include/internal/AssertUtils.h +++ b/service/basis/common/primitiveResource/include/internal/AssertUtils.h @@ -22,7 +22,11 @@ #define __PRIMITIVERESOURCE_ASSERTUTILS_H #include + +#include + #include +#include #include @@ -30,6 +34,63 @@ namespace OIC { namespace Service { + namespace Detail + { + struct NotOCStackResult; + + template< typename RET, typename FUNC, typename ENABLER = void, typename ...PARAMS > + struct EnableIfReturnTypeIs; + + template< typename FUNC, typename ...PARAMS > + struct EnableIfReturnTypeIs< OCStackResult, FUNC, + typename std::enable_if< + std::is_same< typename std::result_of< FUNC(PARAMS...) >::type, + OCStackResult >::value >::type, PARAMS... > + { + using type = void; + }; + + template< typename FUNC, typename ...PARAMS > + struct EnableIfReturnTypeIs< NotOCStackResult, FUNC, + typename std::enable_if< + !std::is_same< typename std::result_of< FUNC(PARAMS...) >::type, + OCStackResult >::value >::type, PARAMS... > + { + using type = typename std::result_of< FUNC(PARAMS...) >::type; + }; + + + template< typename A, typename B, typename ENABLER = void > + struct EnableIfTypeIs; + + template< typename A > + struct EnableIfTypeIs< A, OCStackResult, + typename std::enable_if< std::is_same< A, OCStackResult >::value >::type > + { + using type = void; + }; + + template< typename A > + struct EnableIfTypeIs< A, NotOCStackResult, + typename std::enable_if< !std::is_same< A, OCStackResult >::value >::type > + { + using type = A; + }; + + + template< typename T, typename = typename std::enable_if< + std::is_class::value && std::is_pointer::value>::type > + struct EnableIfClassPointer + { + using type = void; + }; + + template< typename T, typename = typename std::enable_if::value > > + struct EnableIfClass + { + using type = void; + }; + } inline void expectOCStackResult(OCStackResult actual, OCStackResult expected) { @@ -44,6 +105,108 @@ namespace OIC expectOCStackResult(actual, OC_STACK_OK); } + template< typename FUNC, + typename = typename std::enable_if::value>::type, + typename ...PARAMS > + typename Detail::EnableIfReturnTypeIs< OCStackResult, FUNC, PARAMS... >::type + invokeOC(FUNC&& fn, PARAMS&& ...params) + { + try + { + expectOCStackResultOK(fn(std::forward< PARAMS >(params)...)); + } + catch (OC::OCException& e) + { + throw PlatformException(e.code()); + } + } + + template< typename FUNC, + typename = typename std::enable_if::value>::type, + typename ...PARAMS > + typename Detail::EnableIfReturnTypeIs< Detail::NotOCStackResult, FUNC, PARAMS... >::type + invokeOC(FUNC&& fn, PARAMS&& ...params) + { + try + { + return fn(std::forward< PARAMS >(params)...); + } + catch (OC::OCException& e) + { + throw PlatformException(e.code()); + } + } + + template< typename OBJ, typename = typename Detail::EnableIfClassPointer::type, + typename FUNC, typename ...PARAMS > + inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) -> + typename Detail::EnableIfTypeIs< + decltype((obj->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>:: + type + { + try + { + expectOCStackResultOK(obj->*fn(std::forward< PARAMS >(params)...)); + } + catch (OC::OCException& e) + { + throw PlatformException(e.code()); + } + } + + template< typename OBJ, typename = typename Detail::EnableIfClassPointer::type, + typename FUNC, typename ...PARAMS > + inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) -> + typename Detail::EnableIfTypeIs< + decltype((obj->*fn)(std::forward< PARAMS >(params)...)), + Detail::NotOCStackResult>:: + type + { + try + { + obj->*fn(std::forward< PARAMS >(params)...); + } + catch (OC::OCException& e) + { + throw PlatformException(e.code()); + } + } + + template< typename OBJ, typename = typename Detail::EnableIfClass::type, + typename FUNC, typename ...PARAMS > + inline auto invokeOC(const std::shared_ptr< OBJ >& obj, FUNC&& fn, PARAMS&& ...params) -> + typename Detail::EnableIfTypeIs< + decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>:: + type + { + try + { + expectOCStackResultOK((obj.get()->*fn)(std::forward< PARAMS >(params)...)); + } + catch (OC::OCException& e) + { + throw PlatformException(e.code()); + } + } + + template< typename OBJ, typename = typename Detail::EnableIfClass< OBJ >::type, + typename FUNC, typename ...PARAMS > + inline auto invokeOC(const std::shared_ptr& obj, FUNC&& fn, PARAMS&& ...params) -> + typename Detail::EnableIfTypeIs< + decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)), + Detail::NotOCStackResult>:: + type + { + try + { + return (obj.get()->*fn)(std::forward< PARAMS >(params)...); + } + catch (OC::OCException& e) + { + throw PlatformException(e.code()); + } + } + } }