[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/3dcl/libhttpserver/master/src/httpserver/binders.hpp [Back]  [Original]

/*
     This file is part of libhttpserver
     Copyright (C) 2011, 2012, 2013, 2014 Sebastiano Merlino

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library 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
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
     USA
*/

#if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION)
#error "Only  or  can be included directly."
#endif

#ifndef _BINDERS_HPP_
#define _BINDERS_HPP_

namespace httpserver {
namespace details
{
    namespace binders
    {
        class generic_class;
        const int MEMFUNC_SIZE = sizeof(void (generic_class::*)());

        template
        struct converter
        {
            template
            inline static generic_class* convert(
                    X* pmem,
                    func_type func,
                    generic_mem_func_type &bound
            )
            {
                return 0;
            }
        };

        template
        struct converter
        {
            template
            inline static generic_class* convert(
                    X* pmem,
                    func_type func,
                    generic_mem_func_type &bound
            )
            {
                bound = reinterpret_cast(func);
                return reinterpret_cast(pmem);
            }
        };

        template
        class binder
        {
            private:
                typedef void (generic_class::*generic_mem_fun)();
                typedef void (*generic_mem_ptr)();

                generic_class *pmem;
                generic_mem_fun _pfunc;
                generic_mem_ptr _spfunc;

            public:
                binder()
                {
                }

                binder(const binder& o):
                    pmem(o.pmem),
                    _pfunc(o._pfunc),
                    _spfunc(o._spfunc)
                {
                }

                template
                binder(X* pmem, Y fun):
                    pmem(converter::convert(pmem, fun, _pfunc)),
                    _spfunc(0)
                {
                }

                template
                binder(DC* pp, parent_invoker invoker, static_function fun):
                    pmem(converter::convert(pp, invoker, _pfunc)),
                    _spfunc(reinterpret_cast(fun))
                {
                }

                inline generic_class* exec() const
                {
                    return pmem;
                }
                inline generic_mem get_mem_ptr() const
                {
                    return reinterpret_cast(_pfunc);
                }
                inline void_static_function get_static_func() const
                {
                    return reinterpret_cast(_spfunc);
                }
        };

        template
        class functor_one
        {
            private:
                typedef RET_TYPE (*static_function)(PAR1 p1);
                typedef RET_TYPE (*void_static_function)(PAR1 p1);
                typedef RET_TYPE (generic_class::*generic_mem)(PAR1 p1);
                typedef binder binder_type;
                binder_type _binder;

                RET_TYPE exec_static(PAR1 p1) const
                {
                    return (*(_binder.get_static_func()))(p1);
                }

                functor_one& operator=(const functor_one&)
                {
                    return *this;
                }
            public:
                typedef functor_one type;
                functor_one() { }

                template 
                functor_one(Y* pmem, RET_TYPE(X::*func)(PAR1 p1) ):
                    _binder(reinterpret_cast(pmem), func)
                {
                }

                functor_one(RET_TYPE(*func)(PAR1 p1) ):
                    _binder(this, &functor_one::exec_static, func)
                {
                }

                RET_TYPE operator() (PAR1 p1) const
                {
                    return (_binder.exec()->*(_binder.get_mem_ptr()))(p1);
                }
        };

        template
        class functor_two
        {
            private:
                typedef RET_TYPE (*static_function)(PAR1 p1, PAR2 p2);
                typedef RET_TYPE (*void_static_function)(PAR1 p1, PAR2 p2);

                typedef RET_TYPE
                    (generic_class::*generic_mem)(PAR1 p1, PAR2 p2);

                typedef binder<
                    generic_mem, static_function, void_static_function
                > binder_type;

                binder_type _binder;

                RET_TYPE exec_static(PAR1 p1, PAR2 p2) const
                {
                    return (*(_binder.get_static_func()))(p1, p2);
                }
            public:
                typedef functor_two type;
                functor_two() { }

                functor_two(const functor_two& o):
                    _binder(o._binder)
                {
                }

                template 
                functor_two(Y* pmem, RET_TYPE(X::*func)(PAR1 p1, PAR2 p2) ):
                    _binder(reinterpret_cast(pmem), func)
                {
                }
                functor_two(RET_TYPE(*func)(PAR1 p1, PAR2 p2) ):
                    _binder(this, &functor_two::exec_static, func)
                {
                }

                RET_TYPE operator() (PAR1 p1, PAR2 p2) const
                {
                    return (_binder.exec()->*(_binder.get_mem_ptr()))(p1, p2);
                }
        };
    }
}}

#endif

Web Proxy Viewer  |  New URL  |  Original Page