1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_BASE_FUNCTION_H_
28 #define EMBB_BASE_FUNCTION_H_
29 
30 /**
31  * \defgroup CPP_BASE_FUNCTION Function
32  * %Function wrapper and binding of parameters.
33  *
34  * \ingroup CPP_BASE
35  */
36 
37 namespace embb {
38 namespace base {
39 
40 /**
41  * Provides placeholders for Function arguments used in Bind()
42  *
43  * \ingroup CPP_BASE_FUNCTION
44  */
45 class Placeholder {
46  public:
47   class Arg_1 {};
48   class Arg_2 {};
49   class Arg_3 {};
50   class Arg_4 {};
51   class Arg_5 {};
52 
53   /**
54    * Placeholder variable to be used in Bind() for keeping one argument unbound
55    */
56   static Arg_1 _1;
57 
58   /**
59    * Placeholder variable to be used in Bind() for keeping one argument unbound
60    */
61   static Arg_2 _2;
62 
63   /**
64    * Placeholder variable to be used in Bind() for keeping one argument unbound
65    */
66   static Arg_3 _3;
67 
68   /**
69    * Placeholder variable to be used in Bind() for keeping one argument unbound
70    */
71   static Arg_4 _4;
72 
73   /**
74    * Placeholder variable to be used in Bind() for keeping one argument unbound
75    */
76   static Arg_5 _5;
77 };
78 
79 } // namespace base
80 } // namespace embb
81 
82 #ifdef DOXYGEN
83 
84 namespace embb {
85 namespace base {
86 
87 /**
88  * Wraps function pointers, member function pointers, and functors with up to
89  * five arguments.
90  *
91  * \ingroup CPP_BASE_FUNCTION
92  */
93 template <typename ReturnType, ...>
94 class Function {
95  public:
96   /**
97    * Constructor from functor. Uses operator() with return type ReturnType
98    * and up to five arguments. Copies the functor.
99    * \memory Allocates memory for the copy of the functor.
100    */
101   template <class ClassType>
102   explicit Function(
103     ClassType const & obj              /**< The functor to wrap. */
104     );
105 
106   /**
107    * Constructor from function pointer with return type ReturnType and up to
108    * five arguments.
109    */
110   explicit Function(
111     ReturnType(*func)(...)             /**< The function pointer. */
112     );
113 
114   /**
115    * Constructor from object and member function pointer with return type
116    * ReturnType and up to five arguments.
117    */
118   template <class ClassType>
119   Function(
120     ClassType & obj,                   /**< Reference to object. */
121     ReturnType(ClassType::*func)(...)
122                                        /**< Member function pointer. */
123     );
124 
125   /**
126    * Copy constructor.
127    */
128   Function(
129     Function const & func              /**< The Function to copy. */
130     );
131 
132   /**
133    * Destructor.
134    */
135   ~Function();
136 
137   /**
138    * Assigns this object a new function pointer.
139    */
140   void operator = (
141     ReturnType(*func)(...)             /**< The function pointer. */
142     );
143 
144   /**
145    * Assigns this object another Function.
146    */
147   void operator = (
148     Function & func                    /**< The Function. */
149     );
150 
151   /**
152    * Assigns this object a new functor. The functor is copied.
153    */
154   template <class C>
155   void operator = (
156     C const & obj                      /**< The functor. */
157     );
158 
159   /**
160    * Calls the wrapped function with the given parameters.
161    * \returns A value generated by the wrapped function.
162    */
163   ReturnType operator () (...);
164 };
165 
166 /**
167  * Wraps an object and a member function pointer into a Function
168  *
169  * \returns Function with same return value and argument syntax as \c func
170  * \see Function
171  * \tparam ClassType Class that contains the member function pointed to by \c
172  *         func.
173  * \tparam ReturnType Return type of member function pointed to by \c func
174  * \tparam [Arg1,...,Arg5] (Optional) Types of up to five arguments of the
175  *         member function
176  * \ingroup CPP_BASE_FUNCTION
177  */
178 template <class ClassType, typename ReturnType, ...>
179 Function<ReturnType, [Arg1, ..., Arg5]> MakeFunction(
180   ClassType& obj,
181   /**< [IN] Reference to the object with corresponding member function */
182   ReturnType(ClassType::*func)([Arg1, ..., Arg5])
183   /**< [IN] Member function pointer with up to five optional arguments */
184   );
185 
186 /**
187  * Wraps a function pointer into a Function
188  *
189  * \returns Function with same return value and argument syntax as \c func
190  * \see Function
191  * \tparam ReturnType Return type of member function pointed to by \c func.
192  * \tparam [Arg1,...,Arg5] (Optional) Types of up to five arguments of the
193  *         member function
194  * \ingroup CPP_BASE_FUNCTION
195  */
196 template <typename ReturnType, ...>
197 Function<ReturnType, [Arg1, ..., Arg5]> MakeFunction(
198   ReturnType(*func)([Arg1, ..., Arg5])
199   /**< [IN] Function pointer with up to five optional arguments */
200   );
201 
202 /**
203  * Binds given values as arguments of \c func into a new Function
204  *
205  * The new Function has no arguments or one, if Placeholder::_1 is
206  * given as one of the values. The position of Placeholder::_1 determines which
207  * argument of \c func is not bound.
208  * \memory Allocates dynamic memory to hold the parameters.
209  * \returns Function that uses given values as parameters
210  * \see Placeholder, Function
211  * \tparam ReturnType Return type of \c func and parameterless function returned
212  * \tparam [UnboundArgument] Type of not bound argument of \c func, only present
213  *         when a placeholder is used as value in the bind.
214  * \tparam Arg1[,...,Arg5] Types of up to five arguments of the values to bind
215  * \ingroup CPP_BASE_FUNCTION
216  */
217 template <typename ReturnType, UnboundArgument, Arg1, ...>
218 Function<ReturnType[, UnboundArgument]> Bind(
219   Function<ReturnType, Arg1[, ..., Arg5]> func,
220   /**< [IN] The Function to bind the values (\c value1, ...) to */
221   Arg1 value1,
222   /**< [IN] At least one and up to five values to bind as arguments of \c func.
223             Placeholder::_1 can be used instead of one of the values to keep the
224             corresponding argument of \c func unbound. */
225   ...
226   );
227 
228 } // namespace base
229 } // namespace embb
230 
231 #else // DOXYGEN
232 
233 #include <embb/base/internal/function0.h>
234 #include <embb/base/internal/function1.h>
235 #include <embb/base/internal/function2.h>
236 #include <embb/base/internal/function3.h>
237 #include <embb/base/internal/function4.h>
238 #include <embb/base/internal/function5.h>
239 
240 #endif // DOXYGEN
241 
242 #endif // EMBB_BASE_FUNCTION_H_
243