// Copyright (c) ZeroC, Inc.

// slice2cpp version 3.8.1
// <auto-generated>Generated from Slice file 'Router.ice'.</auto-generated>

#ifndef ICE_API_EXPORTS
#   define ICE_API_EXPORTS
#endif
#define ICE_BUILDING_GENERATED_CODE

#include "Ice/Router.h"
#include <Ice/AsyncResponseHandler.h>
#include <Ice/DefaultSliceLoader.h>
#include <Ice/OutgoingAsync.h>
#include <algorithm>
#include <array>

#if defined(_MSC_VER)
#   pragma warning(disable : 4458) // declaration of ... hides class member
#   pragma warning(disable : 4996) // ... was declared deprecated
#elif defined(__clang__)
#   pragma clang diagnostic ignored "-Wshadow"
#   pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__)
#   pragma GCC diagnostic ignored "-Wshadow"
#   pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif

#ifndef ICE_DISABLE_VERSION
#   if ICE_INT_VERSION / 100 != 308
#       error Ice version mismatch!
#   endif
#   if ICE_INT_VERSION % 100 >= 50
#       error Beta header file detected
#   endif
#   if ICE_INT_VERSION % 100 < 1
#       error Ice patch level mismatch!
#   endif
#endif

Ice::RouterPrx::~RouterPrx() = default;

std::optional<Ice::ObjectPrx>
Ice::RouterPrx::getClientProxy(std::optional<bool>& iceP_hasRoutingTable, const Ice::Context& context) const
{
    auto result = IceInternal::makePromiseOutgoing<std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>>>(true, this, &RouterPrx::_iceI_getClientProxy, context).get();
    iceP_hasRoutingTable = std::get<1>(result);
    return std::move(std::get<0>(result));
}

std::future<std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>>>
Ice::RouterPrx::getClientProxyAsync(const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>>>(false, this, &RouterPrx::_iceI_getClientProxy, context);
}

std::function<void()>
Ice::RouterPrx::getClientProxyAsync(std::function<void(std::optional<Ice::ObjectPrx>, std::optional<bool>)> response, std::function<void(std::exception_ptr)> exception, std::function<void(bool)> sent, const Ice::Context& context) const
{
    auto responseCb = [response = std::move(response)](std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>>&& result) mutable
    {
        std::apply(std::move(response), std::move(result));
    };
    return IceInternal::makeLambdaOutgoing<std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>>>(std::move(responseCb), std::move(exception), std::move(sent), this, &Ice::RouterPrx::_iceI_getClientProxy, context);
}

void
Ice::RouterPrx::_iceI_getClientProxy(const std::shared_ptr<IceInternal::OutgoingAsyncT<std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>>>>& outAsync, const Ice::Context& context) const
{
    static constexpr std::string_view operationName = "getClientProxy";

    _checkTwowayOnly(operationName);
    outAsync->invoke(
        operationName,
        Ice::OperationMode::Idempotent,
        std::nullopt,
        context,
        nullptr,
        nullptr,
        [](Ice::InputStream* istr)
        {
            std::tuple<std::optional<Ice::ObjectPrx>, std::optional<bool>> v;
            istr->readAll(std::get<0>(v));
            istr->readAll({1}, std::get<1>(v));
            return v;
        });
}

std::optional<Ice::ObjectPrx>
Ice::RouterPrx::getServerProxy(const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<std::optional<Ice::ObjectPrx>>(true, this, &RouterPrx::_iceI_getServerProxy, context).get();
}

std::future<std::optional<Ice::ObjectPrx>>
Ice::RouterPrx::getServerProxyAsync(const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<std::optional<Ice::ObjectPrx>>(false, this, &RouterPrx::_iceI_getServerProxy, context);
}

std::function<void()>
Ice::RouterPrx::getServerProxyAsync(std::function<void(std::optional<Ice::ObjectPrx>)> response, std::function<void(std::exception_ptr)> exception, std::function<void(bool)> sent, const Ice::Context& context) const
{
    return IceInternal::makeLambdaOutgoing<std::optional<Ice::ObjectPrx>>(std::move(response), std::move(exception), std::move(sent), this, &Ice::RouterPrx::_iceI_getServerProxy, context);
}

