Home | History | Annotate | Download | only in include
      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