summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschodet2005-03-13 20:26:23 +0000
committerschodet2005-03-13 20:26:23 +0000
commitfcfd616f76345787a8eb1318e482ab1076d50039 (patch)
treeadb7200c223de2cd3839bf9c922894f48f377dae
parenta5ccb9a2944290075e032a8a18102a046841e808 (diff)
Ajout de commentaires.
Ajout de l'ObjectBinder.
-rw-r--r--2005/i/robert/src/utils/bind.hh50
-rw-r--r--2005/i/robert/src/utils/callback.hh18
-rw-r--r--2005/i/robert/src/utils/callback.tcc26
-rw-r--r--2005/i/robert/src/utils/test_any.cc2
-rw-r--r--2005/i/robert/src/utils/test_bind.cc16
5 files changed, 94 insertions, 18 deletions
diff --git a/2005/i/robert/src/utils/bind.hh b/2005/i/robert/src/utils/bind.hh
index 2a92c78..a5630fe 100644
--- a/2005/i/robert/src/utils/bind.hh
+++ b/2005/i/robert/src/utils/bind.hh
@@ -24,17 +24,21 @@
// Email: <contact@ni.fr.eu.org>
// }}}
-namespace utils {
-
+/// Class used to bind a function taking an argument to a functor taking no
+/// argument. This is not supposed to be used directly, but using the bind
+/// template function.
template<typename R, typename F, typename A>
-class binder
+class ArgBinder
{
+ /// Original function.
F func_;
+ /// Stored argument reference.
const A &arg_;
public:
+ /// Return value.
typedef R result_type;
public:
- binder (F func, const A &arg)
+ ArgBinder (F func, const A &arg)
: func_ (func), arg_ (arg)
{ }
result_type operator () (void)
@@ -43,13 +47,45 @@ class binder
}
};
+/// Bind a function taking an argument to a functor taking no argument.
+/// Return value must be specified, other template arguments can be implied.
template<typename R, typename F, typename A>
-binder<R, F, A>
+ArgBinder<R, F, A>
bind (F func, const A &arg)
{
- return binder<R, F, A> (func, arg);
+ return ArgBinder<R, F, A> (func, arg);
}
-} // namespace utils
+/// Class used to bind a member function to a functor taking no argument.
+/// This is not supposed to be used directly, but using the bind template
+/// function.
+template<typename R, typename C>
+class ObjBinder
+{
+ /// Original member function.
+ R (C::*func_) (void);
+ /// Object pointer stored.
+ C *obj_;
+ public:
+ /// Return value.
+ typedef R result_type;
+ public:
+ ObjBinder (R (C::*func) (void), C *obj)
+ : func_ (func), obj_ (obj)
+ { }
+ result_type operator () (void)
+ {
+ (obj_->*func_) ();
+ }
+};
+
+/// Bind a member function to a functor taking no argument. All template
+/// parameters must be specified.
+template<typename R, typename C>
+ObjBinder<R, C>
+bind (R (C::*func) (void), C *obj)
+{
+ return ObjBinder<R, C> (func, obj);
+}
#endif // bind_hh
diff --git a/2005/i/robert/src/utils/callback.hh b/2005/i/robert/src/utils/callback.hh
index f9eff8f..c5dc229 100644
--- a/2005/i/robert/src/utils/callback.hh
+++ b/2005/i/robert/src/utils/callback.hh
@@ -26,27 +26,41 @@
#include <stdexcept>
+/// Class to store a callback. This callback can be of any type (function or
+/// fonctor).
template<typename R>
class Callback
{
class AbstractHolder;
AbstractHolder *holder_;
public:
+ /// Return value.
typedef R result_type;
public:
+ /// Default constructor. Make an empty callback.
Callback (void);
+ /// Constructor.
template<typename T>
Callback (T callback);
+ /// Copy constructor.
Callback (const Callback &other);
+ /// Destructor.
~Callback (void);
+ /// Assignement operator.
+ Callback &operator= (const Callback &rhs);
+ /// Call the contained callback.
R operator () (void);
+ /// Swap the callback content with another callback.
void swap (Callback &rhs);
- Callback &operator= (const Callback &rhs);
+ /// Change the contained callback.
template<typename T>
Callback &operator= (T rhs);
+ /// Test if empty.
bool empty (void) const;
+ /// Test if not empty.
operator bool (void) const;
private:
+ /// Abstract container.
class AbstractHolder
{
public:
@@ -54,6 +68,7 @@ class Callback
virtual R operator () (void) = 0;
virtual AbstractHolder *clone (void) = 0;
};
+ /// Templated container.
template<typename T>
class Holder : public AbstractHolder
{
@@ -66,6 +81,7 @@ class Callback
};
};
+/// Exception thrown on call of an empty callback.
class bad_callback : public std::runtime_error
{
public:
diff --git a/2005/i/robert/src/utils/callback.tcc b/2005/i/robert/src/utils/callback.tcc
index 36d97a7..d10df75 100644
--- a/2005/i/robert/src/utils/callback.tcc
+++ b/2005/i/robert/src/utils/callback.tcc
@@ -24,12 +24,14 @@
#include <algorithm>
+/// Default constructor. Make an empty callback.
template<typename R>
Callback<R>::Callback (void)
: holder_ (0)
{
}
+/// Constructor.
template<typename R>
template<typename T>
Callback<R>::Callback (T callback)
@@ -37,18 +39,30 @@ Callback<R>::Callback (T callback)
{
}
+/// Copy constructor.
template<typename R>
Callback<R>::Callback (const Callback<R> &other)
: holder_ (other.holder_ ? other.holder_->clone () : 0)
{
}
+/// Destructor.
template<typename R>
Callback<R>::~Callback (void)
{
delete holder_;
}
+/// Assignement operator.
+template<typename R>
+Callback<R> &
+Callback<R>::operator= (const Callback<R> &rhs)
+{
+ Callback<R> (rhs).swap (*this);
+ return *this;
+}
+
+/// Call the contained callback.
template<typename R>
R
Callback<R>::operator () (void)
@@ -59,6 +73,7 @@ Callback<R>::operator () (void)
return (*holder_) ();
}
+/// Swap the callback content with another callback.
template<typename R>
void
Callback<R>::swap (Callback<R> &rhs)
@@ -66,14 +81,7 @@ Callback<R>::swap (Callback<R> &rhs)
std::swap (holder_, rhs.holder_);
}
-template<typename R>
-Callback<R> &
-Callback<R>::operator= (const Callback<R> &rhs)
-{
- Callback<R> (rhs).swap (*this);
- return *this;
-}
-
+/// Change the contained callback.
template<typename R>
template<typename T>
Callback<R> &
@@ -83,6 +91,7 @@ Callback<R>::operator= (T rhs)
return *this;
}
+/// Test if empty.
template<typename R>
bool
Callback<R>::empty (void) const
@@ -90,6 +99,7 @@ Callback<R>::empty (void) const
return !holder_;
}
+/// Test if not empty.
template<typename R>
Callback<R>::operator bool (void) const
{
diff --git a/2005/i/robert/src/utils/test_any.cc b/2005/i/robert/src/utils/test_any.cc
index e8af644..85d2319 100644
--- a/2005/i/robert/src/utils/test_any.cc
+++ b/2005/i/robert/src/utils/test_any.cc
@@ -33,7 +33,9 @@ main (int argc, char **argv)
any a (45), b (std::string ("toto")), c (5.4), d (std::string ("5"));
try
{
+ // Direct call to output operator.
std::cout << a << ' ' << b << ' ' << c << ' ' << d << std::endl;
+ // Here, it tries to extract the contained data.
std::cout << any_cast<int> (a) << std::endl;
std::cout << any_cast<std::string> (b) << std::endl;
std::cout << any_cast<double> (c) << std::endl;
diff --git a/2005/i/robert/src/utils/test_bind.cc b/2005/i/robert/src/utils/test_bind.cc
index 9ebdc4e..b883cbe 100644
--- a/2005/i/robert/src/utils/test_bind.cc
+++ b/2005/i/robert/src/utils/test_bind.cc
@@ -37,9 +37,21 @@ g (const char *s)
std::cout << "g " << s << std::endl;
}
+class H
+{
+ public:
+ void f (void)
+ {
+ std::cout << "h" << std::endl;
+ }
+};
+
int
main (void)
{
- utils::bind<void> (&f, 42) ();
- utils::bind<void> (&g, "hello world !") ();
+ // Create the callback and execute it.
+ bind<void> (&f, 42) ();
+ bind<void> (&g, "hello world !") ();
+ H h;
+ bind<void, H> (&H::f, &h) ();
}