void
Ice::RouterPrx::_iceI_getServerProxy(const std::shared_ptr<IceInternal::OutgoingAsyncT<std::optional<Ice::ObjectPrx>>>& outAsync, const Ice::Context& context) const
{
    static constexpr std::string_view operationName = "getServerProxy";

    _checkTwowayOnly(operationName);
    outAsync->invoke(
        operationName,
        Ice::OperationMode::Idempotent,
        std::nullopt,
        context,
        nullptr,
        nullptr);
}

::Ice::ObjectProxySeq
Ice::RouterPrx::addProxies(const ObjectProxySeq& iceP_proxies, const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<ObjectProxySeq>(true, this, &RouterPrx::_iceI_addProxies, iceP_proxies, context).get();
}

std::future<::Ice::ObjectProxySeq>
Ice::RouterPrx::addProxiesAsync(const ObjectProxySeq& iceP_proxies, const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<ObjectProxySeq>(false, this, &RouterPrx::_iceI_addProxies, iceP_proxies, context);
}

std::function<void()>
Ice::RouterPrx::addProxiesAsync(const ObjectProxySeq& iceP_proxies, std::function<void(::Ice::ObjectProxySeq)> response, std::function<void(std::exception_ptr)> exception, std::function<void(bool)> sent, const Ice::Context& context) const
{
    return IceInternal::makeLambdaOutgoing<ObjectProxySeq>(std::move(response), std::move(exception), std::move(sent), this, &Ice::RouterPrx::_iceI_addProxies, iceP_proxies, context);
}

void
Ice::RouterPrx::_iceI_addProxies(const std::shared_ptr<IceInternal::OutgoingAsyncT<ObjectProxySeq>>& outAsync, const ObjectProxySeq& iceP_proxies, const Ice::Context& context) const
{
    static constexpr std::string_view operationName = "addProxies";

    _checkTwowayOnly(operationName);
    outAsync->invoke(
        operationName,
        Ice::OperationMode::Idempotent,
        std::nullopt,
        context,
        [&](Ice::OutputStream* ostr)
        {
            ostr->writeAll(iceP_proxies);
        },
        nullptr);
}

const char*
Ice::RouterPrx::ice_staticId() noexcept
{
    return "::Ice::Router";
}

Ice::RouterFinderPrx::~RouterFinderPrx() = default;

std::optional<::Ice::RouterPrx>
Ice::RouterFinderPrx::getRouter(const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<std::optional<RouterPrx>>(true, this, &RouterFinderPrx::_iceI_getRouter, context).get();
}

std::future<std::optional<::Ice::RouterPrx>>
Ice::RouterFinderPrx::getRouterAsync(const Ice::Context& context) const
{
    return IceInternal::makePromiseOutgoing<std::optional<RouterPrx>>(false, this, &RouterFinderPrx::_iceI_getRouter, context);
}

std::function<void()>
Ice::RouterFinderPrx::getRouterAsync(std::function<void(std::optional<::Ice::RouterPrx>)> response, std::function<void(std::exception_ptr)> exception, std::function<void(bool)> sent, const Ice::Context& context) const
{
    return IceInternal::makeLambdaOutgoing<std::optional<RouterPrx>>(std::move(response), std::move(exception), std::move(sent), this, &Ice::RouterFinderPrx::_iceI_getRouter, context);
}

void
Ice::RouterFinderPrx::_iceI_getRouter(const std::shared_ptr<IceInternal::OutgoingAsyncT<std::optional<RouterPrx>>>& outAsync, const Ice::Context& context) const
{
    static constexpr std::string_view operationName = "getRouter";

    _checkTwowayOnly(operationName);
    outAsync->invoke(
        operationName,
        Ice::OperationMode::Normal,
        std::nullopt,
        context,
        nullptr,
        nullptr);
}

const char*
Ice::RouterFinderPrx::ice_staticId() noexcept
{
    return "::Ice::RouterFinder";
}

