/*
 * Copyright 2018-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include <folly/experimental/pushmi/awaitable/senders.h>
#include <folly/experimental/pushmi/sender/detail/concepts.h>
#include <folly/experimental/pushmi/receiver/concepts.h>
#include <folly/experimental/pushmi/sender/primitives.h>

namespace folly {
namespace pushmi {

// add concepts to support senders
//

PUSHMI_CONCEPT_DEF(
    template(class S, class R)              //
    (concept SenderTo)(S, R),               //
    requires(S&& s, R&& r) (                //
      pushmi::submit((S &&) s, (R &&) r)    //
    ) &&
    Sender<S> && Receiver<R>
);

// add concepts to support cancellation and rate control
//

PUSHMI_CONCEPT_DEF(
  template(class S) //
  (concept FlowSender)(S), //
    Sender<S>&&
    DerivedFrom<sender_category_t<S>, flow_sender_tag>
);

PUSHMI_CONCEPT_DEF(
  template(class S, class R) //
  (concept FlowSenderTo)(S, R), //
    FlowSender<S> && //
    SenderTo<S, R>&& //
    FlowReceiver<R>
);

} // namespace pushmi
} // namespace folly
