//--------------------------------------------------------------------------- /* 統合関数オブジェクト by Gimite 同じ引数型&戻り値型を持つ全ての関数オブジェクト&関数ポインタを 代入可能な関数オブジェクト。 nullary_unified_function: 無項関数用 unary_unified_function: 単項関数用 binary_unified_function: 二項関数用 ex. binary_unified_functor func= plus(); int r= func(12, 7); */ //--------------------------------------------------------------------------- #ifndef GIMITE_unified_functorH #define GIMITE_unified_functorH //--------------------------------------------------------------------------- #include #include //--------------------------------------------------------------------------- namespace gimite{ //--------------------------------------------------------------------------- template class basic_nullary_call { public: virtual ~basic_nullary_call(){} virtual Result call() const= 0; virtual basic_nullary_call* clone() const= 0; }; template class nullary_call: public basic_nullary_call { T func; public: nullary_call(T a_func): func(a_func){} virtual Result call() const {return func();} virtual basic_nullary_call* clone() const {return new nullary_call(*this);} }; template class nullary_unified_functor { typedef nullary_unified_functor my_type; typedef Result result_type; std::auto_ptr > call; public: nullary_unified_functor(){} nullary_unified_functor(const my_type& src) : call(src.call.get()? src.call->clone() : 0){} nullary_unified_functor(Result (*func)())//(*2) : call(new nullary_call(func)){} template nullary_unified_functor(const T& func)//(*1) : call(new nullary_call(func)){} my_type& operator=(const my_type& src){ call.reset(src.call.get()? src.call->clone() : 0); return *this; } my_type& operator=(Result (*func)()){//(*2) call.reset(new nullary_call(func)); return *this; } template my_type& operator=(const T& func){//(*1) call.reset(new nullary_call(func)); return *this; } Result operator()() const{ if (call.get()) return call->call(); else return Result(); } }; //--------------------------------------------------------------------------- template class basic_unary_call { public: virtual ~basic_unary_call(){} virtual Result call(const Arg& arg) const= 0; virtual basic_unary_call* clone() const= 0; }; template class unary_call: public basic_unary_call { T func; public: unary_call(T a_func): func(a_func){} virtual Result call(const Arg& arg) const {return func(arg);} virtual basic_unary_call* clone() const {return new unary_call(*this);} }; template class unary_unified_functor: public std::unary_function { typedef unary_unified_functor my_type; std::auto_ptr > call; public: unary_unified_functor(){} unary_unified_functor(const my_type& src) : call(src.call.get()? src.call->clone() : 0){} template unary_unified_functor(Result (*func)(T))//(*2) : call(new unary_call(func)){} template unary_unified_functor(const T& func)//(*1) : call(new unary_call(func)){} my_type& operator=(const my_type& src){ call.reset(src.call.get()? src.call->clone() : 0); return *this; } template my_type& operator=(Result (*func)(T)){//(*2) call.reset(new unary_call(func)); return *this; } template my_type& operator=(const T& func){//(*1) call.reset(new unary_call(func)); return *this; } Result operator()(const Arg& arg) const{ if (call.get()) return call->call(arg); else return Result(); } }; //--------------------------------------------------------------------------- template class basic_binary_call { public: virtual ~basic_binary_call(){} virtual Result call(const Arg1& arg1, const Arg2& arg2) const= 0; virtual basic_binary_call* clone() const= 0; }; template class binary_call: public basic_binary_call { T func; public: binary_call(T a_func): func(a_func){} virtual Result call(const Arg1& arg1, const Arg2& arg2) const {return func(arg1, arg2);} virtual basic_binary_call* clone() const {return new binary_call(*this);} }; template class binary_unified_functor: public std::binary_function { typedef binary_unified_functor my_type; std::auto_ptr > call; public: binary_unified_functor(){} binary_unified_functor(const my_type& src) : call(src.call.get()? src.call->clone() : 0){} template binary_unified_functor(Result (*func)(T, S))//(*2) : call(new binary_call(func)){} template binary_unified_functor(const T& func)//(*1) : call(new binary_call(func)){} my_type& operator=(const my_type& src){ call.reset(src.call.get()? src.call->clone() : 0); return *this; } template my_type& operator=(Result (*func)(T, S)){//(*2) call.reset(new binary_call(func)); return *this; } template my_type& operator=(const T& func){//(*1) call.reset(new binary_call(func)); return *this; } Result operator()(const Arg1& arg1, const Arg2& arg2) const{ if (call.get()) return call->call(arg1, arg2); else return Result(); } }; //--------------------------------------------------------------------------- //*1 引数型Tは不可。コピーコンストラクタ/同じ型の代入が働かなくなる。 //*2 よう分からんけど、こうしないとBCCでは関数ポインタが代入できない。 // 引数をtemplateにしてるのはconst Arg&もOKにするため。 //--------------------------------------------------------------------------- }//namespace gimite //--------------------------------------------------------------------------- #endif