• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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