1 /*
2 * Copyright (c) 2015, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software without
17 * specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #pragma once
31
32 #include <utility>
33 #include "Exception.hpp"
34
35 namespace parameterFramework
36 {
37
38 namespace details
39 {
40
successTest(bool res)41 static inline bool successTest(bool res)
42 {
43 return res;
44 }
45
46 template <class T>
successTest(T * res)47 static inline bool successTest(T *res)
48 {
49 return res != nullptr;
50 }
51
52 } // namespace details
53
54 template <class Base>
55 class FailureWrapper : protected Base
56 {
57 public:
58 /** Forward construction to base. */
59 template <class... Args>
FailureWrapper(Args &&...args)60 FailureWrapper(Args &&... args) : Base(std::forward<Args>(args)...)
61 {
62 }
63
64 /** Wrap a const method that may fail to throw an Exception instead of
65 * retuning a boolean.
66 *
67 * @param[in] method (const) that return a boolean to indicate failure.
68 * @param[in] args parameters to call method call with. */
69 template <class K, class... MArgs, class... Args>
mayFailCall(bool (K::* method)(MArgs...)const,Args &&...args) const70 void mayFailCall(bool (K::*method)(MArgs...) const, Args &&... args) const
71 {
72 wrapCall<bool>(*this, method, std::forward<Args>(args)...);
73 }
74
75 /** Wrap a method that may fail to throw an Exception instead of retuning a
76 * boolean.
77 *
78 * @param[in] method that return a boolean to indicate failure.
79 * @param[in] args parameters to call method call with. */
80 template <class K, class... MArgs, class... Args>
mayFailCall(bool (K::* method)(MArgs...),Args &&...args)81 void mayFailCall(bool (K::*method)(MArgs...), Args &&... args)
82 {
83 wrapCall<bool>(*this, method, std::forward<Args>(args)...);
84 }
85
86 /** Wrap a method that may indicate failure by returning a null pointer to
87 * throw an Exception instead of retuning a null pointer.
88 *
89 * @param[in] method that return a nullprt to indicate failure.
90 * @param[in] args parameters to call method call with. */
91 template <class K, class ReturnType, class... MArgs, class... Args>
mayFailCall(ReturnType * (K::* method)(MArgs...),Args &&...args)92 ReturnType *mayFailCall(ReturnType *(K::*method)(MArgs...), Args &&... args)
93 {
94 return wrapCall<ReturnType *>(*this, method, std::forward<Args>(args)...);
95 }
96
97 /** Wrap a const method that may indicate failure by returning a null pointer to
98 * throw an Exception instead of retuning a null pointer.
99 *
100 * @param[in] method that return a nullprt to indicate failure.
101 * @param[in] args parameters to call method call with. */
102 template <class K, class ReturnType, class... MArgs, class... Args>
mayFailCall(ReturnType * (K::* method)(MArgs...)const,Args &&...args) const103 ReturnType *mayFailCall(ReturnType *(K::*method)(MArgs...) const, Args &&... args) const
104 {
105 return wrapCall<ReturnType *>(*this, method, std::forward<Args>(args)...);
106 }
107
108 /** Wrap a getter to return by value and throw an exception on failure. */
109 template <class K, class Value>
mayFailGet(bool (K::* accessor)(Value &,std::string &)const) const110 Value mayFailGet(bool (K::*accessor)(Value &, std::string &) const) const
111 {
112 Value value;
113 wrapCall<bool>(*this, accessor, value);
114 return value;
115 }
116
117 /** Wrap a setter to throw an exception on failure instead of returning a boolean. */
118 template <class K, class Value>
mayFailSet(bool (K::* accessor)(const Value &,std::string &),const Value & value)119 void mayFailSet(bool (K::*accessor)(const Value &, std::string &), const Value &value)
120 {
121 wrapCall<bool>(*this, accessor, value);
122 }
123
124 private:
125 template <class Ret, class I, class M, class... Args>
wrapCall(I & instance,M method,Args &&...args)126 static Ret wrapCall(I &instance, M method, Args &&... args)
127 {
128 std::string error;
129 auto res = (instance.*method)(std::forward<Args>(args)..., error);
130 if (not details::successTest(res)) {
131 throw Exception(std::move(error));
132 }
133 return res;
134 }
135 };
136 } // namespace parameterFramework
137