void
Ice::Router::dispatch(Ice::IncomingRequest& request, std::function<void(Ice::OutgoingResponse)> sendResponse)
{
    static constexpr std::array<std::string_view, 7> allOperations{"addProxies", "getClientProxy", "getServerProxy", "ice_id", "ice_ids", "ice_isA", "ice_ping"};

    const Ice::Current& current = request.current();
    auto r = std::equal_range(allOperations.begin(), allOperations.end(), current.operation); // NOLINT(modernize-use-ranges)
    if (r.first == r.second)
    {
        sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        return;
    }

    switch (r.first - allOperations.begin())
    {
        case 0:
        {
            _iceD_addProxies(request, std::move(sendResponse));
            break;
        }
        case 1:
        {
            _iceD_getClientProxy(request, std::move(sendResponse));
            break;
        }
        case 2:
        {
            _iceD_getServerProxy(request, std::move(sendResponse));
            break;
        }
        case 3:
        {
            _iceD_ice_id(request, std::move(sendResponse));
            break;
        }
        case 4:
        {
            _iceD_ice_ids(request, std::move(sendResponse));
            break;
        }
        case 5:
        {
            _iceD_ice_isA(request, std::move(sendResponse));
            break;
        }
        case 6:
        {
            _iceD_ice_ping(request, std::move(sendResponse));
            break;
        }
        default:
        {
            assert(false);
            sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        }
    }
}

std::vector<std::string>
Ice::Router::ice_ids(const Ice::Current&) const
{
    static const std::vector<std::string> allTypeIds = {"::Ice::Object", "::Ice::Router"};
    return allTypeIds;
}

std::string
Ice::Router::ice_id(const Ice::Current&) const
{
    return std::string{ice_staticId()};
}

void
Ice::Router::_iceD_getClientProxy(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse) const // NOLINT(performance-unnecessary-value-param)
{
    request.inputStream().skipEmptyEncapsulation();
    std::optional<bool> iceP_hasRoutingTable;
    const std::optional<Ice::ObjectPrx> ret = this->getClientProxy(iceP_hasRoutingTable, request.current());
    sendResponse(Ice::makeOutgoingResponse([&](Ice::OutputStream* ostr)
        {
            ostr->writeAll(ret);
            ostr->writeAll({1}, iceP_hasRoutingTable);
        },
        request.current()));
}

void
Ice::Router::_iceD_getServerProxy(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse) const // NOLINT(performance-unnecessary-value-param)
{
    request.inputStream().skipEmptyEncapsulation();
    const std::optional<Ice::ObjectPrx> ret = this->getServerProxy(request.current());
    sendResponse(Ice::makeOutgoingResponse([&](Ice::OutputStream* ostr)
        {
            ostr->writeAll(ret);
        },
        request.current()));
}

void
Ice::Router::_iceD_addProxies(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse) // NOLINT(performance-unnecessary-value-param)
{
    auto istr = &request.inputStream();
    istr->startEncapsulation();
    ObjectProxySeq iceP_proxies;
    istr->readAll(iceP_proxies);
    istr->endEncapsulation();
    const ObjectProxySeq ret = this->addProxies(std::move(iceP_proxies), request.current());
    sendResponse(Ice::makeOutgoingResponse([&](Ice::OutputStream* ostr)
        {
            ostr->writeAll(ret);
        },
        request.current()));
}

const char*
Ice::Router::ice_staticId() noexcept
{
    return "::Ice::Router";
}

void
Ice::RouterFinder::dispatch(Ice::IncomingRequest& request, std::function<void(Ice::OutgoingResponse)> sendResponse)
{
    static constexpr std::array<std::string_view, 5> allOperations{"getRouter", "ice_id", "ice_ids", "ice_isA", "ice_ping"};

    const Ice::Current& current = request.current();
    auto r = std::equal_range(allOperations.begin(), allOperations.end(), current.operation); // NOLINT(modernize-use-ranges)
    if (r.first == r.second)
    {
        sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        return;
    }

    switch (r.first - allOperations.begin())
    {
        case 0:
        {
            _iceD_getRouter(request, std::move(sendResponse));
            break;
        }
        case 1:
        {
            _iceD_ice_id(request, std::move(sendResponse));
            break;
        }
        case 2:
        {
            _iceD_ice_ids(request, std::move(sendResponse));
            break;
        }
        case 3:
        {
            _iceD_ice_isA(request, std::move(sendResponse));
            break;
        }
        case 4:
        {
            _iceD_ice_ping(request, std::move(sendResponse));
            break;
        }
        default:
        {
            assert(false);
            sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        }
    }
}

