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 41 static inline bool successTest(bool res) 42 { 43 return res; 44 } 45 46 template <class T> 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> 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> 70 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> 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> 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> 103 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> 110 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> 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> 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 } // parameterFramework 137