diff options
author | Josh Blum | 2013-07-13 14:03:11 -0700 |
---|---|---|
committer | Josh Blum | 2013-07-13 14:03:11 -0700 |
commit | cb0c6da5230aad979153b48d3733984c0d62122e (patch) | |
tree | 1c3fc6f13d92e79942f2b050c189f44109e676ab /tmpl/callable.tmpl.hpp | |
parent | f99744a072d97c83f5a7da6c0626a38475c4fc44 (diff) | |
parent | fc98eaf2a00e000841cb16d962f83c118e4824c2 (diff) | |
download | sandhi-cb0c6da5230aad979153b48d3733984c0d62122e.tar.gz sandhi-cb0c6da5230aad979153b48d3733984c0d62122e.tar.bz2 sandhi-cb0c6da5230aad979153b48d3733984c0d62122e.zip |
Merge branch 'generate_templates'
Diffstat (limited to 'tmpl/callable.tmpl.hpp')
-rw-r--r-- | tmpl/callable.tmpl.hpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/tmpl/callable.tmpl.hpp b/tmpl/callable.tmpl.hpp new file mode 100644 index 0000000..900bae4 --- /dev/null +++ b/tmpl/callable.tmpl.hpp @@ -0,0 +1,94 @@ +// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information. + +#ifndef INCLUDED_GRAS_CALLABLE_HPP +#define INCLUDED_GRAS_CALLABLE_HPP + +#include <gras/gras.hpp> +#include <PMC/PMC.hpp> +#include <boost/shared_ptr.hpp> +#include <vector> +#include <string> + +namespace gras +{ + +/*! + * The callable interface allows subclasses to export public methods, + * but without actually exporting traditional library symbols. + * + * Callable handles the template magic so you don't have to: + * - registering subclass methods is simple and easy on the user. + * - users call registered methods with natural code aesthetics. + * + * Register a method (in the constructor of MyClass): + * this->register_call("set_foo", &MyClass::set_foo); + * + * Call a method on a instance of MyClass: + * my_class->x("set_foo", new_foo_val); + * + * Why x for the call method? + * - The "x" is short, one character of screen width. + * - The "x" looks like "*", which is commonly used. + * - The overloaded () operator sucks with pointers. + * - The overloaded () operator has template issues. + */ +class GRAS_API Callable +{ +public: + + //! Default constructor + Callable(void); + + //! Destructor (virtual for subclasses) + virtual ~Callable(void); + + //! Get a list of names for registered calls + std::vector<std::string> get_registered_names(void) const; + +protected: + /*! + * Unregister a previously registered call. + * Throws if the name is not found in the registry. + */ + void unregister_call(const std::string &name); + + /******************************************************************* + * Register API - don't look here, template magic, not helpful + ******************************************************************/ +protected: + #for $NARGS in range($MAX_ARGS) + template <typename ClassType, typename ReturnType, $expand('typename A%d', $NARGS)> + void register_call(const std::string &name, ReturnType(ClassType::*fcn)($expand('const A%d &', $NARGS))); + + template <typename ClassType, $expand('typename A%d', $NARGS)> + void register_call(const std::string &name, void(ClassType::*fcn)($expand('const A%d &', $NARGS))); + + #end for + /******************************************************************* + * Call API - don't look here, template magic, not helpful + ******************************************************************/ +public: + #for $NARGS in range($MAX_ARGS) + template <typename ReturnType, $expand('typename A%d', $NARGS)> + ReturnType x(const std::string &name, $expand('const A%d &', $NARGS)); + + template <$expand('typename A%d', $NARGS)> + void x(const std::string &name, $expand('const A%d &', $NARGS)); + + #end for + /******************************************************************* + * Private registration hooks + ******************************************************************/ +protected: + void _register_call(const std::string &, void *); +public: + virtual PMCC _handle_call(const std::string &, const PMCC &); +private: + boost::shared_ptr<void> _call_registry; +}; + +} //namespace gras + +#include <gras/detail/callable.hpp> + +#endif /*INCLUDED_GRAS_CALLABLE_HPP*/ |