// // Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis // // Permission to use, copy, modify, distribute and sell this software // and its documentation for any purpose is granted without fee, // provided that the above copyright notice and this permission notice // appear in all source code copies and supporting documentation. The // software is provided "as is" without any express or implied // warranty. #ifndef FCPP_FULL_DOT_H #define FCPP_FULL_DOT_H #include "smart.h" #include "curry.h" #include "pre_lambda.h" namespace fcpp { ////////////////////////////////////////////////////////////////////// // Full functoids ////////////////////////////////////////////////////////////////////// // Just as Curryable2/Curryable3 serve as wrappers which decorate // functoids to give them 'curryability', FullN are wrappers to give // functoids _all_ the 'features' that functoids can have. The current // "extra feature set" for functoids is // - curryability (ability to call with fewer args) // - lambda-awareness (operator[] for use inside lambda) // - smartness (inherited typedefs to answer introspective questions) // The FullN classes just combine all of the features into one // uber-wrapper which does it all. // Don't forget that any features added here need to be added to // the indirect functoids in function.h, too. // And also to the Uncurryable class in prelude.h. // FIX THIS take a good look at Uncurry; it may have pre-dated smartness // and can now be written more sanely...? template class Full0 : public SmartFunctoid0, public CFunType::ResultType> { F f; public: Full0() : f() {} Full0( const F& ff ) : f(ff) {} #ifdef FCPP_ENABLE_LAMBDA typedef Full0 This; template typename fcpp_lambda::BracketCallable::Result operator[]( const A& a ) const { return fcpp_lambda::BracketCallable::go( *this, a ); } #endif inline typename RT::ResultType operator()() const { return f(); } }; template class Full1 : public SmartFunctoid1 { F f; public: Full1() : f() {} Full1( const F& ff ) : f(ff) {} #ifdef FCPP_ENABLE_LAMBDA typedef Full1 This; template typename fcpp_lambda::BracketCallable::Result operator[]( const A& a ) const { return fcpp_lambda::BracketCallable::go( *this, a ); } #endif template struct Sig : public FunType::Arg1Type, typename RT::ResultType> {}; template inline typename Sig::ResultType operator()( const T& x ) const { return f(x); } }; template class Full2 : public SmartFunctoid2 { F f; public: Full2() : f() {} Full2( const F& ff ) : f(ff) {} #ifdef FCPP_ENABLE_LAMBDA typedef Full2 This; template typename fcpp_lambda::BracketCallable::Result operator[]( const A& a ) const { return fcpp_lambda::BracketCallable::go( *this, a ); } #endif ///////////// copied from Curryable2; added impl:: to binders ////// template struct Sig : public FunType::Arg1Type, typename F::template Sig::Arg2Type, typename RT::ResultType> {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template typename Sig::ResultType operator()( const X& x ) const { return makeFull1( impl::binder1of2(f,x) ); } template inline typename Sig::ResultType operator()( const X& x, const Y& y ) const { // need partial specialization, so defer to a class helper return impl::Curryable2Helper::ResultType,F,X,Y>::go(f,x,y); } ////////////////////////////////////////////////////////////////////// }; template class Full3 : public SmartFunctoid3 { F f; public: Full3() : f() {} Full3( const F& ff ) : f(ff) {} #ifdef FCPP_ENABLE_LAMBDA typedef Full3 This; template typename fcpp_lambda::BracketCallable::Result operator[]( const A& a ) const { return fcpp_lambda::BracketCallable::go( *this, a ); } #endif ///////////// copied from Curryable3; added impl:: to all binders // template struct Sig : public FunType::Arg1Type, typename F::template Sig::Arg2Type, typename F::template Sig::Arg3Type, typename RT::ResultType> {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template struct Sig : public FunType > > {}; template typename Sig::ResultType operator()( const X& x, const Y& y ) const { // need partial specialization, so defer to a class helper return impl::Curryable3Helper2::ResultType,F,X,Y>::go(f,x,y); } template typename Sig::ResultType operator()( const X& x ) const { return makeFull2(impl::binder1of3(f,x)); } template inline typename Sig::ResultType operator()( const X& x, const Y& y, const Z& z ) const { // need partial specialization, so defer to a class helper return impl::Curryable3Helper::ResultType,F,X,Y,Z> ::go(f,x,y,z); } ////////////////////////////////////////////////////////////////////// }; template Full0 makeFull0( const F& f ) { return Full0(f); } template Full1 makeFull1( const F& f ) { return Full1(f); } template Full2 makeFull2( const F& f ) { return Full2(f); } template Full3 makeFull3( const F& f ) { return Full3(f); } ////////////////////////////////////////////////////////////////////// // Definitions of stuff heretofore put-off... ////////////////////////////////////////////////////////////////////// // from curry.h: typedef Full1 Const; typedef Full2 Bind1of1; typedef Full2 Bind1of2; typedef Full2 Bind2of2; typedef Full3 Bind1and2of2; // FIX THIS? I never noticed: the only 4-arg functoid in the entire library typedef impl::Bind1and2and3of3 Bind1and2and3of3; typedef Full3 Bind1and2of3; typedef Full3 Bind2and3of3; typedef Full3 Bind1and3of3; typedef Full2 Bind1of3; typedef Full2 Bind2of3; typedef Full2 Bind3of3; FCPP_MAYBE_NAMESPACE_OPEN FCPP_MAYBE_EXTERN Const const_; // C++ keyword, so add trailing underscore FCPP_MAYBE_EXTERN Bind1of1 bind1of1; FCPP_MAYBE_EXTERN Bind1of2 bind1of2; FCPP_MAYBE_EXTERN Bind2of2 bind2of2; FCPP_MAYBE_EXTERN Bind1and2of2 bind1and2of2; FCPP_MAYBE_EXTERN Bind1and2and3of3 bind1and2and3of3; FCPP_MAYBE_EXTERN Bind1and2of3 bind1and2of3; FCPP_MAYBE_EXTERN Bind2and3of3 bind2and3of3; FCPP_MAYBE_EXTERN Bind1and3of3 bind1and3of3; FCPP_MAYBE_EXTERN Bind1of3 bind1of3; FCPP_MAYBE_EXTERN Bind2of3 bind2of3; FCPP_MAYBE_EXTERN Bind3of3 bind3of3; FCPP_MAYBE_NAMESPACE_CLOSE } // end namespace fcpp #endif