// // Copyright (c) 2000 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_OPERATOR_DOT_H #define FCPP_OPERATOR_DOT_H ////////////////////////////////////////////////////////////////////// // The goal here is to provide functoids for all C++ operators (e.g. // Plus, Greater, ...) as well as conversions between representations. // The conversions include ptr_to_fun, for turning function pointers into // functoids, stl_to_funN, for turning STL functoids into our functoids, // and monomophizeN, for converting polymorphic direct functoids into // monomorphic ones. // // There's also some miscellaneous at the end of this file, for lack of // a better place to put it. ////////////////////////////////////////////////////////////////////// #include #include #include "curry.h" namespace fcpp { ////////////////////////////////////////////////////////////////////// // operators ////////////////////////////////////////////////////////////////////// struct MakePair { template struct Sig : public FunType > {}; template std::pair operator()( const A& a, const B& b ) const { return std::make_pair(a,b); } }; namespace { MakePair _makePair; Curryable2 makePair(_makePair); } struct Min { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::less()( x, y ) ? x : y; } }; namespace { Min _min; Curryable2 min(_min); } struct Max { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::less()( x, y ) ? y : x; } }; namespace { Max _max; Curryable2 max(_max); } struct Plus { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::plus()( x, y ); } }; namespace { Plus _plus; Curryable2 plus(_plus); } struct Minus { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::minus()( x, y ); } }; namespace { Minus _minus; Curryable2 minus(_minus); } struct Multiplies { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::multiplies()( x, y ); } }; namespace { Multiplies _multiplies; Curryable2 multiplies(_multiplies); } struct Divides { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::divides()( x, y ); } }; namespace { Divides _divides; Curryable2 divides(_divides); } struct Modulus { template struct Sig : public FunType {}; template T operator()( const T& x, const T& y ) const { return std::modulus()( x, y ); } }; namespace { Modulus _modulus; Curryable2 modulus(_modulus); } struct Negate { template struct Sig : public FunType {}; template T operator()( const T& x ) const { return std::negate()( x ); } }; namespace { Negate negate; } struct Equal { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::equal_to()( x, y ); } }; namespace { Equal _equal; Curryable2 equal(_equal); } struct NotEqual { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::not_equal_to()( x, y ); } }; namespace { NotEqual _notEqual; Curryable2 notEqual(_notEqual); } struct Greater { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::greater()( x, y ); } }; namespace { Greater _greater; Curryable2 greater(_greater); } struct Less { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::less()( x, y ); } }; namespace { Less _less; Curryable2 less(_less); } struct GreaterEqual { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::greater_equal()( x, y ); } }; namespace { GreaterEqual _greaterEqual; Curryable2 greaterEqual(_greaterEqual); } struct LessEqual { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::less_equal()( x, y ); } }; namespace { LessEqual _lessEqual; Curryable2 lessEqual(_lessEqual); } struct LogicalAnd { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::logical_and()( x, y ); } }; namespace { LogicalAnd _logicalAnd; Curryable2 logicalAnd(_logicalAnd); } struct LogicalOr { template struct Sig : public FunType {}; template bool operator()( const T&x, const T&y ) const { return std::logical_or()( x, y ); } }; namespace { LogicalOr _logicalOr; Curryable2 logicalOr(_logicalOr); } struct LogicalNot { template struct Sig : public FunType {}; template bool operator()( const T&x ) const { return std::logical_not()( x ); } }; namespace { LogicalNot logicalNot; } // The other "higher-order" operators in STL are easy to do in our // framework. For instance, instead of unary_negate (with all its // complicated type info), we can just say compose1(logicalnot, f). ////////////////////////////////////////////////////////////////////// // STL conversions ////////////////////////////////////////////////////////////////////// template class stl1 : CFunType { Op f; public: stl1( const Op& o ) : f(o) {} typename Op::result_type operator()( const typename Op::argument_type& x ) const { return f(x); } }; template stl1 stl_to_fun1( const Op& o ) { return stl1(o); } template class stl2 : CFunType { Op f; public: stl2( const Op& o ) : f(o) {} typename Op::result_type operator()( const typename Op::first_argument_type& x, const typename Op::second_argument_type& y ) const { return f(x,y); } }; template Curryable2 > stl_to_fun2( const Op& o ) { return makeCurryable2(stl2(o)); } ////////////////////////////////////////////////////////////////////// // monomorphizing conversions ////////////////////////////////////////////////////////////////////// template class MonomorphicWrapper3 : public CFunType { F f; public: MonomorphicWrapper3( const F& g ) : f(g) {} Res operator()( const Arg1& x, const Arg2& y, const Arg3& z ) const { return f(x,y,z); } }; template Curryable3 > monomorphize3( const F& f ) { return makeCurryable3(MonomorphicWrapper3( f )); } template class MonomorphicWrapper2 : public CFunType { F f; public: MonomorphicWrapper2( const F& g ) : f(g) {} Res operator()( const Arg1& x, const Arg2& y ) const { return f(x,y); } }; template Curryable2 > monomorphize2( const F& f ) { return makeCurryable2(MonomorphicWrapper2( f )); } template class MonomorphicWrapper1 : public CFunType { F f; public: MonomorphicWrapper1( const F& g ) : f(g) {} Res operator()( const Arg1& x ) const { return f(x); } }; template MonomorphicWrapper1 monomorphize1( const F& f ) { return MonomorphicWrapper1( f ); } template class MonomorphicWrapper0 : public CFunType { F f; public: MonomorphicWrapper0( const F& g ) : f(g) {} Res operator()() const { return f(); } }; template MonomorphicWrapper0 monomorphize0( const F& f ) { return MonomorphicWrapper0( f ); } ////////////////////////////////////////////////////////////////////// // ptr_fun ////////////////////////////////////////////////////////////////////// template class ptr_to_nullary_function : public CFunType { Result (*ptr)(); public: explicit ptr_to_nullary_function(Result (*x)()) : ptr(x) {} Result operator()() const { return ptr(); } }; template inline ptr_to_nullary_function ptr_to_fun(Result (*x)()) { return ptr_to_nullary_function(x); } template class ptr_to_unary_function : public CFunType { Result (*ptr)(Arg); public: explicit ptr_to_unary_function(Result (*x)(Arg)) : ptr(x) {} Result operator()(Arg x) const { return ptr(x); } }; template inline ptr_to_unary_function ptr_to_fun(Result (*x)(Arg)) { return ptr_to_unary_function(x); } template class ptr_to_binary_function : public CFunType { Result (*ptr)(Arg1, Arg2); public: explicit ptr_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {} Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); } }; template inline Curryable2 > ptr_to_fun(Result (*x)(Arg1, Arg2)) { return makeCurryable2( ptr_to_binary_function(x) ); } template class ptr_to_ternary_function : public CFunType { Result (*ptr)(Arg1, Arg2, Arg3); public: explicit ptr_to_ternary_function(Result (*x)(Arg1, Arg2, Arg3)) : ptr(x) {} Result operator()(Arg1 x, Arg2 y, Arg3 z) const { return ptr(x,y,z); } }; template inline Curryable3 > ptr_to_fun(Result (*x)(Arg1, Arg2, Arg3)) { return makeCurryable3( ptr_to_ternary_function(x) ); } ////////////////////////////////////////////////////////////////////// // Turn member functions into normal functions which take a Receiver* // as their first (extra) argument. Note that we disallow reference // parameters. ////////////////////////////////////////////////////////////////////// template class ptr_to_mem_binary_function : public CFunType { Result (Arg1::*ptr)(Arg2,Arg3); public: explicit ptr_to_mem_binary_function(Result (Arg1::*x)(Arg2,Arg3)) : ptr(x) {} Result operator()(Arg1* x, const Arg2& y, const Arg3& z) const { return (x->*ptr)(y,z); } }; template inline Curryable3 > ptr_to_fun(Result (Arg1::*x)(Arg2,Arg3)) { return makeCurryable3( ptr_to_mem_binary_function(x) ); } template class ptr_to_mem_unary_function : public CFunType { Result (Arg1::*ptr)(Arg2); public: explicit ptr_to_mem_unary_function(Result (Arg1::*x)(Arg2)) : ptr(x) {} Result operator()(Arg1* x, const Arg2& y) const { return (x->*ptr)(y); } }; template inline Curryable2 > ptr_to_fun(Result (Arg1::*x)(Arg2)) { return makeCurryable2( ptr_to_mem_unary_function(x) ); } template class ptr_to_mem_nullary_function : public CFunType { Result (Arg1::*ptr)(); public: explicit ptr_to_mem_nullary_function(Result (Arg1::*x)()) : ptr(x) {} Result operator()(Arg1* x) const { return (x->*ptr)(); } }; template inline ptr_to_mem_nullary_function ptr_to_fun(Result (Arg1::*x)()) { return ptr_to_mem_nullary_function(x); } ////////////////////////////////////////////////////////////////////// // Misc stuff ////////////////////////////////////////////////////////////////////// struct Inc { template struct Sig : public FunType {}; template T operator()(const T& x) const { T y = x; return ++y; } }; namespace { Inc inc; } struct Always1 { template struct Sig : public FunType {}; template bool operator()(const T&) const { return true; } }; namespace { Always1 always1; } struct Never1 { template struct Sig : public FunType {}; template bool operator()(const T&) const { return false; } }; namespace { Never1 never1; } } // end namespace fcpp #endif