Hi Dean.

What do you say about this interface? Take a look at the various possible 
handlers.

#include <iostream>

// Fundamental meta-functions.

struct my_specific_tag { };

template <typename T>
struct has_a_tag
{
private:
    typedef char true_type;
    struct false_type { true_type _[2]; };

    template <typename U>
    static true_type has_tag_checker(typename U::tag*);
    template <typename U>
    static false_type has_tag_checker(...);

public:
    static const bool value =
        sizeof(has_tag_checker<T>(0)) == sizeof(true_type);
};

template <typename T>
struct has_not_a_tag
{
    static const bool value = !has_a_tag<T>::value;
};

template <bool Cond, class T = void>
struct enable_if
{
    typedef T type;
};

template <class T>
struct enable_if<false, T>
{
};

// A sample framework:

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>

struct data_type
{
    data_type(const std::string& val)
        : value_(val)
    {
    }

    friend std::ostream& operator<<(std::ostream& os, const data_type& data)
    {
        return os << data.value_;
    }

private:
    std::string value_;
};

struct error_type
{
    error_type(const std::string& val)
        : value_(val)
    {
    }

    friend std::ostream& operator<<(std::ostream& os, const error_type& error)
    {
        return os << error.value_;
    }

private:
    std::string value_;
};

struct framework
{
    framework()
        : data_("No data"),
          error_("No error")
    {
    }

    template <typename T>
    typename enable_if<has_a_tag<T>::value>::type register_handler(T t)
    {
        priv_register_handler(t, typename T::tag());
    }

    template <typename T>
    typename enable_if<has_not_a_tag<T>::value>::type register_handler(T t)
    {
        data_callback_ = boost::bind<void>(t, _1, error_);
        error_callback_ = boost::bind<void>(t, data_, _1);
    }

    template <typename T1, typename T2>
    void register_handler(T1 f1, T2 f2)
    {
        data_callback_ = f1;
        error_callback_ = f2;
    }

    void call(data_type data)
    {
        data_callback_(data);
    }

    void call(error_type error)
    {
        error_callback_(error);
    }

private:
    template <typename T, typename U>
    void priv_register_handler(T t, U)
    {
        data_callback_ = boost::bind<void>(t, _1, error_);
        error_callback_ = boost::bind<void>(t, data_, _1);
    }

    template <typename T>
    void priv_register_handler(T t, my_specific_tag)
    {
        data_callback_ = boost::bind(&T::handle_data, &t, _1);
        error_callback_ = boost::bind(&T::handle_error, &t, _1);
    }

private:
    boost::function<void(data_type)> data_callback_;
    boost::function<void(error_type)> error_callback_;

    data_type data_;
    error_type error_;
};

// Handlers:

void handler1(data_type data, error_type error)
{
    std::cout << "handler1("
              << "data: '" << data << "', "
              << "error: '" << error << "')" << std::endl;
}

struct handler2
{
    void operator()(data_type data, error_type error)
    {
        std::cout << "handler2("
                  << "data: '" << data << "', "
                  << "error: '" << error << "')" << std::endl;
    }
};

struct handler3
{
    typedef my_specific_tag tag;

    void handle_data(data_type data)
    {
        std::cout << "handler3(data: '" << data << "')" << std::endl;
    }

    void handle_error(error_type error)
    {
        std::cout << "handler3(error: '" << error << "')" << std::endl;
    }
};

void handler4_data(data_type data)
{
    std::cout << "handler4(data: '" << data << "')" << std::endl;
}

void handler4_error(error_type error)
{
    std::cout << "handler4(error: '" << error << "')" << std::endl;
}

int main()
{
    data_type data("data");
    error_type error("error");

    framework frm;

    frm.register_handler(handler1);
    frm.call(data);
    frm.call(error);

    frm.register_handler(handler2());
    frm.call(data);
    frm.call(error);

    frm.register_handler(handler3());
    frm.call(data);
    frm.call(error);

    frm.register_handler(handler4_data, handler4_error);
    frm.call(data);
    frm.call(error);
}


On Feb 24, 2011, at 10:02 AM, Dean Michael Berris wrote:

> On Thu, Feb 24, 2011 at 3:55 PM, Emre Türkay <[email protected]> wrote:
>> Hi Dean,
>> 
>> On Feb 24, 2011, at 7:01 AM, Dean Michael Berris wrote:
>> 
>>> Hi Emre,
>>> 
>>> On Wed, Feb 23, 2011 at 6:22 AM, Emre Türkay <[email protected]> wrote:
>>>> Hi folks,
>>>> 
>>>> In file boost/network/protocol/http/server/sync_connection.http (in 
>>>> sync_connection::start), line 57, there is a call to Handler::log(string).
>>>> 1. This conflicts with the documentation, where there is no 
>>>> hello_world::log() method implemented in the simple http server example.
>>>> 2. Do we really need to keep it that way, i.e., we can make 
>>>> boost::system::system_error an extra argument to the handler function 
>>>> (like asio handlers). By this way, it would even be possible to implement 
>>>> a handler with a free standing function and pass the http::server a ptr to 
>>>> function instead of a functor, for simple cases.
>>>> 
>>>> What you think?
>>>> 
>>> 
>>> I like #2 -- do you have a pull request? :)
>> 
>> No, I wanted to ask before diving in. I'm still reading the docs ;) I'll try 
>> if I can make it.
>> 
> 
> Cool, no worries. :)
> 
> I suggest looking at the cases where the log function is called -- I
> think calling the handler with an extra error argument is a little
> confusing. I like the approach of providing an error handling function
> to the constructor of the HTTP server, and if one isn't provided a
> default error handler is provided that optionally prints information
> to standard error. There was a suggestion to use Boost.Log but I don't
> see how this could be done with Boost.Log not yet being in the
> releases (last I checked).
> 
> This should be easy to do and I would really appreciate it if you can
> give that a shot -- as I have very limited time at the moment to be
> able to work on the library.
> 
> Have a good one and I look forward to your pull requests!
> 
> -- 
> Dean Michael Berris
> about.me/deanberris


------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Cpp-netlib-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/cpp-netlib-devel

Reply via email to