From 5c9b155911cb74f3db2946609c6d7a605e5b7afa Mon Sep 17 00:00:00 2001 From: dufourj Date: Fri, 24 Mar 2006 13:42:48 +0000 Subject: Tester : - découpage en Interpreter ; - Tester ne s'occupe plus que de récupérer les options de la ligne de commandes et les donner à Interpreter. TODO : - gérer le chargement des commandes depuis un fichier. --- i/marvin/src/Makefile.defs | 4 +- i/marvin/src/interpreter/Makefile.defs | 5 + i/marvin/src/interpreter/interpreter.cc | 67 +++++++++++++ i/marvin/src/interpreter/interpreter.hh | 72 ++++++++++++++ i/marvin/src/interpreter/interpreter.tcc | 137 ++++++++++++++++++++++++++ i/marvin/src/interpreter/test_interpreter.cc | 106 ++++++++++++++++++++ i/marvin/src/tester/Makefile.defs | 4 +- i/marvin/src/tester/test_tester.cc | 57 ++--------- i/marvin/src/tester/tester.cc | 141 +++------------------------ i/marvin/src/tester/tester.hh | 48 +-------- i/marvin/src/tester/tester.tcc | 137 -------------------------- 11 files changed, 417 insertions(+), 361 deletions(-) create mode 100644 i/marvin/src/interpreter/Makefile.defs create mode 100644 i/marvin/src/interpreter/interpreter.cc create mode 100644 i/marvin/src/interpreter/interpreter.hh create mode 100644 i/marvin/src/interpreter/interpreter.tcc create mode 100644 i/marvin/src/interpreter/test_interpreter.cc delete mode 100644 i/marvin/src/tester/tester.tcc (limited to 'i') diff --git a/i/marvin/src/Makefile.defs b/i/marvin/src/Makefile.defs index 45c40d7..285264a 100644 --- a/i/marvin/src/Makefile.defs +++ b/i/marvin/src/Makefile.defs @@ -20,9 +20,9 @@ endif CXXFLAGS += -fmessage-length=0 SUBDIRS = utils utils/meta \ - tester \ + interpreter config tester \ log serial timer \ - config data scheduler \ + data scheduler \ proto asserv \ motor diff --git a/i/marvin/src/interpreter/Makefile.defs b/i/marvin/src/interpreter/Makefile.defs new file mode 100644 index 0000000..d1aac01 --- /dev/null +++ b/i/marvin/src/interpreter/Makefile.defs @@ -0,0 +1,5 @@ +PROGRAMS += test_interpreter + +interpreter_OBJECTS = interpreter.o $(utils_OBJECTS) + +test_interpreter_OBJECTS = test_interpreter.o $(interpreter_OBJECTS) diff --git a/i/marvin/src/interpreter/interpreter.cc b/i/marvin/src/interpreter/interpreter.cc new file mode 100644 index 0000000..4b034e3 --- /dev/null +++ b/i/marvin/src/interpreter/interpreter.cc @@ -0,0 +1,67 @@ +// interpreter.cc +// marvin - programme du robot 2006. {{{ +// +// Copyright (C) 2006 Nicolas Schodet +// +// Robot APB Team/Efrei 2006. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "interpreter.hh" + +/// Destructor. +Interpreter::~Interpreter (void) +{ + for (Funcs::iterator i = funcs_.begin (); i != funcs_.end (); ++i) + { + delete i->second; + } +} + +/// Add a function, Interpreter owns f. +void +Interpreter::add (const std::string &s, Func *f) +{ + if (!funcs_.insert (Funcs::value_type (s, f)).second) + { + // Interpreter owns f, therefore, f must be deleted. + delete f; + throw std::runtime_error ("function \'" + s + + "\' inserted two times"); + } +} + +/// Call a function by name. +bool +Interpreter::call (const std::string &s, const Args &a) const +{ + Funcs::const_iterator i; + i = funcs_.find (s); + if (i == funcs_.end ()) + throw std::runtime_error ("function \'" + s + "\' does not exist"); + try + { + return (*i->second) (a); + } + catch (const std::exception &e) + { + throw std::runtime_error ("while calling \'" + s + "\', " + + e.what ()); + } +} + diff --git a/i/marvin/src/interpreter/interpreter.hh b/i/marvin/src/interpreter/interpreter.hh new file mode 100644 index 0000000..729f321 --- /dev/null +++ b/i/marvin/src/interpreter/interpreter.hh @@ -0,0 +1,72 @@ +#ifndef interpreter_hh +#define interpreter_hh +// interpreter.hh +// marvin - programme du robot 2006. {{{ +// +// Copyright (C) 2006 Nicolas Schodet +// +// Robot APB Team/Efrei 2006. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "utils/any.hh" + +#include + +class Interpreter +{ + public: + /// Function arguments. + typedef any Arg; + /// Function arguments list. + typedef std::list Args; + /// Functions must inherit from this type. + class Func + { + public: + /// Mandatory virtual destructor. + virtual ~Func (void) + { } + /// Called on function invocation, getting the argument list and + /// returning true on success. + virtual bool operator() (const Args &) = 0; + }; + private: + /// Func class construction helper. + template + class MemFunc; + private: + /// Type of the private function map. + typedef std::map Funcs; + /// The function map itself. + Funcs funcs_; + public: + /// Destructor. + ~Interpreter (void); + /// Add a function, Interpreter owns f. + void add (const std::string &s, Func *f); + /// Call a function by name. + bool call (const std::string &s, const Args &a) const; + /// Take all the template sophistications out of the programmer hands. + template + static Func *memFunc (T &i, F f); +}; + +#include "interpreter.tcc" + +#endif // interpreter_hh diff --git a/i/marvin/src/interpreter/interpreter.tcc b/i/marvin/src/interpreter/interpreter.tcc new file mode 100644 index 0000000..0e4fcf9 --- /dev/null +++ b/i/marvin/src/interpreter/interpreter.tcc @@ -0,0 +1,137 @@ +#ifndef interpreter_tcc +#define interpreter_tcc +// interpreter.tcc +// marvin - programme du robot 2006. {{{ +// +// Copyright (C) 2006 Nicolas Schodet +// +// Robot APB Team/Efrei 2006. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "utils/meta/remove_reference.hh" + +#include + +/// Func class construction helper. +template +class Interpreter::MemFunc +{ +}; + +/// Partially specialised for member functions taking an arguments list. +template +class Interpreter::MemFunc : public Func +{ + T &i_; + typedef bool (T::*F) (const Interpreter::Args &); + F f_; + public: + MemFunc (T &i, F f) : i_ (i), f_ (f) { } + bool operator() (const Args &a) + { + return (i_.*f_) (a); + } +}; + +/// Partially specialised for members functions taking no argument. +template +class Interpreter::MemFunc : public Func +{ + T &i_; + typedef bool (T::*F) (void); + F f_; + public: + MemFunc (T &i, F f) : i_ (i), f_ (f) { } + bool operator() (const Args &a) + { + if (!a.empty ()) + throw std::runtime_error ("no argument expected"); + return (i_.*f_) (); + } +}; + +/// Partially specialised for members functions taking one argument. +template +class Interpreter::MemFunc : public Func +{ + T &i_; + typedef bool (T::*F) (A1); + F f_; + public: + MemFunc (T &i, F f) : i_ (i), f_ (f) { } + bool operator() (const Args &a) + { + Args::const_iterator i = a.begin (); + if (a.size () != 1) + throw std::runtime_error ("one argument expected"); + A1 a1 = any_cast::type> (*i); + return (i_.*f_) (a1); + } +}; + +/// Partially specialised for members functions taking two arguments. +template +class Interpreter::MemFunc : public Func +{ + T &i_; + typedef bool (T::*F) (A1, A2); + F f_; + public: + MemFunc (T &i, F f) : i_ (i), f_ (f) { } + bool operator() (const Args &a) + { + Args::const_iterator i = a.begin (); + if (a.size () != 2) + throw std::runtime_error ("two arguments expected"); + A1 a1 = any_cast::type> (*i); + A2 a2 = any_cast::type> (*++i); + return (i_.*f_) (a1, a2); + } +}; + +/// Partially specialised for members functions taking three arguments. +template +class Interpreter::MemFunc : public Func +{ + T &i_; + typedef bool (T::*F) (A1, A2, A3); + F f_; + public: + MemFunc (T &i, F f) : i_ (i), f_ (f) { } + bool operator() (const Args &a) + { + Args::const_iterator i = a.begin (); + if (a.size () != 3) + throw std::runtime_error ("three arguments expected"); + A1 a1 = any_cast::type> (*i); + A2 a2 = any_cast::type> (*++i); + A3 a3 = any_cast::type> (*++i); + return (i_.*f_) (a1, a2, a3); + } +}; + +/// Take all the template sophistications out of the programmer hands. +template +Interpreter::Func * +Interpreter::memFunc (T &i, F f) +{ + return new MemFunc (i, f); +} + +#endif // interpreter_tcc diff --git a/i/marvin/src/interpreter/test_interpreter.cc b/i/marvin/src/interpreter/test_interpreter.cc new file mode 100644 index 0000000..99a9ad9 --- /dev/null +++ b/i/marvin/src/interpreter/test_interpreter.cc @@ -0,0 +1,106 @@ +// test_interpreter.cc +// marvin - programme du robot 2006. {{{ +// +// Copyright (C) 2006 Nicolas Schodet +// +// Robot APB Team/Efrei 2006. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "interpreter.hh" + +#include +#include +#include + +class TestInterpreter +{ + Interpreter t; + public: + bool funcA (const Interpreter::Args &a) + { + std::cout << " a " << a << std::endl; + return true; + } + bool funcB (void) + { + std::cout << " b ( )" << std::endl; + return true; + } + bool funcC (int i) + { + std::cout << " c ( " << i << " )" << std::endl; + return true; + } + bool funcD (const std::string &s) + { + std::cout << " d ( " << s << " )" << std::endl; + return true; + } + bool funcE (int i, const std::string &s, double d) + { + std::cout << " e ( " << i << ' ' << s << ' ' << d << " )" << std::endl; + return true; + } + void call (const std::string &s, const Interpreter::Args &a) + { + try + { + std::cout << "call " << s << ' ' << a << std::endl; + t.call (s, a); + } + catch (const std::exception &e) + { + // Do not use std::cerr as there should be only normal errors. + std::cout << ' ' << e.what () << std::endl; + } + } + int main (void) + { + Interpreter::Args a[4]; + // Add functions. + t.add ("a", Interpreter::memFunc (*this, &TestInterpreter::funcA)); + t.add ("b", Interpreter::memFunc (*this, &TestInterpreter::funcB)); + t.add ("c", Interpreter::memFunc (*this, &TestInterpreter::funcC)); + t.add ("d", Interpreter::memFunc (*this, &TestInterpreter::funcD)); + t.add ("e", Interpreter::memFunc (*this, &TestInterpreter::funcE)); + // Make argument lists. + a[1].push_back (71117); + a[2].push_back (std::string ("robert")); + a[3].push_back (42); + a[3].push_back (std::string ("merguez")); + a[3].push_back (51.1664); + // Call all those wonderful functions. + call ("unknown", a[0]); + for (unsigned int i = 0; i < sizeof (a) / sizeof (a[0]); ++i) + { + call ("a", a[i]); + call ("b", a[i]); + call ("c", a[i]); + call ("d", a[i]); + call ("e", a[i]); + } + return 0; + } +}; + +int main (void) +{ + TestInterpreter tt; + return tt.main (); +} diff --git a/i/marvin/src/tester/Makefile.defs b/i/marvin/src/tester/Makefile.defs index 6c1b60d..ec5bd6a 100644 --- a/i/marvin/src/tester/Makefile.defs +++ b/i/marvin/src/tester/Makefile.defs @@ -1,5 +1,5 @@ PROGRAMS += test_tester -tester_OBJECTS = tester.o $(config_OBJECTS) +tester_OBJECTS = tester.o $(config_OBJECTS) $(interpreter_OBJECTS) -test_tester_OBJECTS = test_tester.o $(tester_OBJECTS) $(utils_OBJECTS) +test_tester_OBJECTS = test_tester.o $(tester_OBJECTS) diff --git a/i/marvin/src/tester/test_tester.cc b/i/marvin/src/tester/test_tester.cc index 6e1c208..3075552 100644 --- a/i/marvin/src/tester/test_tester.cc +++ b/i/marvin/src/tester/test_tester.cc @@ -24,10 +24,6 @@ // }}} #include "tester.hh" -#include -#include -#include - class TestTester { Tester t; @@ -35,7 +31,7 @@ class TestTester // Constructor TestTester (int argc, char ** argv) : t (argc, argv) { } - bool funcA (const Tester::Args &a) + bool funcA (const Interpreter::Args &a) { std::cout << " a " << a << std::endl; return true; @@ -60,52 +56,17 @@ class TestTester std::cout << " e ( " << i << ' ' << s << ' ' << d << " )" << std::endl; return true; } - void call (const std::string &s, const Tester::Args &a) - { - try - { - std::cout << "call " << s << ' ' << a << std::endl; - t.call (s, a); - } - catch (const std::exception &e) - { - // Do not use std::cerr as there should be only normal errors. - std::cout << ' ' << e.what () << std::endl; - } - } - int run (void) + int main (void) { - t.add ("m", Tester::memFunc (*this, &TestTester::main)); + // Add functions. + t.add ("a", Interpreter::memFunc (*this, &TestTester::funcA)); + t.add ("b", Interpreter::memFunc (*this, &TestTester::funcB)); + t.add ("c", Interpreter::memFunc (*this, &TestTester::funcC)); + t.add ("d", Interpreter::memFunc (*this, &TestTester::funcD)); + t.add ("e", Interpreter::memFunc (*this, &TestTester::funcE)); t.run (); return 0; } - bool main (void) - { - Tester::Args a[4]; - // Add functions. - t.add ("a", Tester::memFunc (*this, &TestTester::funcA)); - t.add ("b", Tester::memFunc (*this, &TestTester::funcB)); - t.add ("c", Tester::memFunc (*this, &TestTester::funcC)); - t.add ("d", Tester::memFunc (*this, &TestTester::funcD)); - t.add ("e", Tester::memFunc (*this, &TestTester::funcE)); - // Make argument lists. - a[1].push_back (71117); - a[2].push_back (std::string ("robert")); - a[3].push_back (42); - a[3].push_back (std::string ("merguez")); - a[3].push_back (51.1664); - // Call all those wonderful functions. - call ("unknown", a[0]); - for (unsigned int i = 0; i < sizeof (a) / sizeof (a[0]); ++i) - { - call ("a", a[i]); - call ("b", a[i]); - call ("c", a[i]); - call ("d", a[i]); - call ("e", a[i]); - } - return true; - } }; int @@ -114,7 +75,7 @@ main (int argc, char **argv) TestTester tt (argc, argv); try { - return tt.run (); + return tt.main (); } catch (const std::exception &e) { diff --git a/i/marvin/src/tester/tester.cc b/i/marvin/src/tester/tester.cc index 3251fbb..5b93fd8 100644 --- a/i/marvin/src/tester/tester.cc +++ b/i/marvin/src/tester/tester.cc @@ -24,28 +24,18 @@ // }}} #include "tester.hh" -#include -#include -#include -#include +#include // getopt +#include // std::exception +#include // std::exit /// Constructor. Tester::Tester (int argc, char **argv) - : config_ (argc, argv), program_(argv[0]), commands_ ("") + : config_ (argc, argv), program_(argv[0]) { // Parse command line getOpt (argc, argv); } -/// Destructor. -Tester::~Tester (void) -{ - for (Funcs::iterator i = funcs_.begin (); i != funcs_.end (); ++i) - { - delete i->second; - } -} - /// Getopt command line. /// Supported arguemnts : /// - -c "commands list" @@ -60,7 +50,7 @@ Tester::getOpt (int argc, char **argv) { std::cerr << "Argument missing." << std::endl; usage (); - exit (1); + std::exit (1); } // Automatic error message @@ -71,12 +61,12 @@ Tester::getOpt (int argc, char **argv) switch (option) { case 'c': - commands_ = optarg; + commands_.append (optarg); break; case '?': default: usage (); - exit (2); + std::exit (2); break; } } @@ -84,131 +74,24 @@ Tester::getOpt (int argc, char **argv) /// Print usage to stdout. void -Tester::usage (void) +Tester::usage (void) const { std::cout << "Usage: " << program_ << " [-c ]" << std::endl; } -/// Run command list. -/// If check is true, the command list will be checked, otherwise, it -/// will be executed. If check failed, it throw an exception. -void -Tester::parse (const std::string &commands, bool check) -{ - Args argList; - std::istringstream list_commands (commands); - std::string commandargs, command, args; - std::string::size_type pos; - - // Cut it by ; - while (std::getline (list_commands, commandargs, ';')) - { - argList.clear (); - // Remove space at begining - pos = commandargs.find_first_not_of (' '); - // For empty command... - if (pos != std::string::npos) - { - commandargs = commandargs.substr - (commandargs.find_first_not_of (' ')); - // Remove space at end - commandargs = commandargs.substr - (0, commandargs.find_last_not_of (' ') + 1); - // Get the command - pos = commandargs.find_first_of (' '); - command = commandargs.substr (0, pos); - // Args ? - if (pos != std::string::npos) - { - args = commandargs.substr (pos); - pos = 0; - do - { - // Next - args = args.substr (pos); - // Remove space at begining - args = args.substr (args.find_first_not_of (' ')); - // Get the end position of the first arg - pos = args.find_first_of (' '); - // Add args - // TODO type ? - argList.push_back (args.substr (0, pos)); - } - while (pos != std::string::npos); - } - if (check) - { - // TODO Check args - if (!exist (command)) - throw std::runtime_error ("Unknow command : " + command); - } - else - call (command, argList); - } - } -} - -/// Check function exists. -bool -Tester::exist (const std::string &s) -{ - Funcs::const_iterator i; - i = funcs_.find (s); - if (i == funcs_.end ()) - return false; - else - return true; -} /// Add a test function, Tester owns f. void -Tester::add (const std::string &s, Func *f) +Tester::add (const std::string &s, Interpreter::Func *f) { - if (!funcs_.insert (Funcs::value_type (s, f)).second) - { - // Tester owns f, therefore, f must be deleted. - delete f; - throw std::runtime_error ("function \'" + s - + "\' inserted two times"); - } -} - -/// Call a test function by name. -bool -Tester::call (const std::string &s, const Args &a) const -{ - Funcs::const_iterator i; - i = funcs_.find (s); - if (i == funcs_.end ()) - throw std::runtime_error ("function \'" + s + "\' does not exist"); - try - { - return (*i->second) (a); - } - catch (const std::exception &e) - { - throw std::runtime_error ("while calling \'" + s + "\', " - + e.what ()); - } + interpreter_.add (s, f); } void Tester::run (void) { - if (commands_.size () < 1) - throw std::runtime_error ("Nothing to do"); - // Check commands - try - { - parse (commands_, true); - } - catch (const std::exception &e) - { - std::cerr << "Error : " << e.what () << std::endl; - usage (); - exit (3); - } - parse (commands_, false); + // TODO called interpreter with the commands_, in check mode then in run + // mode. } diff --git a/i/marvin/src/tester/tester.hh b/i/marvin/src/tester/tester.hh index e38967d..c476125 100644 --- a/i/marvin/src/tester/tester.hh +++ b/i/marvin/src/tester/tester.hh @@ -24,71 +24,33 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // }}} -#include "utils/any.hh" #include "config/config.hh" +#include "interpreter/interpreter.hh" -#include #include class Tester { - public: - /// Test function argument. - typedef any Arg; - /// Test function argument list. - typedef std::list Args; - /// Test functions must inherit from this type. - class Func - { - public: - /// Mandatory virtual destructor. - virtual ~Func (void) - { } - /// Called on function invocation, getting the argument list and - /// returning true on success. - virtual bool operator() (const Args &) = 0; - }; - private: - /// Func class construction helper. - template - class MemFunc; private: - /// Type of the private function map. - typedef std::map Funcs; - /// The function map itself. - Funcs funcs_; /// The config. Config config_; + /// The interperter + Interpreter interpreter_; /// Program name. std::string program_; /// Commands to parse. std::string commands_; /// Getopt command line. void getOpt (int argc, char **argv); - /// Run command list. - /// If check is true, the command list will be checked, otherwise, it - /// will be executed. If check failed, it throw an exception. - void parse (const std::string &command, bool check); /// Print usage to stdout. - void usage (void); + void usage (void) const; public: /// Constructor. Tester (int argc, char ** argv); - /// Destructor. - ~Tester (void); /// Add a test function, Tester owns f. - void add (const std::string &s, Func *f); - /// Call a test function by name. - bool call (const std::string &s, const Args &a) const; - /// Check function exists. - bool exist (const std::string &s); - /// Take all the template sophistications out of the programmer hands. - template - static Func *memFunc (T &i, F f); + void add (const std::string &s, Interpreter::Func *f); /// Run commands. void run (void); }; -#include "tester.tcc" - #endif // tester_hh diff --git a/i/marvin/src/tester/tester.tcc b/i/marvin/src/tester/tester.tcc deleted file mode 100644 index 56d066b..0000000 --- a/i/marvin/src/tester/tester.tcc +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef tester_tcc -#define tester_tcc -// tester.tcc -// marvin - programme du robot 2006. {{{ -// -// Copyright (C) 2006 Nicolas Schodet -// -// Robot APB Team/Efrei 2006. -// Web: http://assos.efrei.fr/robot/ -// Email: robot AT efrei DOT fr -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// }}} -#include "utils/meta/remove_reference.hh" - -#include - -/// Func class construction helper. -template -class Tester::MemFunc -{ -}; - -/// Partially specialised for member functions taking an argument list. -template -class Tester::MemFunc : public Func -{ - T &i_; - typedef bool (T::*F) (const Tester::Args &); - F f_; - public: - MemFunc (T &i, F f) : i_ (i), f_ (f) { } - bool operator() (const Args &a) - { - return (i_.*f_) (a); - } -}; - -/// Partially specialised for member functions taking no argument. -template -class Tester::MemFunc : public Func -{ - T &i_; - typedef bool (T::*F) (void); - F f_; - public: - MemFunc (T &i, F f) : i_ (i), f_ (f) { } - bool operator() (const Args &a) - { - if (!a.empty ()) - throw std::runtime_error ("no argument expected"); - return (i_.*f_) (); - } -}; - -/// Partially specialised for member functions taking one argument. -template -class Tester::MemFunc : public Func -{ - T &i_; - typedef bool (T::*F) (A1); - F f_; - public: - MemFunc (T &i, F f) : i_ (i), f_ (f) { } - bool operator() (const Args &a) - { - Args::const_iterator i = a.begin (); - if (a.size () != 1) - throw std::runtime_error ("one argument expected"); - A1 a1 = any_cast::type> (*i); - return (i_.*f_) (a1); - } -}; - -/// Partially specialised for member functions taking two argument. -template -class Tester::MemFunc : public Func -{ - T &i_; - typedef bool (T::*F) (A1, A2); - F f_; - public: - MemFunc (T &i, F f) : i_ (i), f_ (f) { } - bool operator() (const Args &a) - { - Args::const_iterator i = a.begin (); - if (a.size () != 2) - throw std::runtime_error ("two argument expected"); - A1 a1 = any_cast::type> (*i); - A2 a2 = any_cast::type> (*++i); - return (i_.*f_) (a1, a2); - } -}; - -/// Partially specialised for member functions taking three argument. -template -class Tester::MemFunc : public Func -{ - T &i_; - typedef bool (T::*F) (A1, A2, A3); - F f_; - public: - MemFunc (T &i, F f) : i_ (i), f_ (f) { } - bool operator() (const Args &a) - { - Args::const_iterator i = a.begin (); - if (a.size () != 3) - throw std::runtime_error ("three argument expected"); - A1 a1 = any_cast::type> (*i); - A2 a2 = any_cast::type> (*++i); - A3 a3 = any_cast::type> (*++i); - return (i_.*f_) (a1, a2, a3); - } -}; - -/// Take all the template sophistications out of the programmer hands. -template -Tester::Func * -Tester::memFunc (T &i, F f) -{ - return new MemFunc (i, f); -} - -#endif // tester_tcc -- cgit v1.2.3