From 0fa524693bc8d73b0555d960b4426bfb5a05ac15 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Sun, 12 Jan 2014 17:21:55 +0100 Subject: [PATCH] initial code --- crtp_functor_ttp.cpp | 121 ++++++++++++++++++++++++++++++++++++++++ inheritance_functor.cpp | 91 ++++++++++++++++++++++++++++++ test.sh | 12 ++++ 3 files changed, 224 insertions(+) create mode 100644 crtp_functor_ttp.cpp create mode 100644 inheritance_functor.cpp create mode 100755 test.sh diff --git a/crtp_functor_ttp.cpp b/crtp_functor_ttp.cpp new file mode 100644 index 0000000..0843970 --- /dev/null +++ b/crtp_functor_ttp.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +#define ITEMS(c) c.begin(),c.end() + +// remains inchanged +template +class Increment +{ + public: + T arg; + Increment( T a ) : arg(a) {} + + template + T operator() ( T & value, OutIt out ) + { + value+=arg; + *out++ = value; + return 1; + } +}; + +/* We want to be able to use the functor interface as a templated class. + * But, it takes the derived class as a template parameter, + * along with the type of an operator class, which is templated: + * both of which are templated themselves. + * + * We want to avoid having to use declarations of the form: + * Functor,T>,Increment,T> + * Thus the complicated template of template (of template) structures below, which permits to write: + * Functor + * + * Below, "typename" is used where a standard type (being fundamentals or in the STL) is expected, + * and "class" where a class from the framework is expected. + */ +template< + // The templates structure of the derived class + template< + // An operator, i.e. a class with a template <=> a template of template + template class, + // A type + typename + // used as a type called CRTP + > class CRTP, + + // The template structure of the operator <=> a template of template called OP + template class OP, + + // the simple value type + typename T +> +class Functor +{ + public: + OP & op; + Functor( OP & o ) : op(o) {} + + // the function is not virtual, we can put a template on it + template + int operator() ( int& v, OutIt out ) + { + return static_cast*>(this)->functor(v,out); + } +}; + +/* + * Instead of having to write: + * Assign f(op); + * We can just write: + * auto f = make(op); + */ +template< + template< template class, typename > class FC, + template class OP, + typename T +> +FC& make_Functor( OP & op ) +{ + return *(new FC(op)); +} + +// Inherits from Functor via the CRTP +template