Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/libraries/core/command/Functor.h @ 10876

Last change on this file since 10876 was 10876, checked in by muemart, 8 years ago

Use variadic templates for Functor
Had to put on my template hat for this one… The only thing preventing it from supporting more than five parameters is the complete type erasure (see operator())
I also had to use type_index because you can't store type_info, so I changed the other functions too for consistency's sake

  • Property svn:eol-style set to native
File size: 30.2 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @ingroup Command FunctorExecutor
32    @brief Definition of orxonox::Functor and its specialized subclasses, as well as the createFunctor() functions.
33
34    @anchor FunctorExample
35
36    Functors can be used to wrap function-pointers. While function-pointers have a very
37    complicated syntax in C++, Functors are always the same and you can call the wrapped
38    function-pointer independently of its parameter with arguments of type MultiType. These
39    arguments are then automatically converted to the right type.
40
41    To create a Functor, the helper function createFunctor() is used. It returns an instance
42    of orxonox::FunctorPtr which is simply a typedef of "std::shared_ptr<Functor>". This
43    means you don't have to delete the Functor after using it, because it is managed
44    by the std::shared_ptr.
45
46    Example:
47    @code
48    int myStaticFunction(int value)                         // Definition of a static function
49    {
50        return (value * 2);                                 // Return the double of the value
51    }
52
53    FunctorPtr functor = createFunctor(&myStaticFunction);  // Create a Functor
54
55    int result = (*functor)(5);                             // Calls the functor with value = 5, result == 10
56
57    int result = (*functor)("7");                           // Calls the functor with a string which is converted to an integer, result == 14
58    @endcode
59
60    Functors can also be used if you work with member-functions. In this case createFunctor()
61    returns an instance of orxonox::FunctorMemberPtr - this allows you to define the object
62    that will be used to call the function.
63
64    Example:
65    @code
66    class MyClass                                                   // Define a class
67    {
68        public:
69            MyClass(const std::string& text)                        // Constructor
70            {
71                this->text_ = text;
72            }
73
74            bool contains(const std::string& word)                  // Function that searches for "word" in "text"
75            {
76                return (this->text_.find(word) != std::string::npos);
77            }
78
79        private:
80            std::string text_;                                      // Member variable
81    };
82
83    MyClass* object = new MyClass("Hello World");                   // Create an object of type MyClass and set its text to "Hello World"
84
85    FunctorPtr functor = createFunctor(&MyClass:contains, object);  // Create a Functor (note the object!)
86
87    bool result = (*functor)("World");                              // result == true
88    bool result = (*functor)("test");                               // result == false
89    @endcode
90
91    Instead of assigning the object directly to the functor when creating it, you can also define
92    it at any later point or when you call the functor. Note however that this works only with
93    orxonox::FunctorMember.
94
95    @code
96    MyClass* object1 = new MyClass("Hello World");                  // Create an object
97    MyClass* object2 = new MyClass("this is a test");               // Create another object
98
99    FunctorMemberPtr functor = createFunctor(&MyClass:contains);    // Create a FunctorMember (note: no object this time)
100
101    bool result = (*functor)("World");                              // result == false and an error: "Error: Can't execute FunctorMember, no object set."
102
103    bool result = (*functor)(object1, "World");                     // result == true
104    bool result = (*functor)(object1, "test");                      // result == false
105    bool result = (*functor)(object2, "test");                      // result == true
106
107    functor->setObject(object1);                                    // Assign an object to the FunctorMember
108
109    bool result = (*functor)("World");                              // result == true (no error this time, because the object was set using setObject())
110    @endcode
111*/
112
113#ifndef _Functor_H__
114#define _Functor_H__
115
116#include "core/CorePrereqs.h"
117
118#include <array>
119#include <typeindex>
120#include <tuple>
121
122#include "util/Output.h"
123#include "util/MultiType.h"
124#include "core/object/Destroyable.h"
125#include "FunctorPtr.h"
126
127namespace orxonox
128{
129    const unsigned int MAX_FUNCTOR_ARGUMENTS = 5;   ///< The maximum number of parameters of a function that is supported by Functor
130
131    namespace detail
132    {
133        template <class T>
134        inline std::string _typeToString() { return "unknown"; }
135
136        template <> inline std::string _typeToString<void>()               { return "void"; }
137        template <> inline std::string _typeToString<int>()                { return "int"; }
138        template <> inline std::string _typeToString<unsigned int>()       { return "uint"; }
139        template <> inline std::string _typeToString<char>()               { return "char"; }
140        template <> inline std::string _typeToString<unsigned char>()      { return "uchar"; }
141        template <> inline std::string _typeToString<short>()              { return "short"; }
142        template <> inline std::string _typeToString<unsigned short>()     { return "ushort"; }
143        template <> inline std::string _typeToString<long>()               { return "long"; }
144        template <> inline std::string _typeToString<unsigned long>()      { return "ulong"; }
145        template <> inline std::string _typeToString<long long>()          { return "longlong"; }
146        template <> inline std::string _typeToString<unsigned long long>() { return "ulonglong"; }
147        template <> inline std::string _typeToString<float>()              { return "float"; }
148        template <> inline std::string _typeToString<double>()             { return "double"; }
149        template <> inline std::string _typeToString<long double>()        { return "longdouble"; }
150        template <> inline std::string _typeToString<bool>()               { return "bool"; }
151        template <> inline std::string _typeToString<std::string>()        { return "string"; }
152        template <> inline std::string _typeToString<Vector2>()            { return "Vector2"; }
153        template <> inline std::string _typeToString<Vector3>()            { return "Vector3"; }
154        template <> inline std::string _typeToString<Quaternion>()         { return "Quaternion"; }
155        template <> inline std::string _typeToString<ColourValue>()        { return "ColourValue"; }
156        template <> inline std::string _typeToString<Radian>()             { return "Radian"; }
157        template <> inline std::string _typeToString<Degree>()             { return "Degree"; }
158    }
159
160    /// Returns the name of type @a T as string.
161    template <class T>
162    inline std::string typeToString() { return detail::_typeToString<typename Loki::TypeTraits<T>::UnqualifiedReferredType>(); }
163
164    /**
165        @brief The Functor classes are used to wrap function pointers.
166
167        Function-pointers in C++ have a pretty complicated syntax and you can't store
168        and call them unless you know the exact type. A Functor can be used to wrap
169        a function-pointer and to store it independent of its type. You can also call
170        it independently of its parameters by passing the arguments as MultiType. They
171        are converted automatically to the right type.
172
173        Functor is a pure virtual base class.
174
175        @see See @ref FunctorExample "Functor.h" for some examples.
176    */
177    class _CoreExport Functor
178    {
179        public:
180            struct Type
181            {
182                /// Defines the type of a function (static or member)
183                enum Enum
184                {
185                    Static,
186                    Member
187                };
188            };
189
190        public:
191            virtual ~Functor() {}
192
193            /// Calls the function-pointer with up to five arguments. In case of a member-function, the assigned object-pointer is used to call the function. @return Returns the return-value of the function (if any; MultiType::Null otherwise)
194            virtual MultiType operator()(const MultiType& param1 = MultiType::Null, const MultiType& param2 = MultiType::Null, const MultiType& param3 = MultiType::Null, const MultiType& param4 = MultiType::Null, const MultiType& param5 = MultiType::Null) = 0;
195
196            /// Creates a new instance of Functor with the same values like this (used instead of a copy-constructor)
197            virtual FunctorPtr clone() = 0;
198
199            /// Returns the type of the function: static or member.
200            virtual Type::Enum getType() const = 0;
201            /// Returns the number of parameters of the function.
202            virtual unsigned int getParamCount() const = 0;
203            /// Returns true if the function has a return-value.
204            virtual bool hasReturnvalue() const = 0;
205
206            /// Returns the type-name of the parameter with given index (the first parameter has index 0).
207            virtual std::string getTypenameParam(unsigned int index) const = 0;
208            /// Returns the type-name of the return-value.
209            virtual std::string getTypenameReturnvalue() const = 0;
210
211            /// Converts a given argument to the type of the parameter with given index (the first parameter has index 0).
212            virtual void evaluateArgument(unsigned int index, MultiType& argument) const = 0;
213
214            /// Assigns an object-pointer to the functor which is used to execute a member-function.
215            virtual void setRawObjectPointer(void* object) = 0;
216            /// Returns the object-pointer.
217            virtual void* getRawObjectPointer() const = 0;
218
219            /// Enables or disables the safe mode which causes the functor to change the object pointer to nullptr if the object is deleted (only member functors).
220            virtual void setSafeMode(bool bSafeMode) = 0;
221
222            /// Returns the full identifier of the function-pointer which is defined as typeid(@a F), where @a F is the type of the stored function-pointer. Used to compare functors.
223            virtual const std::type_index getFullIdentifier() const = 0;
224            /// Returns an identifier of the header of the function (doesn't include the function's class). Used to compare functors.
225            virtual const std::type_index getHeaderIdentifier() const = 0;
226            /// Returns an identifier of the header of the function (doesn't include the function's class), but regards only the first @a params parameters. Used to compare functions if an Executor provides default-values for the other parameters.
227            virtual const std::type_index getHeaderIdentifier(unsigned int params) const = 0;
228    };
229
230    /**
231        @brief FunctorMember is a child class of Functor and expands it with an object-pointer, that
232        is used for member-functions, as well as an overloaded execution operator.
233
234        @param O The type of the function's class (or void if it's a static function)
235
236        Note that FunctorMember is also used for static functions, but with T = void. FunctorStatic
237        is a typedef of FunctorMember<void>. The void* object-pointer is ignored in this case.
238
239        @see See @ref FunctorExample "Functor.h" for some examples.
240    */
241    template <class O>
242    class FunctorMember : public Functor, public DestructionListener
243    {
244        public:
245            /// Constructor: Stores the object-pointer.
246            FunctorMember(O* object = nullptr) : object_(object), bSafeMode_(false) {}
247            virtual ~FunctorMember() { if (this->bSafeMode_) { this->unregisterObject(this->object_); } }
248
249            /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be nullptr. @return Returns the return-value of the function (if any; MultiType::Null otherwise)
250            virtual MultiType operator()(O* object, const MultiType& param1 = MultiType::Null, const MultiType& param2 = MultiType::Null, const MultiType& param3 = MultiType::Null, const MultiType& param4 = MultiType::Null, const MultiType& param5 = MultiType::Null) = 0;
251
252            // see Functor::operator()()
253            virtual MultiType operator()(const MultiType& param1 = MultiType::Null, const MultiType& param2 = MultiType::Null, const MultiType& param3 = MultiType::Null, const MultiType& param4 = MultiType::Null, const MultiType& param5 = MultiType::Null) override
254            {
255                // call the function if an object was assigned
256                if (this->object_)
257                    return (*this)(this->object_, param1, param2, param3, param4, param5);
258                else
259                {
260                    orxout(internal_error) << "Can't execute FunctorMember, no object set." << endl;
261                    return MultiType::Null;
262                }
263            }
264
265            // see Functor::getType()
266            virtual inline Functor::Type::Enum getType() const override
267                { return Functor::Type::Member; }
268
269            /// Assigns an object-pointer to the functor which is used to execute a member-function.
270            inline void setObject(O* object)
271            {
272                if (this->bSafeMode_ && object != this->object_)
273                {
274                    this->unregisterObject(this->object_);
275                    this->registerObject(object);
276                }
277                this->object_ = object;
278            }
279            /// Returns the object-pointer.
280            inline O* getObject() const
281                { return this->object_; }
282
283            // see Functor::setRawObjectPointer()
284            virtual inline void setRawObjectPointer(void* object) override
285                { this->setObject((O*)object); }
286            // see Functor::getRawObjectPointer()
287            virtual inline void* getRawObjectPointer() const override
288                { return this->object_; }
289
290            // see Functor::setSafeMode()
291            virtual inline void setSafeMode(bool bSafeMode) override
292            {
293                if (bSafeMode == this->bSafeMode_)
294                    return;
295
296                this->bSafeMode_ = bSafeMode;
297
298                if (bSafeMode)
299                    this->registerObject(this->object_);
300                else
301                    this->unregisterObject(this->object_);
302            }
303
304        protected:
305            /// Casts the object and registers as destruction listener.
306            inline void registerObject(O* object)
307                { Destroyable* base = dynamic_cast<Destroyable*>(object); if (base) { this->registerAsDestructionListener(base); } }
308            /// Casts the object and unregisters as destruction listener.
309            inline void unregisterObject(O* object)
310                { Destroyable* base = dynamic_cast<Destroyable*>(object); if (base) { this->unregisterAsDestructionListener(base); } }
311
312            /// Will be called by Destroyable::~Destroyable() if the stored object is deleted and the Functor is in safe mode.
313            virtual inline void objectDeleted() override
314                { this->object_ = nullptr; }
315
316            O* object_;     ///< The stored object-pointer, used to execute a member-function (or nullptr for static functions)
317            bool bSafeMode_; ///< If true, the functor is in safe mode and registers itself as listener at the object and changes the pointer to nullptr if the object is deleted
318    };
319
320    /// Specialization of FunctorMember with @a T = void.
321    template <>
322    class FunctorMember<void> : public Functor
323    {
324        public:
325            /// Constructor: Stores the object-pointer.
326            FunctorMember(void* object = nullptr) {}
327
328            /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be nullptr. @return Returns the return-value of the function (if any; MultiType::Null otherwise)
329            virtual MultiType operator()(void* object, const MultiType& param1 = MultiType::Null, const MultiType& param2 = MultiType::Null, const MultiType& param3 = MultiType::Null, const MultiType& param4 = MultiType::Null, const MultiType& param5 = MultiType::Null) = 0;
330
331            // see Functor::operator()()
332            virtual MultiType operator()(const MultiType& param1 = MultiType::Null, const MultiType& param2 = MultiType::Null, const MultiType& param3 = MultiType::Null, const MultiType& param4 = MultiType::Null, const MultiType& param5 = MultiType::Null) override
333            {
334                return (*this)((void*)nullptr, param1, param2, param3, param4, param5);
335            }
336
337            // see Functor::getType()
338            virtual inline Functor::Type::Enum getType() const override
339                { return Functor::Type::Static; }
340
341            // see Functor::setRawObjectPointer()
342            virtual inline void setRawObjectPointer(void*) override
343                { orxout(internal_warning) << "Can't assign an object pointer to a static functor" << endl; }
344            // see Functor::getRawObjectPointer()
345            virtual inline void* getRawObjectPointer() const override
346                { return nullptr; }
347
348            // see Functor::setSafeMode()
349            virtual inline void setSafeMode(bool) override {}
350    };
351
352    /// FunctorStatic is just a typedef of FunctorMember with @a T = void.
353    typedef FunctorMember<void> FunctorStatic;
354
355    /**
356        @brief FunctorPointer is a child class of FunctorMember and expands it with a function-pointer.
357        @param F The type of the function-pointer
358        @param O The type of the function's class (or void if it's a static function)
359
360        The template FunctorPointer has an additional template parameter that defines the type
361        of the function-pointer. This can be handy if you want to get or set the function-pointer.
362        You can then use a static_cast to cast a Functor to FunctorPointer if you know the type
363        of the function-pointer.
364
365        However FunctorPointer is not aware of the types of the different parameters or the
366        return value.
367    */
368    template <class F, class O = void>
369    class FunctorPointer : public FunctorMember<O>
370    {
371        public:
372            /// Constructor: Initializes the base class and stores the function-pointer.
373            FunctorPointer(F functionPointer, O* object = nullptr) : FunctorMember<O>(object), functionPointer_(functionPointer) {}
374
375            /// Changes the function-pointer.
376            inline void setFunction(F functionPointer)
377                { this->functionPointer_ = functionPointer; }
378            /// Returns the function-pointer.
379            inline F getFunction() const
380                { return this->functionPointer_; }
381
382            // see Functor::getFullIdentifier()
383            const std::type_index getFullIdentifier() const
384                { return typeid(F); }
385
386        protected:
387            F functionPointer_;     ///< The stored function-pointer
388    };
389
390    namespace detail
391    {
392        // Helper class to get the type of the function pointer with the given class, parameters, return-value, and constness
393        template <class R, class O, bool isconst, class... Params> struct FunctionPointer                                   { typedef R (O::*Type)(Params...); };
394        template <class R, class O, class... Params>               struct FunctionPointer<R, O, true, Params...>            { typedef R (O::*Type)(Params...) const; };
395        template <class R, class... Params>                        struct FunctionPointer<R, void, false, Params...>        { typedef R (*Type)(Params...); };
396
397        // Helper class, used to call a function-pointer with a given object and parameters and to return its return-value (if available)
398        template <class R, class O, bool isconst, class... Params>         struct FunctorCaller                                        { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, Params...>::Type functionPointer, O* object, const Params&... parameters)    { return (object->*functionPointer)(parameters...); } };
399        template <class O, bool isconst, class... Params>                  struct FunctorCaller<void, O, isconst, Params...>           { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, Params...>::Type functionPointer, O* object, const Params&... parameters) { (object->*functionPointer)(parameters...); return MultiType::Null; } };
400        template <class R, bool isconst, class... Params>                  struct FunctorCaller<R, void, isconst, Params...>           { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, Params...>::Type functionPointer, void*, const Params&... parameters)     { return (*functionPointer)(parameters...); } };
401        template <bool isconst, class... Params>                           struct FunctorCaller<void, void, isconst, Params...>        { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, Params...>::Type functionPointer, void*, const Params&... parameters)  { (*functionPointer)(parameters...); return MultiType::Null; } };
402
403        // Helper class, used to identify the header of a function-pointer (independent of its class)
404        template <class R, class... Params>
405        struct FunctorHeaderIdentifier
406        {};
407
408        // Helper class to determine if a function has a returnvalue
409        template <class T>
410        struct FunctorHasReturnvalue
411        { enum { result = true }; };
412        template <>
413        struct FunctorHasReturnvalue<void>
414        { enum { result = false }; };
415
416        //Barebones implementation of (make_)index_sequence for C++11
417        template <std::size_t...> struct index_sequence {};
418
419        template <std::size_t N, std::size_t... Is>
420        struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {};
421
422        template <std::size_t... Is>
423        struct make_index_sequence<0u, Is...> : index_sequence<Is...> {};
424
425        //Helper structs to deduce the first N types of a parameter pack
426        template<class... Types> struct type_list {};
427
428        template <class T1, class... AllTypes>
429        struct make_type_list_helper
430        {
431            template <std::size_t N, class... Types>
432            struct make_type_list_impl : make_type_list_helper<AllTypes...>::template make_type_list_impl<N - 1, Types..., T1> {};
433
434            template <class... Types>
435            struct make_type_list_impl<1u, Types...> : type_list<Types..., T1> {};
436        };
437
438        template <std::size_t N, class... Types>
439        struct make_type_list : make_type_list_helper<Types...>::template make_type_list_impl<N> {};
440
441        template <class... Types>
442        struct make_type_list<0u, Types...> : type_list<> {};
443    }
444
445    /**
446        @brief FunctorTemplate is a child class of FunctorPointer and implements all functions
447        that need to know the exact types of the parameters, return-value, and class.
448
449        @param R The type of the return-value of the function
450        @param O The class of the function
451        @param isconst True if the function is a const member-function
452        @param P1 The type of the first parameter
453        @param P2 The type of the second parameter
454        @param P3 The type of the third parameter
455        @param P4 The type of the fourth parameter
456        @param P5 The type of the fifth parameter
457
458        This template has many parameters and is usually not used directly. It is created by
459        createFunctor(), but only the base-classes Functor, FunctorMember, and FunctorPointer
460        are used directly. It implements all the virtual functions that are declared by its
461        base classes.
462
463        All template arguments can be void.
464    */
465    template <class R, class O, bool isconst, class... Params>
466    class FunctorTemplate : public FunctorPointer<typename detail::FunctionPointer<R, O, isconst, Params...>::Type, O>
467    {
468        static_assert(sizeof...(Params) <= 5, "Only up to 5 parameters are supported");
469
470        public:
471            /// Constructor: Initializes the base class.
472            FunctorTemplate(typename detail::FunctionPointer<R, O, isconst, Params...>::Type functionPointer, O* object = nullptr) : FunctorPointer<typename detail::FunctionPointer<R, O, isconst, Params...>::Type, O>(functionPointer, object) {}
473
474            // see FunctorMember::operator()()
475            virtual MultiType operator()(O* object, const MultiType& param1 = MultiType::Null, const MultiType& param2 = MultiType::Null, const MultiType& param3 = MultiType::Null, const MultiType& param4 = MultiType::Null, const MultiType& param5 = MultiType::Null) override
476            {
477                auto multis = std::make_tuple(param1, param2, param3, param4, param5);
478                return callHelper(object, multis, detail::make_index_sequence<sizeof...(Params)>{});
479            }
480
481            // see Functor::clone()
482            virtual FunctorPtr clone() override
483            {
484                return std::make_shared<FunctorTemplate>(*this);
485            }
486
487            // see Functor::evaluateArgument()
488            virtual void evaluateArgument(unsigned int index, MultiType& argument) const override
489            {
490                static const std::array<std::function<bool(MultiType&)>, sizeof...(Params)> funcs = {&MultiType::convert<Params>...};
491                if (index < funcs.size())
492                {
493                    funcs[index](argument);
494                }
495            }
496
497            // see Functor::getParamCount()
498            virtual unsigned int getParamCount() const override
499            {
500                return sizeof...(Params);
501            }
502
503            // see Functor::hasReturnvalue()
504            virtual bool hasReturnvalue() const override
505            {
506                return detail::FunctorHasReturnvalue<R>::result;
507            }
508
509            // see Functor::getTypenameParam()
510            virtual std::string getTypenameParam(unsigned int index) const override
511            {
512                static const std::array<std::string, sizeof...(Params)> names = { typeToString<Params>()... };
513                if (index >= names.size())
514                {
515                    return "";
516                }
517                return names[index];
518            }
519
520            // see Functor::getTypenameReturnvalue()
521            virtual std::string getTypenameReturnvalue() const override
522            {
523                return typeToString<R>();
524            }
525
526            // see Functor::getHeaderIdentifier()
527            virtual const std::type_index getHeaderIdentifier() const override
528            {
529                return typeid(detail::FunctorHeaderIdentifier<R, Params...>);
530            }
531
532            // see Functor::getHeaderIdentifier(unsigned int)
533            virtual const std::type_index getHeaderIdentifier(unsigned int params) const override
534            {
535                //+1 because e.g. for two parameters, we want typeids for zero, one, or two parameters
536                return getHeaderIdentifierHelper(params, detail::make_index_sequence<sizeof...(Params) + 1>{});
537            }
538
539    private:
540
541            /// Helper function that extracts index numbers of parameters from a tuple. Needed to call the function pointer with the correct amount of arguments.
542            template<typename Tup, std::size_t... index>
543            MultiType callHelper(O* object, Tup&& tup, detail::index_sequence<index...>)
544            {
545                return detail::FunctorCaller<R, O, isconst, Params...>::call(this->functionPointer_, object, std::get<index>(std::forward<Tup>(tup))...);
546            }
547
548            /// Helper function to extract all identifiers of the function pointer using a deduced index sequence
549            template<std::size_t... index>
550            const std::type_index& getHeaderIdentifierHelper(unsigned int params, detail::index_sequence<index...>) const
551            {
552                static const std::array<const std::type_index, sizeof...(index)> typeinfos = { getTypelistIdentifier(detail::make_type_list<index, Params...>{})... };
553                if (params >= typeinfos.size())
554                {
555                    return typeinfos.back();
556                }
557                return typeinfos[params];
558            }
559
560            ///Helper function that deduces a parameter pack of types and returns the corresponding identifier
561            template<class... Types>
562            const std::type_index getTypelistIdentifier(detail::type_list<Types...>) const
563            {
564                return typeid(detail::FunctorHeaderIdentifier<R, Types...>);
565            }
566    };
567
568    template <class R, class O, class OO, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...), OO* object) { return std::make_shared<FunctorTemplate<R, O, false, Params...>>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
569    template <class R, class O, class OO, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...) const, OO* object) { return std::make_shared<FunctorTemplate<R, O, true, Params...>>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
570
571    template <class R, class O, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...)) { return std::make_shared<FunctorTemplate<R, O, false, Params...>>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
572    template <class R, class O, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...) const) { return std::make_shared<FunctorTemplate<R, O, true, Params...>>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
573
574    template <class R, class... Params> inline FunctorStaticPtr createFunctor(R (*functionPointer)(Params...)) { return std::make_shared<FunctorTemplate<R, void, false, Params...>>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
575}
576
577#endif /* _Functor_H__ */
Note: See TracBrowser for help on using the repository browser.