diff --git a/src/beast/modules/beast_core/functional/SharedFunction.h b/src/beast/modules/beast_core/functional/SharedFunction.h index 9f2b416139..937942c929 100644 --- a/src/beast/modules/beast_core/functional/SharedFunction.h +++ b/src/beast/modules/beast_core/functional/SharedFunction.h @@ -25,6 +25,8 @@ template > class SharedFunction; +//------------------------------------------------------------------------------ + // nullary function // template @@ -61,6 +63,10 @@ public: //-------------------------------------------------------------------------- + SharedFunction () + { + } + template SharedFunction (F f, A a = A ()) : m_ptr (::new ( @@ -86,8 +92,15 @@ public: return *this; } - R operator() () + bool empty () const { + return m_ptr == nullptr; + } + + R operator() () const + { + bassert (! empty()); + return (*m_ptr)(); } @@ -95,5 +108,88 @@ private: SharedPtr m_ptr; }; +//------------------------------------------------------------------------------ + +// unary function (arity 1) +// +template +class SharedFunction +{ +public: + class Call : public SharedObject + { + public: + virtual R operator() (P1 p1) = 0; + }; + + template + class CallType : public Call + { + public: + typedef typename A:: template rebind >::other Allocator; + + CallType (BEAST_MOVE_ARG(F) f, A a = A ()) + : m_f (BEAST_MOVE_CAST(F)(f)) + , m_a (a) + { + } + + R operator() (P1 p1) + { + return m_f (p1); + } + + private: + F m_f; + Allocator m_a; + }; + + //-------------------------------------------------------------------------- + + SharedFunction () + { + } + + template + SharedFunction (F f, A a = A ()) + : m_ptr (::new ( + typename CallType ::Allocator (a) + .allocate (sizeof (CallType ))) + CallType (BEAST_MOVE_CAST(F)(f), a)) + { + } + + SharedFunction (SharedFunction const& other) + : m_ptr (other.m_ptr) + { + } + + SharedFunction (SharedFunction const& other, A) + : m_ptr (other.m_ptr) + { + } + + SharedFunction& operator= (SharedFunction const& other) + { + m_ptr = other.m_ptr; + return *this; + } + + bool empty () const + { + return m_ptr == nullptr; + } + + R operator() (P1 p1) const + { + bassert (! empty()); + + return (*m_ptr)(p1); + } + +private: + SharedPtr m_ptr; +}; + #endif