std::vector<std::string>
Ice::RouterFinder::ice_ids(const Ice::Current&) const
{
    static const std::vector<std::string> allTypeIds = {"::Ice::Object", "::Ice::RouterFinder"};
    return allTypeIds;
}

std::string
Ice::RouterFinder::ice_id(const Ice::Current&) const
{
    return std::string{ice_staticId()};
}

void
Ice::RouterFinder::_iceD_getRouter(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse) // NOLINT(performance-unnecessary-value-param)
{
    checkNonIdempotent(request.current());
    request.inputStream().skipEmptyEncapsulation();
    const std::optional<RouterPrx> ret = this->getRouter(request.current());
    sendResponse(Ice::makeOutgoingResponse([&](Ice::OutputStream* ostr)
        {
            ostr->writeAll(ret);
        },
        request.current()));
}

const char*
Ice::RouterFinder::ice_staticId() noexcept
{
    return "::Ice::RouterFinder";
}

void
Ice::AsyncRouter::dispatch(Ice::IncomingRequest& request, std::function<void(Ice::OutgoingResponse)> sendResponse)
{
    static constexpr std::array<std::string_view, 7> allOperations{"addProxies", "getClientProxy", "getServerProxy", "ice_id", "ice_ids", "ice_isA", "ice_ping"};

    const Ice::Current& current = request.current();
    auto r = std::equal_range(allOperations.begin(), allOperations.end(), current.operation); // NOLINT(modernize-use-ranges)
    if (r.first == r.second)
    {
        sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        return;
    }

    switch (r.first - allOperations.begin())
    {
        case 0:
        {
            _iceD_addProxies(request, std::move(sendResponse));
            break;
        }
        case 1:
        {
            _iceD_getClientProxy(request, std::move(sendResponse));
            break;
        }
        case 2:
        {
            _iceD_getServerProxy(request, std::move(sendResponse));
            break;
        }
        case 3:
        {
            _iceD_ice_id(request, std::move(sendResponse));
            break;
        }
        case 4:
        {
            _iceD_ice_ids(request, std::move(sendResponse));
            break;
        }
        case 5:
        {
            _iceD_ice_isA(request, std::move(sendResponse));
            break;
        }
        case 6:
        {
            _iceD_ice_ping(request, std::move(sendResponse));
            break;
        }
        default:
        {
            assert(false);
            sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        }
    }
}

std::vector<std::string>
Ice::AsyncRouter::ice_ids(const Ice::Current&) const
{
    static const std::vector<std::string> allTypeIds = {"::Ice::Object", "::Ice::Router"};
    return allTypeIds;
}

std::string
Ice::AsyncRouter::ice_id(const Ice::Current&) const
{
    return std::string{ice_staticId()};
}

void
Ice::AsyncRouter::_iceD_getClientProxy(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse) const
{
    request.inputStream().skipEmptyEncapsulation();
    auto responseHandler = std::make_shared<IceInternal::AsyncResponseHandler>(std::move(sendResponse), request.current());
    auto responseCb = [responseHandler](const std::optional<Ice::ObjectPrx>& ret, std::optional<bool> iceP_hasRoutingTable)
    {
        responseHandler->sendResponse(
            [&](Ice::OutputStream* ostr)
            {
                ostr->writeAll(ret);
                ostr->writeAll({1}, iceP_hasRoutingTable);
            });
    };
    try
    {
        this->getClientProxyAsync(std::move(responseCb), [responseHandler](std::exception_ptr ex) { responseHandler->sendException(ex); }, responseHandler->current());
    }
    catch (...)
    {
        responseHandler->sendException(std::current_exception());
    }
}

