Orders OrderBook::cross() {
    sort(orders_);
    size_t indicativeQuantity = 0;
    size_t currentBidQuantity = totalBid_;
    size_t currentAskQuantity = 0;
    double indicativePrice = 1e9;
    for (const auto& o : orders_) {
        if (o.isBid_) {
            currentBidQuantity -= o.quantity_;
        } else {
            currentAskQuantity += o.quantity_;
        }
        auto quantity = min(currentBidQuantity, currentAskQuantity);
        if (quantity > indicativeQuantity) {
            indicativePrice = o.price_;
            indicativeQuantity = o.quantity_;
        }
    }

    Orders result;

    for (auto toOrder = orders_.begin(); toOrder != orders_.end();) {
        bool include = false;
        if (toOrder->isBid_) {
            if (toOrder->price_ >= indicativePrice) {
                include = true;
            }
        } else {
            if (toOrder->price_ <= indicativePrice) {
                include = true;
            }
        }

        if (include) {
            if (toOrder->quantity_ <= indicativeQuantity) {
                indicativeQuantity -= toOrder->quantity_;
                result.emplace_back(*toOrder);
                orders_.erase(toOrder);
            } else {
                indicativeQuantity = 0;
                toOrder->quantity_ -= indicativeQuantity;
                ++toOrder;
            }
        } else {
            ++toOrder;
        }

        if (0 == indicativeQuantity) {
            break;
        }
    }

    return result;
}