Mercurial > octave
diff liboctave/util/action-container.h @ 25653:b3d357990b52
better use of templates for action_container and derived classes
It should now be possible to add arbitrary lambda functions or
std::function objects to the unwind_protect objects and octave_link
event queues, and to add functions (including member functions) with
any number of parameters.
* action-container.h (action_container::fcn_elem): Define using
variadic template, std::bind, and std::function for more flexibility
and to eliminate code duplication.
(action_container::method_elem, action_container::method_arg_elem,
action_container::method_crefarg_elem,
action_container::method_arg2_elem,
action_container::method_arg3_elem,
action_container::method_arg4_elem): Delete.
(action_container::add_action): Rename from add. Now protected.
(action_container::add): New generic function for adding functions.
(action_container::add_fcn, action_container::add_method): Define
using variadic template for more flexibility and to eliminate code
duplication.
* event-queue.h (event_queue::add_action): Rename from add.
Now protected.
* unwind-prot.h (unwind_protect::add_action): Likewise.
* variable-editor-model.cc: Eliminate template parameters for calls to
octave_link::post_event fucntions.
* octave-link.h (octave_link::post_event, octave_link::do_post_event):
Define using variadic template for more flexibility and to eliminate
code duplication.
* pt-eval.h, pt-eval.cc (tree_evaluator::uwp_set_echo_state):
New function.
(tree_evaluator::set_echo_state, tree_evaluator::set_echo_file_name,
tree_evaluator::set_echo_file_pos): Delete.
(tree_evaluator::push_echo_state_cleanup): Use uwp_set_echo_state
instead of set_echo_state, set_echo_file_name, and set_echo_file_pos.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 20 Jul 2018 18:38:03 -0400 |
parents | 078b795c5219 |
children | f23f27e78aa2 00f796120a6d |
line wrap: on
line diff
--- a/liboctave/util/action-container.h Fri Jul 20 13:09:19 2018 -0700 +++ b/liboctave/util/action-container.h Fri Jul 20 18:38:03 2018 -0400 @@ -26,7 +26,7 @@ #include "octave-config.h" -#include <cstddef> +#include <functional> // This class allows registering actions in a list for later // execution, either explicitly or when the container goes out of @@ -34,9 +34,6 @@ // FIXME: is there a better name for this class? -// FIXME: we should probably be using std::function, std::bind, and -// related c++11 features to implement this functionality. - namespace octave { class @@ -71,238 +68,16 @@ { public: - fcn_elem (void (*fptr) (void)) - : e_fptr (fptr) { } - - void run (void) { e_fptr (); } - - private: - - void (*e_fptr) (void); - }; - - // An element that stores a variable of type T along with a void (*) (T) - // function pointer, and calls the function with the parameter. - - template <typename T> - class fcn_arg_elem : public elem - { - public: - - fcn_arg_elem (void (*fcn) (T), T arg) - : e_fcn (fcn), e_arg (arg) { } - - // No copying! - - fcn_arg_elem (const fcn_arg_elem&) = delete; - - fcn_arg_elem& operator = (const fcn_arg_elem&) = delete; - - void run (void) { e_fcn (e_arg); } - - private: - - void (*e_fcn) (T); - - T e_arg; - }; - - // An element that stores a variable of type T along with a - // void (*) (const T&) function pointer, and calls the function with - // the parameter. - - template <typename T> - class fcn_crefarg_elem : public elem - { - public: - - fcn_crefarg_elem (void (*fcn) (const T&), const T& arg) - : e_fcn (fcn), e_arg (arg) { } - - void run (void) { e_fcn (e_arg); } - - private: + template <typename F, typename... Args> + fcn_elem (F&& fcn, Args&&... args) + : m_fcn (std::bind (fcn, args...)) + { } - void (*e_fcn) (const T&); - - T e_arg; - }; - - // An element for calling a member function. - - template <typename T> - class method_elem : public elem - { - public: - - method_elem (T *obj, void (T::*method) (void)) - : e_obj (obj), e_method (method) { } - - method_elem (T& obj, void (T::*method) (void)) - : e_obj (&obj), e_method (method) { } - - // No copying! - - method_elem (const method_elem&) = delete; - - method_elem operator = (const method_elem&) = delete; - - void run (void) { (e_obj->*e_method) (); } - - private: - - T *e_obj; - - void (T::*e_method) (void); - }; - - // An element for calling a member function with a single argument - - template <typename T, typename A> - class method_arg_elem : public elem - { - public: - - method_arg_elem (T *obj, void (T::*method) (A), A arg) - : e_obj (obj), e_method (method), e_arg (arg) { } - - method_arg_elem (T& obj, void (T::*method) (A), A arg) - : e_obj (&obj), e_method (method), e_arg (arg) { } - - // No copying! - - method_arg_elem (const method_arg_elem&) = delete; - - method_arg_elem operator = (const method_arg_elem&) = delete; - - void run (void) { (e_obj->*e_method) (e_arg); } + void run (void) { m_fcn (); } private: - T *e_obj; - - void (T::*e_method) (A); - - A e_arg; - }; - - // An element for calling a member function with a single argument - - template <typename T, typename A> - class method_crefarg_elem : public elem - { - public: - - method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg) - : e_obj (obj), e_method (method), e_arg (arg) { } - - method_crefarg_elem (T& obj, void (T::*method) (const A&), const A& arg) - : e_obj (&obj), e_method (method), e_arg (arg) { } - - // No copying! - - method_crefarg_elem (const method_crefarg_elem&) = delete; - - method_crefarg_elem operator = (const method_crefarg_elem&) = delete; - - void run (void) { (e_obj->*e_method) (e_arg); } - - private: - - T *e_obj; - - void (T::*e_method) (const A&); - - A e_arg; - }; - - /// An element for calling a member function with two arguments - template <class T, class A, class B> - class method_arg2_elem : public elem - { - public: - method_arg2_elem (T *obj, void (T::*method) (const A&, const B&), - const A& arg_a, const B& arg_b) - : e_obj (obj), e_method (method), - e_arg_a (arg_a), e_arg_b (arg_b) { } - - void run (void) { (e_obj->*e_method) (e_arg_a, e_arg_b); } - - private: - - T *e_obj; - void (T::*e_method) (const A&, const B&); - A e_arg_a; - B e_arg_b; - - // No copying! - - method_arg2_elem (const method_arg2_elem&); - - method_arg2_elem operator = (const method_arg2_elem&); - }; - - /// An element for calling a member function with three arguments - template <class T, class A, class B, class C> - class method_arg3_elem : public elem - { - public: - method_arg3_elem (T *obj, - void (T::*method) (const A&, const B&, const C&), - const A& arg_a, const B& arg_b, const C& arg_c) - : e_obj (obj), e_method (method), - e_arg_a (arg_a), e_arg_b (arg_b), e_arg_c (arg_c) - { } - - void run (void) { (e_obj->*e_method) (e_arg_a, e_arg_b, e_arg_c); } - - private: - - T *e_obj; - void (T::*e_method) (const A&, const B&, const C&); - A e_arg_a; - B e_arg_b; - C e_arg_c; - - // No copying! - - method_arg3_elem (const method_arg3_elem&); - - method_arg3_elem operator = (const method_arg3_elem&); - }; - - /// An element for calling a member function with three arguments - template <class T, class A, class B, class C, class D> - class method_arg4_elem : public elem - { - public: - method_arg4_elem (T *obj, - void (T::*method) (const A&, const B&, const C&, const D&), - const A& arg_a, const B& arg_b, const C& arg_c, - const D& arg_d) - : e_obj (obj), e_method (method), - e_arg_a (arg_a), e_arg_b (arg_b), e_arg_c (arg_c), e_arg_d (arg_d) - { } - - void run (void) - { - (e_obj->*e_method) (e_arg_a, e_arg_b, e_arg_c, e_arg_d); - } - - private: - - T *e_obj; - void (T::*e_method) (const A&, const B&, const C&, const D&); - A e_arg_a; - B e_arg_b; - C e_arg_c; - D e_arg_d; - - // No copying! - - method_arg4_elem (const method_arg4_elem&); - - method_arg4_elem operator = (const method_arg4_elem&); + std::function<void (void)> m_fcn; }; // An element that stores arbitrary variable, and restores it. @@ -361,94 +136,33 @@ virtual ~action_container (void) = default; - virtual void add (elem *new_elem) = 0; - - // Call to void func (void). - void add_fcn (void (*fcn) (void)) - { - add (new fcn_elem (fcn)); - } - - // Call to void func (T). - template <typename T> - void add_fcn (void (*action) (T), T val) - { - add (new fcn_arg_elem<T> (action, val)); - } - - // Call to void func (const T&). - template <typename T> - void add_fcn (void (*action) (const T&), const T& val) + template <typename F, typename... Args> + void add (F&& fcn, Args&&... args) { - add (new fcn_crefarg_elem<T> (action, val)); - } - - // Call to T::method (void). - template <typename T> - void add_method (T *obj, void (T::*method) (void)) - { - add (new method_elem<T> (obj, method)); - } - - template <typename T> - void add_method (T& obj, void (T::*method) (void)) - { - add (new method_elem<T> (obj, method)); - } - - // Call to T::method (A). - template <typename T, typename A> - void add_method (T *obj, void (T::*method) (A), A arg) - { - add (new method_arg_elem<T, A> (obj, method, arg)); + add_action (new fcn_elem (std::forward<F> (fcn), + std::forward<Args> (args)...)); } - template <typename T, typename A> - void add_method (T& obj, void (T::*method) (A), A arg) - { - add (new method_arg_elem<T, A> (obj, method, arg)); - } + // Use separate template types for function pointer parameter + // declarations and captured arguments so that differences in + // const are handled properly. - // Call to T::method (const A&). - template <typename T, typename A> - void add_method (T *obj, void (T::*method) (const A&), const A& arg) + template <typename... Params, typename... Args> + void add_fcn (void (*fcn) (Params...), Args&&... args) { - add (new method_crefarg_elem<T, A> (obj, method, arg)); - } - - template <typename T, typename A> - void add_method (T& obj, void (T::*method) (const A&), const A& arg) - { - add (new method_crefarg_elem<T, A> (obj, method, arg)); + add_action (new fcn_elem (fcn, std::forward<Args> (args)...)); } - // Call to T::method (A, B). - template <class T, class A, class B> - void add_method (T *obj, void (T::*method) (const A&, const B&), - const A& arg_a, const B& arg_b) + template <typename T, typename... Params, typename... Args> + void add_method (T *obj, void (T::*method) (Params...), Args&&... args) { - add (new method_arg2_elem<T, A, B> (obj, method, arg_a, arg_b)); + add_action (new fcn_elem (method, obj, std::forward<Args> (args)...)); } - // Call to T::method (A, B, C). - template <class T, class A, class B, class C> - void add_method (T *obj, - void (T::*method) (const A&, const B&, const C&), - const A& arg_a, const B& arg_b, const C& arg_c) + template <typename T, typename... Params, typename... Args> + void add_method (T& obj, void (T::*method) (Params...), Args&&... args) { - add (new method_arg3_elem<T, A, B, C> (obj, method, arg_a, - arg_b, arg_c)); - } - - // Call to T::method (A, B, C, D). - template <class T, class A, class B, class C, class D> - void add_method (T *obj, - void (T::*method) (const A&, const B&, const C&, const D&), - const A& arg_a, const B& arg_b, - const C& arg_c, const D& arg_d) - { - add (new method_arg4_elem<T, A, B, C, D> (obj, method, arg_a, - arg_b, arg_c, arg_d)); + add_action (new fcn_elem (method, &obj, std::forward<Args> (args)...)); } // Call to delete (T*). @@ -456,21 +170,21 @@ template <typename T> void add_delete (T *obj) { - add (new delete_ptr_elem<T> (obj)); + add_action (new delete_ptr_elem<T> (obj)); } // Protect any variable. template <typename T> void protect_var (T& var) { - add (new restore_var_elem<T> (var, var)); + add_action (new restore_var_elem<T> (var, var)); } // Protect any variable, value given. template <typename T> void protect_var (T& var, const T& val) { - add (new restore_var_elem<T> (var, val)); + add_action (new restore_var_elem<T> (var, val)); } operator bool (void) const { return ! empty (); } @@ -504,6 +218,10 @@ virtual size_t size (void) const = 0; bool empty (void) const { return size () == 0; } + + protected: + + virtual void add_action (elem *new_elem) = 0; }; }