void
Ice::AsyncRouter::_iceD_getServerProxy(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse) const
{
    request.inputStream().skipEmptyEncapsulation();
    auto responseHandler = std::make_shared<IceInternal::AsyncResponseHandler>(std::move(sendResponse), request.current());
    auto responseCb = [responseHandler](const std::optional<Ice::ObjectPrx>& ret)
    {
        responseHandler->sendResponse(
            [&](Ice::OutputStream* ostr)
            {
                ostr->writeAll(ret);
            });
    };
    try
    {
        this->getServerProxyAsync(std::move(responseCb), [responseHandler](std::exception_ptr ex) { responseHandler->sendException(ex); }, responseHandler->current());
    }
    catch (...)
    {
        responseHandler->sendException(std::current_exception());
    }
}

void
Ice::AsyncRouter::_iceD_addProxies(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse)
{
    auto istr = &request.inputStream();
    istr->startEncapsulation();
    ObjectProxySeq iceP_proxies;
    istr->readAll(iceP_proxies);
    istr->endEncapsulation();
    auto responseHandler = std::make_shared<IceInternal::AsyncResponseHandler>(std::move(sendResponse), request.current());
    auto responseCb = [responseHandler](const ObjectProxySeq& ret)
    {
        responseHandler->sendResponse(
            [&](Ice::OutputStream* ostr)
            {
                ostr->writeAll(ret);
            });
    };
    try
    {
        this->addProxiesAsync(std::move(iceP_proxies), std::move(responseCb), [responseHandler](std::exception_ptr ex) { responseHandler->sendException(ex); }, responseHandler->current());
    }
    catch (...)
    {
        responseHandler->sendException(std::current_exception());
    }
}

const char*
Ice::AsyncRouter::ice_staticId() noexcept
{
    return "::Ice::Router";
}

void
Ice::AsyncRouterFinder::dispatch(Ice::IncomingRequest& request, std::function<void(Ice::OutgoingResponse)> sendResponse)
{
    static constexpr std::array<std::string_view, 5> allOperations{"getRouter", "ice_id", "ice_ids", "ice_isA", "ice_ping"};

    const Ice::Current& current = request.current();
    auto r = std::equal_range(allOperations.begin(), allOperations.end(), current.operation); // NOLINT(modernize-use-ranges)
    if (r.first == r.second)
    {
        sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        return;
    }

    switch (r.first - allOperations.begin())
    {
        case 0:
        {
            _iceD_getRouter(request, std::move(sendResponse));
            break;
        }
        case 1:
        {
            _iceD_ice_id(request, std::move(sendResponse));
            break;
        }
        case 2:
        {
            _iceD_ice_ids(request, std::move(sendResponse));
            break;
        }
        case 3:
        {
            _iceD_ice_isA(request, std::move(sendResponse));
            break;
        }
        case 4:
        {
            _iceD_ice_ping(request, std::move(sendResponse));
            break;
        }
        default:
        {
            assert(false);
            sendResponse(Ice::makeOutgoingResponse(std::make_exception_ptr(Ice::OperationNotExistException{__FILE__, __LINE__}), current));
        }
    }
}

std::vector<std::string>
Ice::AsyncRouterFinder::ice_ids(const Ice::Current&) const
{
    static const std::vector<std::string> allTypeIds = {"::Ice::Object", "::Ice::RouterFinder"};
    return allTypeIds;
}

std::string
Ice::AsyncRouterFinder::ice_id(const Ice::Current&) const
{
    return std::string{ice_staticId()};
}

void
Ice::AsyncRouterFinder::_iceD_getRouter(
    Ice::IncomingRequest& request,
    std::function<void(Ice::OutgoingResponse)> sendResponse)
{
    checkNonIdempotent(request.current());
    request.inputStream().skipEmptyEncapsulation();
    auto responseHandler = std::make_shared<IceInternal::AsyncResponseHandler>(std::move(sendResponse), request.current());
    auto responseCb = [responseHandler](const std::optional<RouterPrx>& ret)
    {
        responseHandler->sendResponse(
            [&](Ice::OutputStream* ostr)
            {
                ostr->writeAll(ret);
            });
    };
    try
    {
        this->getRouterAsync(std::move(responseCb), [responseHandler](std::exception_ptr ex) { responseHandler->sendException(ex); }, responseHandler->current());
    }
    catch (...)
    {
        responseHandler->sendException(std::current_exception());
    }
}

const char*
Ice::AsyncRouterFinder::ice_staticId() noexcept
{
    return "::Ice::RouterFinder";
}
