Changeset 10986 for code/branches/cpp11_v2/src/libraries/core
- Timestamp:
- Dec 28, 2015, 6:57:26 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/cpp11_v2/src/libraries/core/command/Functor.h
r10985 r10986 357 357 358 358 /** 359 @brief FunctorPointer is a child class of FunctorMember and ex pands it with a function-pointer.360 @param F The type of the function-pointer 361 @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) 362 362 363 363 The template FunctorPointer has an additional template parameter that defines the type 364 of the function-pointer . This can be handy if you want to get or set the function-pointer.365 You can then use a static_cast to cast a Functor to FunctorPointer if you know the type366 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. 367 367 368 368 However FunctorPointer is not aware of the types of the different parameters or the … … 383 383 { return this->functionPointer_; } 384 384 385 // see Functor::getFullIdentifier()386 virtual const std::type_info& getFullIdentifier() const override387 { return typeid(F); }388 389 385 protected: 390 386 F functionPointer_; ///< The stored function-pointer … … 393 389 namespace detail 394 390 { 395 // Helper class to get the type of the function pointer with the given class, parameters, return-value, and constness 396 template <class R, class O, bool isconst, class... Params> struct FunctionPointer { typedef R (O::*Type)(Params...); }; 397 template <class R, class O, class... Params> struct FunctionPointer<R, O, true, Params...> { typedef R (O::*Type)(Params...) const; }; 398 template <class R, class... Params> struct FunctionPointer<R, void, false, Params...> { typedef R (*Type)(Params...); }; 399 400 // Helper class, used to call a function-pointer with a given object and parameters and to return its return-value (if available) 401 template <class R, class O, bool isconst, class... Params> struct FunctorCaller { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, Params...>::Type functionPointer, O* object, const Params&... parameters, const UnusedParams&...) { return (object->*functionPointer)(parameters...); } }; 402 template <class O, bool isconst, class... Params> struct FunctorCaller<void, O, isconst, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionPointer<void, O, isconst, Params...>::Type functionPointer, O* object, const Params&... parameters, const UnusedParams&...) { (object->*functionPointer)(parameters...); return MultiType::Null; } }; 403 template <class R, bool isconst, class... Params> struct FunctorCaller<R, void, isconst, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionPointer<R, void, isconst, Params...>::Type functionPointer, void*, const Params&... parameters, const UnusedParams&...) { return (*functionPointer)(parameters...); } }; 404 template <bool isconst, class... Params> struct FunctorCaller<void, void, isconst, Params...> { template <class... UnusedParams> static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, Params...>::Type functionPointer, void*, const Params&... parameters, const UnusedParams&...) { (*functionPointer)(parameters...); return MultiType::Null; } }; 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 405 406 406 407 // Helper class to determine if a function has a returnvalue … … 457 458 that need to know the exact types of the parameters, return-value, and class. 458 459 460 @param F the type of the function-object (or void if a function-pointer is used). 459 461 @param R The type of the return-value of the function 460 462 @param O The class of the function … … 469 471 All template arguments can be void. 470 472 */ 471 template <class R, class O, bool isconst, class... Params>472 class FunctorTemplate : public FunctorPointer<typename detail::Function Pointer<R, O, isconst, Params...>::Type, O>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> 473 475 { 474 476 static_assert(sizeof...(Params) <= 5, "Only up to 5 parameters are supported"); … … 476 478 public: 477 479 /// Constructor: Initializes the base class. 478 FunctorTemplate(typename detail::Function Pointer<R, O, isconst, Params...>::Type functionPointer, O* object = nullptr) : FunctorPointer<typename detail::FunctionPointer<R, O, isconst, Params...>::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) {} 479 481 480 482 // see FunctorMember::operator()() 481 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 482 484 { 483 return detail::FunctorCaller< R, O, isconst, Params...>::call(this->functionPointer_, object, param1, param2, param3, param4, param5);485 return detail::FunctorCaller<F, R, O, isconst, Params...>::call(this->functionPointer_, object, param1, param2, param3, param4, param5); 484 486 } 485 487 … … 535 537 } 536 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 537 545 // see Functor::getHeaderIdentifier() 538 546 virtual const std::type_info& getHeaderIdentifier() const override 539 547 { 540 return typeid(typename detail::Function Pointer<R, void, false, Params...>::Type);548 return typeid(typename detail::FunctionType<void, R, void, false, Params...>::Type); 541 549 } 542 550 … … 560 568 const std::type_info& getTypelistIdentifier(detail::type_list<Types...>) const 561 569 { 562 return typeid(typename detail::Function Pointer<R, void, false, Types...>::Type);570 return typeid(typename detail::FunctionType<void, R, void, false, Types...>::Type); 563 571 } 564 572 }; 565 573 566 574 567 /**568 @brief FunctorCallable is a child class of FunctorTemplate. It stores a callable569 object (e.g. a lambda or a class with operator()) inside and acts like any570 other functor. Note that it stores a \em copy of the object, not a reference or a pointer.571 Take care that this functor does not outlive objects that have been captured by reference572 in a lambda.573 574 @param F The type of the callable object575 @param R The type of the return-value of the function576 @param isconst True if operator() is const577 @param Params The types of the parameters578 579 This template can not be used directly when using lambdas - the type of a lambda580 is not specified. It can only really be used through the base-class Functor.581 */582 template <class F, class R, bool isconst, class... Params>583 class FunctorCallable : public FunctorTemplate<R, F, isconst, Params...>584 {585 public:586 FunctorCallable(const F& obj): FunctorTemplate<R, F, isconst, Params...>(&F::operator(), &obj_)587 , obj_(obj)588 {}589 590 private:591 F obj_; ///< The callable object592 };593 594 575 namespace detail 595 576 { 596 577 //Helper functions to deduce types and constness of operator() and return the correct FunctorCallable 597 template <class F, class R, class... Params> inline Functor MemberPtr<F> callableHelper(const F& obj, R(F::*func)(Params...) const) { return std::make_shared<FunctorCallable<F, R, true, Params...>>(obj); }598 template <class F, class R, class... Params> inline Functor MemberPtr<F> callableHelper(const F& obj, R(F::*func)(Params...)) { return std::make_shared<FunctorCallable<F, R, false, Params...>>(obj); }578 template <class F, class R, class... Params> inline FunctorStaticPtr callableHelper(const F& functionObject, R(F::*)(Params...)) { return std::make_shared<FunctorTemplate<F, R, void, false, Params...>>(functionObject); } 579 template <class F, class R, class... Params> inline FunctorStaticPtr callableHelper(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. 599 580 } 600 581 601 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 602 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 603 604 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 605 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 606 607 template <class R, class... Params> inline FunctorStaticPtr createFunctor(R (*functionPointer)(Params...)) { return std::make_shared<FunctorTemplate<R, void, false, Params...>>(functionPointer); } ///< Creates a new FunctorStatic with the given function-pointer 608 609 template <class F> inline FunctorMemberPtr<F> createFunctor(const F& obj) { return detail::callableHelper(obj, &F::operator()); } ///< Creates a new Functor with a callable object 582 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 583 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 584 585 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 586 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 587 588 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 589 590 /** Take care that this functor does not outlive objects that have been captured by reference in a lambda. */ 591 template <class F> inline FunctorStaticPtr createFunctor(const F& functionObject) { return detail::callableHelper(functionObject, &F::operator()); } ///< Creates a new Functor with a callable object 610 592 } 611 593
Note: See TracChangeset
for help on using the changeset viewer.