Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / common / primitiveResource / include / AssertUtils.h
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #ifndef COMMON_INTERNAL_ASSERTUTILS_H
22 #define COMMON_INTERNAL_ASSERTUTILS_H
23
24 #include <cstdint>
25
26 #include <memory>
27
28 #include <octypes.h>
29 #include <OCException.h>
30
31 #include <RCSException.h>
32
33 namespace OIC
34 {
35     namespace Service
36     {
37         namespace Detail
38         {
39             struct NotOCStackResult;
40
41             template <typename FUNC, typename ...PARAMS>
42             struct ResultType
43             {
44                 typedef decltype(std::declval<FUNC>()(std::declval<PARAMS>()...)) type;
45             };
46
47             template< typename A, typename B, typename ENABLER = void >
48             struct EnableIfTypeIs;
49
50             template< typename A >
51             struct EnableIfTypeIs< A, OCStackResult,
52                     typename std::enable_if< std::is_same< A, OCStackResult >::value >::type >
53             {
54                 typedef void type;
55             };
56
57             template< typename A >
58             struct EnableIfTypeIs< A, NotOCStackResult,
59                     typename std::enable_if< !std::is_same< A, OCStackResult >::value >::type >
60             {
61                 typedef A type;
62             };
63
64             template< typename T, typename = typename std::enable_if<
65                     std::is_class<T>::value && std::is_pointer<T>::value>::type >
66             struct EnableIfClassPointer
67             {
68                 typedef void type;
69             };
70
71             template< typename T, typename = typename std::enable_if< std::is_class< T >::value > >
72             struct EnableIfClass
73             {
74                 typedef void type;
75             };
76         }
77
78         inline void expectOCStackResult(OCStackResult actual,
79                 std::initializer_list<OCStackResult> allowed)
80         {
81             for (auto r : allowed)
82             {
83                 if (actual == r) return;
84             }
85
86             throw PlatformException(actual);
87         }
88
89         inline void expectOCStackResult(OCStackResult actual, OCStackResult expected)
90         {
91             if (actual != expected)
92             {
93                 throw PlatformException(actual);
94             }
95         }
96
97         inline void expectOCStackResultOK(OCStackResult actual)
98         {
99             expectOCStackResult(actual, OC_STACK_OK);
100         }
101
102         template< typename FUNC, typename ...PARAMS >
103         typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
104                 OCStackResult >::type
105         invokeOCFuncWithResultExpect(std::initializer_list<OCStackResult> allowed,
106                 FUNC&& fn, PARAMS&& ...params)
107         {
108             try
109             {
110                 expectOCStackResult(fn(std::forward< PARAMS >(params)...), std::move(allowed));
111             }
112             catch (const OC::OCException& e)
113             {
114                 throw PlatformException(e.code());
115             }
116         }
117
118
119         template< typename FUNC, typename ...PARAMS >
120         typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
121                 OCStackResult >::type
122         invokeOCFunc(FUNC&& fn, PARAMS&& ...params)
123         {
124             try
125             {
126                 expectOCStackResultOK(fn(std::forward< PARAMS >(params)...));
127             }
128             catch (const OC::OCException& e)
129             {
130                 throw PlatformException(e.code());
131             }
132         }
133
134         template< typename FUNC, typename ...PARAMS >
135         typename Detail::EnableIfTypeIs< typename Detail::ResultType< FUNC, PARAMS... >::type,
136                         Detail::NotOCStackResult >::type
137         invokeOCFunc(FUNC* fn, PARAMS&& ...params)
138         {
139             try
140             {
141                 return fn(std::forward< PARAMS >(params)...);
142             }
143             catch (const OC::OCException& e)
144             {
145                 throw PlatformException(e.code());
146             }
147         }
148
149         template< typename OBJ, typename = typename Detail::EnableIfClassPointer<OBJ>::type,
150                 typename FUNC, typename ...PARAMS >
151         inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) ->
152             typename Detail::EnableIfTypeIs<
153                 decltype((obj->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>::
154                 type
155         {
156             try
157             {
158                 expectOCStackResultOK(obj->*fn(std::forward< PARAMS >(params)...));
159             }
160             catch (const OC::OCException& e)
161             {
162                 throw PlatformException(e.code());
163             }
164         }
165
166         template< typename OBJ, typename = typename Detail::EnableIfClassPointer<OBJ>::type,
167                 typename FUNC, typename ...PARAMS >
168         inline auto invokeOC(OBJ&& obj, FUNC&& fn, PARAMS&& ...params) ->
169                 typename Detail::EnableIfTypeIs<
170                     decltype((obj->*fn)(std::forward< PARAMS >(params)...)),
171                     Detail::NotOCStackResult>::
172                     type
173         {
174             try
175             {
176                 obj->*fn(std::forward< PARAMS >(params)...);
177             }
178             catch (const OC::OCException& e)
179             {
180                 throw PlatformException(e.code());
181             }
182         }
183
184         template< typename OBJ, typename = typename Detail::EnableIfClass<OBJ>::type,
185                 typename FUNC, typename ...PARAMS >
186         inline auto invokeOC(const std::shared_ptr< OBJ >& obj, FUNC&& fn, PARAMS&& ...params) ->
187                 typename Detail::EnableIfTypeIs<
188                     decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)), OCStackResult>::
189                     type
190         {
191             try
192             {
193                 expectOCStackResultOK((obj.get()->*fn)(std::forward< PARAMS >(params)...));
194             }
195             catch (const OC::OCException& e)
196             {
197                 throw PlatformException(e.code());
198             }
199         }
200
201         template< typename OBJ, typename = typename Detail::EnableIfClass< OBJ >::type,
202                 typename FUNC, typename ...PARAMS >
203         inline auto invokeOC(const std::shared_ptr<OBJ>& obj, FUNC&& fn, PARAMS&& ...params) ->
204             typename Detail::EnableIfTypeIs<
205                    decltype((obj.get()->*fn)(std::forward< PARAMS >(params)...)),
206                    Detail::NotOCStackResult>::
207                    type
208         {
209             try
210             {
211                 return (obj.get()->*fn)(std::forward< PARAMS >(params)...);
212             }
213             catch (const OC::OCException& e)
214             {
215                 throw PlatformException(e.code());
216             }
217         }
218
219     }
220 }
221
222 #endif // COMMON_INTERNAL_ASSERTUTILS_H