- Timestamp:
- Jan 10, 2016, 1:54:11 PM (8 years ago)
- Location:
- code/branches/cpp11_v3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/cpp11_v3
- Property svn:mergeinfo changed
-
code/branches/cpp11_v3/src/libraries/core/command/Functor.h
r9667 r11054 40 40 41 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 @ref orxonox::SharedPtr "SharedPtr<Functor>".43 Thismeans you don't have to delete the Functor after using it, because it is managed44 by the SharedPtr.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 45 46 46 Example: … … 187 187 188 188 public: 189 virtual ~Functor() {}189 virtual ~Functor() = default; 190 190 191 191 /// 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) … … 215 215 virtual void* getRawObjectPointer() const = 0; 216 216 217 /// Enables or disables the safe mode which causes the functor to change the object pointer to NULLif the object is deleted (only member functors).217 /// 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). 218 218 virtual void setSafeMode(bool bSafeMode) = 0; 219 219 … … 242 242 public: 243 243 /// Constructor: Stores the object-pointer. 244 FunctorMember(O* object = 0) : object_(object), bSafeMode_(false) {}244 FunctorMember(O* object = nullptr) : object_(object), bSafeMode_(false) {} 245 245 virtual ~FunctorMember() { if (this->bSafeMode_) { this->unregisterObject(this->object_); } } 246 246 247 /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be NULL. @return Returns the return-value of the function (if any; MultiType::Null otherwise)247 /// 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) 248 248 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; 249 249 250 250 // see Functor::operator()() 251 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)251 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 252 252 { 253 253 // call the function if an object was assigned … … 262 262 263 263 // see Functor::getType() 264 inline Functor::Type::Enum getType() const264 virtual inline Functor::Type::Enum getType() const override 265 265 { return Functor::Type::Member; } 266 266 … … 280 280 281 281 // see Functor::setRawObjectPointer() 282 inline void setRawObjectPointer(void* object)282 virtual inline void setRawObjectPointer(void* object) override 283 283 { this->setObject((O*)object); } 284 284 // see Functor::getRawObjectPointer() 285 inline void* getRawObjectPointer() const285 virtual inline void* getRawObjectPointer() const override 286 286 { return this->object_; } 287 287 288 288 // see Functor::setSafeMode() 289 inline void setSafeMode(bool bSafeMode)289 virtual inline void setSafeMode(bool bSafeMode) override 290 290 { 291 291 if (bSafeMode == this->bSafeMode_) … … 301 301 302 302 protected: 303 /// Casts the object and registers as destruction listener. 304 inline void registerObject(O* object) 305 { Destroyable* base = dynamic_cast<Destroyable*>(object); if (base) { this->registerAsDestructionListener(base); } } 306 /// Casts the object and unregisters as destruction listener. 307 inline void unregisterObject(O* object) 308 { Destroyable* base = dynamic_cast<Destroyable*>(object); if (base) { this->unregisterAsDestructionListener(base); } } 309 310 /// Will be called by Destroyable::~Destroyable() if the stored object is deleted and the Functor is in safe mode. 311 inline void objectDeleted() 312 { this->object_ = 0; } 313 314 O* object_; ///< The stored object-pointer, used to execute a member-function (or NULL for static functions) 315 bool bSafeMode_; ///< If true, the functor is in safe mode and registers itself as listener at the object and changes the pointer to NULL if the object is deleted 303 /// Casts the object and registers as destruction listener if the object is a Destroyable. 304 inline void registerObject(Destroyable* object) 305 { this->registerAsDestructionListener(object); } 306 307 inline void registerObject(void* object) {} 308 309 /// Casts the object and unregisters as destruction listener if the object is a Destroyable. 310 inline void unregisterObject(Destroyable* object) 311 { this->unregisterAsDestructionListener(object); } 312 313 inline void unregisterObject(void* object) {} 314 315 /// Will be called by Destroyable::~Destroyable() if the stored object is a Destroyable and deleted and the Functor is in safe mode. 316 virtual inline void objectDeleted() override 317 { this->object_ = nullptr; } 318 319 O* object_; ///< The stored object-pointer, used to execute a member-function (or nullptr for static functions) 320 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 316 321 }; 317 322 … … 322 327 public: 323 328 /// Constructor: Stores the object-pointer. 324 FunctorMember(void* object = 0) {}325 326 /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be NULL. @return Returns the return-value of the function (if any; MultiType::Null otherwise)329 FunctorMember(void* object = nullptr) {} 330 331 /// 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) 327 332 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; 328 333 329 334 // see Functor::operator()() 330 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)331 { 332 return (*this)((void*) 0, param1, param2, param3, param4, param5);335 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 336 { 337 return (*this)((void*)nullptr, param1, param2, param3, param4, param5); 333 338 } 334 339 335 340 // see Functor::getType() 336 inline Functor::Type::Enum getType() const341 virtual inline Functor::Type::Enum getType() const override 337 342 { return Functor::Type::Static; } 338 343 339 344 // see Functor::setRawObjectPointer() 340 inline void setRawObjectPointer(void*)345 virtual inline void setRawObjectPointer(void*) override 341 346 { orxout(internal_warning) << "Can't assign an object pointer to a static functor" << endl; } 342 347 // see Functor::getRawObjectPointer() 343 inline void* getRawObjectPointer() const344 { return 0; }348 virtual inline void* getRawObjectPointer() const override 349 { return nullptr; } 345 350 346 351 // see Functor::setSafeMode() 347 inline void setSafeMode(bool){}352 virtual inline void setSafeMode(bool) override {} 348 353 }; 349 354 … … 352 357 353 358 /** 354 @brief FunctorPointer is a child class of FunctorMember and ex pands it with a function-pointer.355 @param F The type of the function-pointer 356 @param O The type of the function's class (or void if it's a static function )359 @brief FunctorPointer is a child class of FunctorMember and extends it with a function-pointer (or a function-object). 360 @param F The type of the function-pointer (or the function-object) 361 @param O The type of the function's class (or void if it's a static function or a function-object) 357 362 358 363 The template FunctorPointer has an additional template parameter that defines the type 359 of the function-pointer . This can be handy if you want to get or set the function-pointer.360 You can then use a static_cast to cast a Functor to FunctorPointer if you know the type361 of the function-pointer.364 of the function-pointer (or the function-object). This can be handy if you want to get 365 or set the function-pointer (or the function-object). You can then use a static_cast 366 to cast a Functor to FunctorPointer if you know the type of the function. 362 367 363 368 However FunctorPointer is not aware of the types of the different parameters or the … … 369 374 public: 370 375 /// Constructor: Initializes the base class and stores the function-pointer. 371 FunctorPointer(F functionPointer, O* object = 0) : FunctorMember<O>(object), functionPointer_(functionPointer) {}376 FunctorPointer(F functionPointer, O* object = nullptr) : FunctorMember<O>(object), functionPointer_(functionPointer) {} 372 377 373 378 /// Changes the function-pointer. … … 378 383 { return this->functionPointer_; } 379 384 380 // see Functor::getFullIdentifier()381 const std::type_info& getFullIdentifier() const382 { return typeid(F); }383 384 385 protected: 385 386 F functionPointer_; ///< The stored function-pointer … … 388 389 namespace detail 389 390 { 390 // Helper class to get the type of the function pointer with the given class, parameters, return-value, and constness 391 template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctionPointer { typedef R (O::*Type)(P1, P2, P3, P4, P5); }; 392 template <class R, class O, class P1, class P2, class P3, class P4, class P5> struct FunctionPointer<R, O, false, P1, P2, P3, P4, P5> { typedef R (O::*Type)(P1, P2, P3, P4, P5); }; 393 template <class R, class O, class P1, class P2, class P3, class P4> struct FunctionPointer<R, O, false, P1, P2, P3, P4, void> { typedef R (O::*Type)(P1, P2, P3, P4); }; 394 template <class R, class O, class P1, class P2, class P3> struct FunctionPointer<R, O, false, P1, P2, P3, void, void> { typedef R (O::*Type)(P1, P2, P3); }; 395 template <class R, class O, class P1, class P2> struct FunctionPointer<R, O, false, P1, P2, void, void, void> { typedef R (O::*Type)(P1, P2); }; 396 template <class R, class O, class P1> struct FunctionPointer<R, O, false, P1, void, void, void, void> { typedef R (O::*Type)(P1); }; 397 template <class R, class O> struct FunctionPointer<R, O, false, void, void, void, void, void> { typedef R (O::*Type)(); }; 398 template <class R, class O, class P1, class P2, class P3, class P4, class P5> struct FunctionPointer<R, O, true, P1, P2, P3, P4, P5> { typedef R (O::*Type)(P1, P2, P3, P4, P5) const; }; 399 template <class R, class O, class P1, class P2, class P3, class P4> struct FunctionPointer<R, O, true, P1, P2, P3, P4, void> { typedef R (O::*Type)(P1, P2, P3, P4) const; }; 400 template <class R, class O, class P1, class P2, class P3> struct FunctionPointer<R, O, true, P1, P2, P3, void, void> { typedef R (O::*Type)(P1, P2, P3) const; }; 401 template <class R, class O, class P1, class P2> struct FunctionPointer<R, O, true, P1, P2, void, void, void> { typedef R (O::*Type)(P1, P2) const; }; 402 template <class R, class O, class P1> struct FunctionPointer<R, O, true, P1, void, void, void, void> { typedef R (O::*Type)(P1) const; }; 403 template <class R, class O> struct FunctionPointer<R, O, true, void, void, void, void, void> { typedef R (O::*Type)() const; }; 404 template <class R, class P1, class P2, class P3, class P4, class P5> struct FunctionPointer<R, void, false, P1, P2, P3, P4, P5> { typedef R (*Type)(P1, P2, P3, P4, P5); }; 405 template <class R, class P1, class P2, class P3, class P4> struct FunctionPointer<R, void, false, P1, P2, P3, P4, void> { typedef R (*Type)(P1, P2, P3, P4); }; 406 template <class R, class P1, class P2, class P3> struct FunctionPointer<R, void, false, P1, P2, P3, void, void> { typedef R (*Type)(P1, P2, P3); }; 407 template <class R, class P1, class P2> struct FunctionPointer<R, void, false, P1, P2, void, void, void> { typedef R (*Type)(P1, P2); }; 408 template <class R, class P1> struct FunctionPointer<R, void, false, P1, void, void, void, void> { typedef R (*Type)(P1); }; 409 template <class R> struct FunctionPointer<R, void, false, void, void, void, void, void> { typedef R (*Type)(); }; 410 411 // Helper class, used to call a function-pointer with a given object and parameters and to return its return-value (if available) 412 template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctorCaller { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { return (object->*functionPointer)(param1, param2, param3, param4, param5); } }; 413 template <class R, class O, bool isconst, class P1, class P2, class P3, class P4> struct FunctorCaller<R, O, isconst, P1, P2, P3, P4, void> { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType&) { return (object->*functionPointer)(param1, param2, param3, param4); } }; 414 template <class R, class O, bool isconst, class P1, class P2, class P3> struct FunctorCaller<R, O, isconst, P1, P2, P3, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, void, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType&, const MultiType&) { return (object->*functionPointer)(param1, param2, param3); } }; 415 template <class R, class O, bool isconst, class P1, class P2> struct FunctorCaller<R, O, isconst, P1, P2, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, P2, void, void, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType&, const MultiType&, const MultiType&) { return (object->*functionPointer)(param1, param2); } }; 416 template <class R, class O, bool isconst, class P1> struct FunctorCaller<R, O, isconst, P1, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, void, void, void, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { return (object->*functionPointer)(param1); } }; 417 template <class R, class O, bool isconst> struct FunctorCaller<R, O, isconst, void, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, void, void, void, void, void>::Type functionPointer, O* object, const MultiType&, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { return (object->*functionPointer)(); } }; 418 template <class O, bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctorCaller<void, O, isconst, P1, P2, P3, P4, P5> { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, P1, P2, P3, P4, P5>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { (object->*functionPointer)(param1, param2, param3, param4, param5); return MultiType::Null; } }; 419 template <class O, bool isconst, class P1, class P2, class P3, class P4> struct FunctorCaller<void, O, isconst, P1, P2, P3, P4, void> { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, P1, P2, P3, P4, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType&) { (object->*functionPointer)(param1, param2, param3, param4); return MultiType::Null; } }; 420 template <class O, bool isconst, class P1, class P2, class P3> struct FunctorCaller<void, O, isconst, P1, P2, P3, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, P1, P2, P3, void, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType&, const MultiType&) { (object->*functionPointer)(param1, param2, param3); return MultiType::Null; } }; 421 template <class O, bool isconst, class P1, class P2> struct FunctorCaller<void, O, isconst, P1, P2, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, P1, P2, void, void, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType&, const MultiType&, const MultiType&) { (object->*functionPointer)(param1, param2); return MultiType::Null; } }; 422 template <class O, bool isconst, class P1> struct FunctorCaller<void, O, isconst, P1, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, P1, void, void, void, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { (object->*functionPointer)(param1); return MultiType::Null; } }; 423 template <class O, bool isconst> struct FunctorCaller<void, O, isconst, void, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, void, void, void, void, void>::Type functionPointer, O* object, const MultiType&, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { (object->*functionPointer)(); return MultiType::Null; } }; 424 template <class R, bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctorCaller<R, void, isconst, P1, P2, P3, P4, P5> { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, P1, P2, P3, P4, P5>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { return (*functionPointer)(param1, param2, param3, param4, param5); } }; 425 template <class R, bool isconst, class P1, class P2, class P3, class P4> struct FunctorCaller<R, void, isconst, P1, P2, P3, P4, void> { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, P1, P2, P3, P4, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType&) { return (*functionPointer)(param1, param2, param3, param4); } }; 426 template <class R, bool isconst, class P1, class P2, class P3> struct FunctorCaller<R, void, isconst, P1, P2, P3, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, P1, P2, P3, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType&, const MultiType&) { return (*functionPointer)(param1, param2, param3); } }; 427 template <class R, bool isconst, class P1, class P2> struct FunctorCaller<R, void, isconst, P1, P2, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, P1, P2, void, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType&, const MultiType&, const MultiType&) { return (*functionPointer)(param1, param2); } }; 428 template <class R, bool isconst, class P1> struct FunctorCaller<R, void, isconst, P1, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, P1, void, void, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { return (*functionPointer)(param1); } }; 429 template <class R, bool isconst> struct FunctorCaller<R, void, isconst, void, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, void, void, void, void, void>::Type functionPointer, void*, const MultiType&, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { return (*functionPointer)(); } }; 430 template <bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctorCaller<void, void, isconst, P1, P2, P3, P4, P5> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, P1, P2, P3, P4, P5>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { (*functionPointer)(param1, param2, param3, param4, param5); return MultiType::Null; } }; 431 template <bool isconst, class P1, class P2, class P3, class P4> struct FunctorCaller<void, void, isconst, P1, P2, P3, P4, void> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, P1, P2, P3, P4, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType&) { (*functionPointer)(param1, param2, param3, param4); return MultiType::Null; } }; 432 template <bool isconst, class P1, class P2, class P3> struct FunctorCaller<void, void, isconst, P1, P2, P3, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, P1, P2, P3, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType&, const MultiType&) { (*functionPointer)(param1, param2, param3); return MultiType::Null; } }; 433 template <bool isconst, class P1, class P2> struct FunctorCaller<void, void, isconst, P1, P2, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, P1, P2, void, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType&, const MultiType&, const MultiType&) { (*functionPointer)(param1, param2); return MultiType::Null; } }; 434 template <bool isconst, class P1> struct FunctorCaller<void, void, isconst, P1, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, P1, void, void, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { (*functionPointer)(param1); return MultiType::Null; } }; 435 template <bool isconst> struct FunctorCaller<void, void, isconst, void, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, void, void, void, void, void>::Type functionPointer, void*, const MultiType&, const MultiType&, const MultiType&, const MultiType&, const MultiType&) { (*functionPointer)(); return MultiType::Null; } }; 436 437 // Helper class, used to identify the header of a function-pointer (independent of its class) 438 template <class R, class P1, class P2, class P3, class P4, class P5> 439 struct FunctorHeaderIdentifier 440 {}; 391 // Helper class to get the type of the function-pointer (or the function-object) with the given class, parameters, return-value, and constness 392 template <class F, class R, class O, bool isconst, class... Params> struct FunctionType /* generic type is undefined */; 393 template < class R, class O, class... Params> struct FunctionType<void, R, O, false, Params...> { typedef R (O::*Type)(Params...); }; // spezialization: non-const member function 394 template < class R, class O, class... Params> struct FunctionType<void, R, O, true, Params...> { typedef R (O::*Type)(Params...) const; }; // spezialization: const member function 395 template < class R, class... Params> struct FunctionType<void, R, void, false, Params...> { typedef R (*Type)(Params...); }; // spezialization: static function 396 template <class F, class R, class... Params> struct FunctionType<F, R, void, false, Params...> { typedef F Type; }; // spezialization: function object 397 398 // Helper class, used to call a function with a given object and parameters and to return its return-value (if available) 399 template <class F, class R, class O, bool isconst, class... Params> struct FunctorCaller /* generic type is undefined */; 400 template < class R, class O, bool isconst, class... Params> struct FunctorCaller<void, R, O, isconst, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionType<void, R, O, isconst, Params...>::Type functionPointer, O* object, const Params&... parameters, const UnusedParams&...) { return (object->*functionPointer)(parameters...); } }; // spezialization: member function with return value 401 template < class O, bool isconst, class... Params> struct FunctorCaller<void, void, O, isconst, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionType<void, void, O, isconst, Params...>::Type functionPointer, O* object, const Params&... parameters, const UnusedParams&...) { (object->*functionPointer)(parameters...); return MultiType::Null; } }; // spezialization: member function without return value 402 template < class R, class... Params> struct FunctorCaller<void, R, void, false, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionType<void, R, void, false, Params...>::Type functionPointer, void*, const Params&... parameters, const UnusedParams&...) { return (*functionPointer)(parameters...); } }; // spezialization: static function with return value 403 template < class... Params> struct FunctorCaller<void, void, void, false, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionType<void, void, void, false, Params...>::Type functionPointer, void*, const Params&... parameters, const UnusedParams&...) { (*functionPointer)(parameters...); return MultiType::Null; } }; // spezialization: static function without return value 404 template <class F, class R, class... Params> struct FunctorCaller<F, R, void, false, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionType<F, R, void, false, Params...>::Type functor, void*, const Params&... parameters, const UnusedParams&...) { return functor(parameters...); } }; // spezialization: function object with return value 405 template <class F, class... Params> struct FunctorCaller<F, void, void, false, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionType<F, void, void, false, Params...>::Type functor, void*, const Params&... parameters, const UnusedParams&...) { functor(parameters...); return MultiType::Null; } }; // spezialization: function object without return value 441 406 442 407 // Helper class to determine if a function has a returnvalue … … 448 413 { enum { result = false }; }; 449 414 450 // Helper class to count the number of parameters 451 template <class P1, class P2, class P3, class P4, class P5> 452 struct FunctorParamCount 453 { enum { result = 5 }; }; 454 template <class P1, class P2, class P3, class P4> 455 struct FunctorParamCount<P1, P2, P3, P4, void> 456 { enum { result = 4 }; }; 457 template <class P1, class P2, class P3> 458 struct FunctorParamCount<P1, P2, P3, void, void> 459 { enum { result = 3 }; }; 460 template <class P1, class P2> 461 struct FunctorParamCount<P1, P2, void, void, void> 462 { enum { result = 2 }; }; 463 template <class P1> 464 struct FunctorParamCount<P1, void, void, void, void> 465 { enum { result = 1 }; }; 415 // Helper class to determine the N-th parameter of a variadic template (with 0 being the index of the first parameter) 416 template <int n, typename T = void, typename... Other> 417 struct GetNthParamType 418 { typedef typename GetNthParamType<n - 1, Other...>::Type Type; }; 419 template <typename T, typename... Other> 420 struct GetNthParamType<0, T, Other...> 421 { typedef T Type; }; 422 423 // Helper structs to deduce the first N types of a parameter pack 424 template<class... Types> struct type_list {}; 425 426 template <class T1, class... AllTypes> 427 struct make_type_list_helper 428 { 429 template <std::size_t N, class... Types> 430 struct make_type_list_impl : make_type_list_helper<AllTypes...>::template make_type_list_impl<N - 1, Types..., T1> {}; 431 432 template <class... Types> 433 struct make_type_list_impl<1u, Types...> : type_list<Types..., T1> {}; 434 }; 435 436 template <class T1> 437 struct make_type_list_helper<T1> 438 { 439 template <std::size_t N, class... Types> 440 struct make_type_list_impl : type_list<Types..., T1> {}; 441 }; 442 443 template <std::size_t N, class... Types> 444 struct make_type_list : make_type_list_helper<Types...>::template make_type_list_impl<N> {}; 445 446 template <class... Types> 447 struct make_type_list<0u, Types...> : type_list<> {}; 448 449 template <std::size_t N> 450 struct make_type_list<N> : type_list<> {}; 451 466 452 template <> 467 struct FunctorParamCount<void, void, void, void, void> 468 { enum { result = 0 }; }; 453 struct make_type_list<0u> : type_list<> {}; 469 454 } 470 455 … … 473 458 that need to know the exact types of the parameters, return-value, and class. 474 459 460 @param F the type of the function-object (or void if a function-pointer is used). 475 461 @param R The type of the return-value of the function 476 462 @param O The class of the function 477 463 @param isconst True if the function is a const member-function 478 @param P1 The type of the first parameter 479 @param P2 The type of the second parameter 480 @param P3 The type of the third parameter 481 @param P4 The type of the fourth parameter 482 @param P5 The type of the fifth parameter 464 @param Params The types of the parameters 483 465 484 466 This template has many parameters and is usually not used directly. It is created by … … 489 471 All template arguments can be void. 490 472 */ 491 template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5> 492 class FunctorTemplate : public FunctorPointer<typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type, O> 493 { 473 template <class F, class R, class O, bool isconst, class... Params> 474 class FunctorTemplate : public FunctorPointer<typename detail::FunctionType<F, R, O, isconst, Params...>::Type, O> 475 { 476 static_assert(sizeof...(Params) <= 5, "Only up to 5 parameters are supported"); 477 494 478 public: 495 479 /// Constructor: Initializes the base class. 496 FunctorTemplate(typename detail::Function Pointer<R, O, isconst, P1, P2, P3, P4, P5>::Type functionPointer, O* object = 0) : FunctorPointer<typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type, O>(functionPointer, object) {}480 FunctorTemplate(typename detail::FunctionType<F, R, O, isconst, Params...>::Type functionPointer, O* object = nullptr) : FunctorPointer<typename detail::FunctionType<F, R, O, isconst, Params...>::Type, O>(functionPointer, object) {} 497 481 498 482 // see FunctorMember::operator()() 499 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)500 { 501 return detail::FunctorCaller< R, O, isconst, P1, P2, P3, P4, P5>::call(this->functionPointer_, object, param1, param2, param3, param4, param5);483 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 484 { 485 return detail::FunctorCaller<F, R, O, isconst, Params...>::call(this->functionPointer_, object, param1, param2, param3, param4, param5); 502 486 } 503 487 504 488 // see Functor::clone() 505 FunctorPtr clone()506 { 507 return new FunctorTemplate(*this);489 virtual FunctorPtr clone() override 490 { 491 return std::make_shared<FunctorTemplate>(*this); 508 492 } 509 493 510 494 // see Functor::evaluateArgument() 511 v oid evaluateArgument(unsigned int index, MultiType& argument) const495 virtual void evaluateArgument(unsigned int index, MultiType& argument) const override 512 496 { 513 497 switch (index) 514 498 { 515 case 0: argument.convert< P1>(); break;516 case 1: argument.convert< P2>(); break;517 case 2: argument.convert< P3>(); break;518 case 3: argument.convert< P4>(); break;519 case 4: argument.convert< P5>(); break;499 case 0: argument.convert<typename detail::GetNthParamType<0, Params...>::Type>(); break; 500 case 1: argument.convert<typename detail::GetNthParamType<1, Params...>::Type>(); break; 501 case 2: argument.convert<typename detail::GetNthParamType<2, Params...>::Type>(); break; 502 case 3: argument.convert<typename detail::GetNthParamType<3, Params...>::Type>(); break; 503 case 4: argument.convert<typename detail::GetNthParamType<4, Params...>::Type>(); break; 520 504 } 521 505 } 522 506 523 507 // see Functor::getParamCount() 524 unsigned int getParamCount() const525 { 526 return detail::FunctorParamCount<P1, P2, P3, P4, P5>::result;508 virtual unsigned int getParamCount() const override 509 { 510 return sizeof...(Params); 527 511 } 528 512 529 513 // see Functor::hasReturnvalue() 530 bool hasReturnvalue() const514 virtual bool hasReturnvalue() const override 531 515 { 532 516 return detail::FunctorHasReturnvalue<R>::result; … … 534 518 535 519 // see Functor::getTypenameParam() 536 std::string getTypenameParam(unsigned int index) const520 virtual std::string getTypenameParam(unsigned int index) const override 537 521 { 538 522 switch (index) 539 523 { 540 case 0: return typeToString< P1>();541 case 1: return typeToString< P2>();542 case 2: return typeToString< P3>();543 case 3: return typeToString< P4>();544 case 4: return typeToString< P5>();524 case 0: return typeToString<typename detail::GetNthParamType<0, Params...>::Type>(); 525 case 1: return typeToString<typename detail::GetNthParamType<1, Params...>::Type>(); 526 case 2: return typeToString<typename detail::GetNthParamType<2, Params...>::Type>(); 527 case 3: return typeToString<typename detail::GetNthParamType<3, Params...>::Type>(); 528 case 4: return typeToString<typename detail::GetNthParamType<4, Params...>::Type>(); 545 529 default: return ""; 546 530 } … … 548 532 549 533 // see Functor::getTypenameReturnvalue() 550 std::string getTypenameReturnvalue() const534 virtual std::string getTypenameReturnvalue() const override 551 535 { 552 536 return typeToString<R>(); 553 537 } 554 538 539 // see Functor::getFullIdentifier() 540 virtual const std::type_info& getFullIdentifier() const override 541 { 542 return typeid(typename detail::FunctionType<void, R, O, isconst, Params...>::Type); 543 } 544 555 545 // see Functor::getHeaderIdentifier() 556 const std::type_info& getHeaderIdentifier() const557 { 558 return typeid( detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, P5>);546 virtual const std::type_info& getHeaderIdentifier() const override 547 { 548 return typeid(typename detail::FunctionType<void, R, void, false, Params...>::Type); 559 549 } 560 550 561 551 // see Functor::getHeaderIdentifier(unsigned int) 562 const std::type_info& getHeaderIdentifier(unsigned int params) const552 virtual const std::type_info& getHeaderIdentifier(unsigned int params) const override 563 553 { 564 554 switch (params) 565 555 { 566 case 0: return t ypeid(detail::FunctorHeaderIdentifier<R, void, void, void, void, void>);567 case 1: return t ypeid(detail::FunctorHeaderIdentifier<R, P1, void, void, void, void>);568 case 2: return t ypeid(detail::FunctorHeaderIdentifier<R, P1, P2, void, void, void>);569 case 3: return t ypeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, void, void>);570 case 4: return t ypeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, void>);571 default: return t ypeid(detail::FunctorHeaderIdentifier<R, P1, P2, P3, P4, P5>);556 case 0: return this->getTypelistIdentifier(detail::make_type_list<0, Params...>{}); 557 case 1: return this->getTypelistIdentifier(detail::make_type_list<1, Params...>{}); 558 case 2: return this->getTypelistIdentifier(detail::make_type_list<2, Params...>{}); 559 case 3: return this->getTypelistIdentifier(detail::make_type_list<3, Params...>{}); 560 case 4: return this->getTypelistIdentifier(detail::make_type_list<4, Params...>{}); 561 default: return this->getTypelistIdentifier(detail::make_type_list<5, Params...>{}); 572 562 } 573 563 } 564 565 private: 566 /// Helper function that deduces a parameter pack of types and returns the corresponding identifier 567 template<class... Types> 568 const std::type_info& getTypelistIdentifier(detail::type_list<Types...>) const 569 { 570 return typeid(typename detail::FunctionType<void, R, void, false, Types...>::Type); 571 } 574 572 }; 575 573 576 template <class R, class O, class OO, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5), OO* object) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, P5>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 577 template <class R, class O, class OO, class P1, class P2, class P3, class P4> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4), OO* object) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 578 template <class R, class O, class OO, class P1, class P2, class P3> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3), OO* object) { return new FunctorTemplate<R, O, false, P1, P2, P3, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 579 template <class R, class O, class OO, class P1, class P2> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2), OO* object) { return new FunctorTemplate<R, O, false, P1, P2, void, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 580 template <class R, class O, class OO, class P1> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1), OO* object) { return new FunctorTemplate<R, O, false, P1, void, void, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 581 template <class R, class O, class OO> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(), OO* object) { return new FunctorTemplate<R, O, false, void, void, void, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 582 template <class R, class O, class OO, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5) const, OO* object) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, P5>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 583 template <class R, class O, class OO, class P1, class P2, class P3, class P4> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4) const, OO* object) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 584 template <class R, class O, class OO, class P1, class P2, class P3> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3) const, OO* object) { return new FunctorTemplate<R, O, true, P1, P2, P3, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 585 template <class R, class O, class OO, class P1, class P2> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2) const, OO* object) { return new FunctorTemplate<R, O, true, P1, P2, void, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 586 template <class R, class O, class OO, class P1> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1) const, OO* object) { return new FunctorTemplate<R, O, true, P1, void, void, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 587 template <class R, class O, class OO> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)() const, OO* object) { return new FunctorTemplate<R, O, true, void, void, void, void, void>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 588 589 template <class R, class O, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5)) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, P5>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 590 template <class R, class O, class P1, class P2, class P3, class P4> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4)) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 591 template <class R, class O, class P1, class P2, class P3> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3)) { return new FunctorTemplate<R, O, false, P1, P2, P3, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 592 template <class R, class O, class P1, class P2> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2)) { return new FunctorTemplate<R, O, false, P1, P2, void, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 593 template <class R, class O, class P1> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1)) { return new FunctorTemplate<R, O, false, P1, void, void, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 594 template <class R, class O> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)()) { return new FunctorTemplate<R, O, false, void, void, void, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 595 template <class R, class O, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5) const) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, P5>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 596 template <class R, class O, class P1, class P2, class P3, class P4> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4) const) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 597 template <class R, class O, class P1, class P2, class P3> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3) const) { return new FunctorTemplate<R, O, true, P1, P2, P3, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 598 template <class R, class O, class P1, class P2> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2) const) { return new FunctorTemplate<R, O, true, P1, P2, void, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 599 template <class R, class O, class P1> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1) const) { return new FunctorTemplate<R, O, true, P1, void, void, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 600 template <class R, class O> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)() const) { return new FunctorTemplate<R, O, true, void, void, void, void, void>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 601 602 template <class R, class P1, class P2, class P3, class P4, class P5> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3, P4, P5)) { return new FunctorTemplate<R, void, false, P1, P2, P3, P4, P5>(functionPointer); } ///< Creates a new Functor with the given function-pointer 603 template <class R, class P1, class P2, class P3, class P4> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3, P4)) { return new FunctorTemplate<R, void, false, P1, P2, P3, P4, void>(functionPointer); } ///< Creates a new Functor with the given function-pointer 604 template <class R, class P1, class P2, class P3> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3)) { return new FunctorTemplate<R, void, false, P1, P2, P3, void, void>(functionPointer); } ///< Creates a new Functor with the given function-pointer 605 template <class R, class P1, class P2> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2)) { return new FunctorTemplate<R, void, false, P1, P2, void, void, void>(functionPointer); } ///< Creates a new Functor with the given function-pointer 606 template <class R, class P1> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1)) { return new FunctorTemplate<R, void, false, P1, void, void, void, void>(functionPointer); } ///< Creates a new Functor with the given function-pointer 607 template <class R> inline FunctorStaticPtr createFunctor(R (*functionPointer)()) { return new FunctorTemplate<R, void, false, void, void, void, void, void>(functionPointer); } ///< Creates a new Functor with the given function-pointer 574 575 namespace detail 576 { 577 // Helper functions to deduce types and constness of operator() and return the correct FunctorTemplate 578 template <class F> 579 struct CallableHelper 580 { 581 template <class R, class... Params> static inline FunctorStaticPtr create(const F& functionObject, R(F::*)(Params...)) { return std::make_shared<FunctorTemplate<F, R, void, false, Params...>>(functionObject); } 582 template <class R, class... Params> static inline FunctorStaticPtr create(const F& functionObject, R(F::*)(Params...) const) { return std::make_shared<FunctorTemplate<F, R, void, false, Params...>>(functionObject); } // note: both const and non-const function-objects are treated as static functors with isconst=false. 583 }; 584 } 585 586 template <class R, class O, class OO, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...), OO* object) { return std::make_shared<FunctorTemplate<void, R, O, false, Params...>>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 587 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<void, R, O, true, Params...>>(functionPointer, object); } ///< Creates a new FunctorMember with the given function-pointer and an assigned object 588 589 template <class R, class O, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...)) { return std::make_shared<FunctorTemplate<void, R, O, false, Params...>>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 590 template <class R, class O, class... Params> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(Params...) const) { return std::make_shared<FunctorTemplate<void, R, O, true, Params...>>(functionPointer); } ///< Creates a new FunctorMember with the given function-pointer 591 592 template <class R, class... Params> inline FunctorStaticPtr createFunctor(R (*functionPointer)(Params...)) { return std::make_shared<FunctorTemplate<void, R, void, false, Params...>>(functionPointer); } ///< Creates a new FunctorStatic with the given function-pointer 593 594 /** Take care that this functor does not outlive objects that have been captured by reference in a lambda. */ 595 template <class F> inline FunctorStaticPtr createFunctor(const F& functionObject) { return detail::CallableHelper<F>::create(functionObject, &F::operator()); } ///< Creates a new Functor with a callable object 608 596 } 609 597
Note: See TracChangeset
for help on using the changeset viewer.