Skip to content

Instantly share code, notes, and snippets.

@vczh
Created December 20, 2017 17:34
Show Gist options
  • Save vczh/b26f5d50cc3de2ffd327d5536352f3a8 to your computer and use it in GitHub Desktop.
Save vczh/b26f5d50cc3de2ffd327d5536352f3a8 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <functional>
#include <string>
#include <vector>
using namespace std;
class Interceptor
{
using THandler = function<void(string, function<void(string)>)>;
vector<THandler> handlers;
void Next(string data, int index)
{
if (index < handlers.size())
{
handlers[index](data, [=](auto newData) {Next(newData, index + 1); });
}
}
public:
Interceptor& Child(THandler handler)
{
handlers.push_back(handler);
return *this;
}
void Handle(string data)
{
Next(data, 0);
}
};
int main()
{
Interceptor interceptor;
interceptor
.Child([](auto data, auto next) {next("[1]" + data); })
.Child([](auto data, auto next) {next("[2]" + data); })
.Child([](auto data, auto next) {cout << data << endl; })
;
interceptor.Handle("text");
return 0;
}
@IronsDu
Copy link

IronsDu commented Jan 10, 2018

#include <string>
#include <iostream>
#include <functional>
#include <memory>

template<typename... Args>
class Interceptor
{
public:
    typedef std::function<void(Args&&...)> INTERCEPTOR;
    // 处理器
    typedef std::function<void(Args&&..., const INTERCEPTOR&)> HANDLER;

    Interceptor& childHandler(HANDLER handler)
    {
        // 默认interceptor
        auto newInterceptor = std::make_shared<INTERCEPTOR>([](Args&&... buffer) {
        });

        auto wrapper = [=](Args&&... args) {
            handler(std::forward<Args>(args)..., *newInterceptor);
        };

        if (mLastInterceptor == nullptr)
        {
            mLastInterceptor = std::make_shared<INTERCEPTOR>();
        }
        else
        {
            // 修改上一个interceptor
            *mLastInterceptor = wrapper;
        }
        mLastInterceptor = newInterceptor;

        if (mReceiveChain == nullptr)
        {
            mReceiveChain = wrapper;
        }

        return *this;
    }

    void handle(Args&& ...args)
    {
        if (mReceiveChain != nullptr)
        {
            mReceiveChain(std::forward<Args>(args)...);
        }
    }

private:
    INTERCEPTOR                     mReceiveChain;
    std::shared_ptr<INTERCEPTOR>    mLastInterceptor;
};

int main(int argc, char **argv)
{
    using TestInterceptor = Interceptor<std::string, int>;

    TestInterceptor interceptor;

    interceptor
        .childHandler([](std::string&& a, int&& b, const TestInterceptor::INTERCEPTOR& next) {
            next(std::move(a), std::move(b));
        })
        .childHandler([](std::string&& a, int&& b, const TestInterceptor::INTERCEPTOR& next) {
            std::cout << a << std::endl;
        });
    interceptor.handle(std::string("test"), 1);

    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment