Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: Composer.h
- Revision:
- 5:5c91c61f50b6
- Child:
- 8:71037a47492d
diff -r 627e19790dd9 -r 5c91c61f50b6 Composer.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Composer.h Sun Apr 17 14:54:18 2016 -0500
@@ -0,0 +1,496 @@
+/* Composer
+ * Static function composition
+ */
+#ifndef COMPOSER_H
+#define COMPOSER_H
+
+#include "FuncPtr.h"
+
+
+/** Static function composition
+ */
+template <typename F, typename G>
+class Composer;
+
+/** Static function composition
+ */
+template <typename R, typename B0, typename A0, typename A1, typename A2, typename A3>
+class Composer<R(B0), B0(A0, A1, A2, A3)> {
+public:
+ /** Create an uncomposed Composer
+ */
+ Composer() {}
+
+ /** Create a Composer, composing two functions
+ */
+ Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2, A3)> g) {
+ attach(f, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM>
+ Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2, A3)> g) {
+ attach(fobj, fmethod, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename GT, typename GM>
+ Composer(FuncPtr<B0(A0, A1, A2, A3)> f, GT *gobj, GM gmethod) {
+ attach(f, gobj, gmethod);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(fobj, fmethod, gobj, gmethod);
+ }
+
+ /** Compose two functions
+ */
+ void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2, A3)> g) {
+ _f.attach(f);
+ _g.attach(g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM>
+ void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2, A3)> g) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod), g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename GT, typename GM>
+ void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
+ attach(f, FuncPtr<B0(A0, A1, A2, A3)>(gobj, gmethod));
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod),
+ FuncPtr<B0(A0, A1, A2, A3)>(gobj, gmethod));
+ }
+
+ /** Call the composed functions
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3) {
+ return _f(_g(a0, a1, a2, a3));
+ }
+
+ /** Call the composed functions
+ */
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) {
+ return call(a0, a1, a2, a3);
+ }
+
+ /** Test if functions have been composed
+ */
+ operator bool(void) const {
+ return _f && _g;
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Composer to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return static_cast<Composer<R(B0), B0(A0, A1, A2, A3)>*>(func)
+ ->call(a0, a1, a2, a3);
+ }
+
+private:
+ FuncPtr<R(B0)> _f;
+ FuncPtr<B0(A0, A1, A2, A3)> _g;
+};
+
+/** Static function composition
+ */
+template <typename R, typename B0, typename A0, typename A1, typename A2>
+class Composer<R(B0), B0(A0, A1, A2)> {
+public:
+ /** Create an uncomposed Composer
+ */
+ Composer() {}
+
+ /** Create a Composer, composing two functions
+ */
+ Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2)> g) {
+ attach(f, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM>
+ Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2)> g) {
+ attach(fobj, fmethod, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename GT, typename GM>
+ Composer(FuncPtr<B0(A0, A1, A2)> f, GT *gobj, GM gmethod) {
+ attach(f, gobj, gmethod);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(fobj, fmethod, gobj, gmethod);
+ }
+
+ /** Compose two functions
+ */
+ void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1, A2)> g) {
+ _f.attach(f);
+ _g.attach(g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM>
+ void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1, A2)> g) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod), g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename GT, typename GM>
+ void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
+ attach(f, FuncPtr<B0(A0, A1, A2)>(gobj, gmethod));
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod),
+ FuncPtr<B0(A0, A1, A2)>(gobj, gmethod));
+ }
+
+ /** Call the composed functions
+ */
+ R call(A0 a0, A1 a1, A2 a2) {
+ return _f(_g(a0, a1, a2));
+ }
+
+ /** Call the composed functions
+ */
+ R operator()(A0 a0, A1 a1, A2 a2) {
+ return call(a0, a1, a2);
+ }
+
+ /** Test if functions have been composed
+ */
+ operator bool(void) const {
+ return _f && _g;
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Composer to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
+ return static_cast<Composer<R(B0), B0(A0, A1, A2)>*>(func)
+ ->call(a0, a1, a2);
+ }
+
+private:
+ FuncPtr<R(B0)> _f;
+ FuncPtr<B0(A0, A1, A2)> _g;
+};
+
+/** Static function composition
+ */
+template <typename R, typename B0, typename A0, typename A1>
+class Composer<R(B0), B0(A0, A1)> {
+public:
+ /** Create an uncomposed Composer
+ */
+ Composer() {}
+
+ /** Create a Composer, composing two functions
+ */
+ Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1)> g) {
+ attach(f, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM>
+ Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1)> g) {
+ attach(fobj, fmethod, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename GT, typename GM>
+ Composer(FuncPtr<B0(A0, A1)> f, GT *gobj, GM gmethod) {
+ attach(f, gobj, gmethod);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(fobj, fmethod, gobj, gmethod);
+ }
+
+ /** Compose two functions
+ */
+ void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0, A1)> g) {
+ _f.attach(f);
+ _g.attach(g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM>
+ void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0, A1)> g) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod), g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename GT, typename GM>
+ void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
+ attach(f, FuncPtr<B0(A0, A1)>(gobj, gmethod));
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod),
+ FuncPtr<B0(A0, A1)>(gobj, gmethod));
+ }
+
+ /** Call the composed functions
+ */
+ R call(A0 a0, A1 a1) {
+ return _f(_g(a0, a1));
+ }
+
+ /** Call the composed functions
+ */
+ R operator()(A0 a0, A1 a1) {
+ return call(a0, a1);
+ }
+
+ /** Test if functions have been composed
+ */
+ operator bool(void) const {
+ return _f && _g;
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Composer to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0, A1 a1) {
+ return static_cast<Composer<R(B0), B0(A0, A1)>*>(func)
+ ->call(a0, a1);
+ }
+
+private:
+ FuncPtr<R(B0)> _f;
+ FuncPtr<B0(A0, A1)> _g;
+};
+
+/** Static function composition
+ */
+template <typename R, typename B0, typename A0>
+class Composer<R(B0), B0(A0)> {
+public:
+ /** Create an uncomposed Composer
+ */
+ Composer() {}
+
+ /** Create a Composer, composing two functions
+ */
+ Composer(FuncPtr<R(B0)> f, FuncPtr<B0(A0)> g) {
+ attach(f, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM>
+ Composer(FT *fobj, FM fmethod, FuncPtr<B0(A0)> g) {
+ attach(fobj, fmethod, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename GT, typename GM>
+ Composer(FuncPtr<B0(A0)> f, GT *gobj, GM gmethod) {
+ attach(f, gobj, gmethod);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(fobj, fmethod, gobj, gmethod);
+ }
+
+ /** Compose two functions
+ */
+ void attach(FuncPtr<R(B0)> f, FuncPtr<B0(A0)> g) {
+ _f.attach(f);
+ _g.attach(g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM>
+ void attach(FT *fobj, FM fmethod, FuncPtr<B0(A0)> g) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod), g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename GT, typename GM>
+ void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
+ attach(f, FuncPtr<B0(A0)>(gobj, gmethod));
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod),
+ FuncPtr<B0(A0)>(gobj, gmethod));
+ }
+
+ /** Call the composed functions
+ */
+ R call(A0 a0) {
+ return _f(_g(a0));
+ }
+
+ /** Call the composed functions
+ */
+ R operator()(A0 a0) {
+ return call(a0);
+ }
+
+ /** Test if functions have been composed
+ */
+ operator bool(void) const {
+ return _f && _g;
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Composer to call passed as void pointer
+ */
+ static R thunk(void *func, A0 a0) {
+ return static_cast<Composer<R(B0), B0(A0)>*>(func)
+ ->call(a0);
+ }
+
+private:
+ FuncPtr<R(B0)> _f;
+ FuncPtr<B0(A0)> _g;
+};
+
+/** Static function composition
+ */
+template <typename R, typename B0>
+class Composer<R(B0), B0()> {
+public:
+ /** Create an uncomposed Composer
+ */
+ Composer() {}
+
+ /** Create a Composer, composing two functions
+ */
+ Composer(FuncPtr<R(B0)> f, FuncPtr<B0()> g) {
+ attach(f, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM>
+ Composer(FT *fobj, FM fmethod, FuncPtr<B0()> g) {
+ attach(fobj, fmethod, g);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename GT, typename GM>
+ Composer(FuncPtr<B0()> f, GT *gobj, GM gmethod) {
+ attach(f, gobj, gmethod);
+ }
+
+ /** Create a Composer, composing functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ Composer(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(fobj, fmethod, gobj, gmethod);
+ }
+
+ /** Compose two functions
+ */
+ void attach(FuncPtr<R(B0)> f, FuncPtr<B0()> g) {
+ _f.attach(f);
+ _g.attach(g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM>
+ void attach(FT *fobj, FM fmethod, FuncPtr<B0()> g) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod), g);
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename GT, typename GM>
+ void attach(FuncPtr<R(B0)> f, GT *gobj, GM gmethod) {
+ attach(f, FuncPtr<B0()>(gobj, gmethod));
+ }
+
+ /** Compose functions and methods
+ */
+ template <typename FT, typename FM, typename GT, typename GM>
+ void attach(FT *fobj, FM fmethod, GT *gobj, GM gmethod) {
+ attach(FuncPtr<R(B0)>(fobj, fmethod),
+ FuncPtr<B0()>(gobj, gmethod));
+ }
+
+ /** Call the composed functions
+ */
+ R call() {
+ return _f(_g());
+ }
+
+ /** Call the composed functions
+ */
+ R operator()() {
+ return call();
+ }
+
+ /** Test if functions have been composed
+ */
+ operator bool(void) const {
+ return _f && _g;
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Composer to call passed as void pointer
+ */
+ static R thunk(void *func) {
+ return static_cast<Composer<R(B0), B0()>*>(func)
+ ->call();
+ }
+
+private:
+ FuncPtr<R(B0)> _f;
+ FuncPtr<B0()> _g;
+};
+
+
+#endif