/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License Version 2.0 with LLVM Exceptions * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * https://llvm.org/LICENSE.txt * * 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 #include #include #include namespace unifex { namespace _adapt_stream { template struct _adapted { struct type; }; template using adapted = typename _adapted< remove_cvref_t, std::decay_t, std::decay_t>::type; template struct _adapted::type { Stream innerStream_; NextAdaptFunc nextAdapter_; CleanupAdaptFunc cleanupAdapter_; friend auto tag_invoke(tag_t, type& s) -> std::invoke_result_t> { return std::invoke(s.nextAdapter_, next(s.innerStream_)); } friend auto tag_invoke(tag_t, type& s) -> std::invoke_result_t> { return std::invoke(s.cleanupAdapter_, cleanup(s.innerStream_)); } }; template struct _adapted { struct type; }; template struct _adapted::type { Stream innerStream_; AdaptFunc adapter_; friend auto tag_invoke(tag_t, type& s) -> std::invoke_result_t> { return std::invoke(s.adapter_, next(s.innerStream_)); } friend auto tag_invoke(tag_t, type& s) -> std::invoke_result_t> { return std::invoke(s.adapter_, cleanup(s.innerStream_)); } }; } // namespace _adapt_stream namespace _adapt_stream_cpo { inline const struct _fn { template auto operator()(Stream&& stream, AdapterFunc&& adapt) const -> _adapt_stream::adapted { return {(Stream &&) stream, (AdapterFunc &&) adapt}; } template < typename Stream, typename NextAdapterFunc, typename CleanupAdapterFunc> auto operator()( Stream&& stream, NextAdapterFunc&& adaptNext, CleanupAdapterFunc&& adaptCleanup) const -> _adapt_stream::adapted { return { (Stream &&) stream, (NextAdapterFunc &&) adaptNext, (CleanupAdapterFunc &&) adaptCleanup}; } } adapt_stream {}; } // namespace _adapt_stream_cpo using _adapt_stream_cpo::adapt_stream; } // namespace unifex #include