/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 #include #include namespace apache { namespace thrift { namespace adapt_detail { // Used to detect if an adapted type has a reset method. template using HasResetType = decltype(std::declval().reset()); template constexpr bool has_reset_v = folly::is_detected_v; template using if_has_reset = std::enable_if_t, R>; template using if_has_no_reset = std::enable_if_t, R>; } // namespace adapt_detail template struct IndirectionAdapter { template static constexpr AdaptedT fromThrift(ThriftT&& value) { AdaptedT adapted; toThrift(adapted) = std::forward(value); return adapted; } FOLLY_ERASE static constexpr decltype(auto) toThrift(AdaptedT& adapted) noexcept( noexcept(::apache::thrift::apply_indirection(adapted))) { return ::apache::thrift::apply_indirection(adapted); } FOLLY_ERASE static constexpr decltype(auto) toThrift(const AdaptedT& adapted) noexcept( noexcept(::apache::thrift::apply_indirection(adapted))) { return ::apache::thrift::apply_indirection(adapted); } }; namespace type { template using indirected = adapted< ::apache::thrift::IndirectionAdapter, cpp_type< folly::remove_cvref_t<::apache::thrift::adapt_detail::thrift_t< ::apache::thrift::IndirectionAdapter, folly::remove_cvref_t>>, Tag>>; } template struct StaticCastAdapter { template static constexpr decltype(auto) fromThrift(T&& value) { return static_cast(std::forward(value)); } template static constexpr decltype(auto) toThrift(T&& value) { return static_cast(std::forward(value)); } }; template struct InlineAdapter { template static decltype(auto) toThrift(U&& value) { return std::forward(value).toThrift(); } // If an adapted type (e.g. type::detail::Wrap) has a reset method, use it. template static adapt_detail::if_has_reset clear(U& value) { value.reset(); } template static auto encode(Protocol& prot_, const U& u) -> decltype(u.encode(prot_)) { return u.encode(prot_); } template static auto decode(Protocol& prot_, U& u) -> decltype(u.decode(prot_)) { u.decode(prot_); } template static adapt_detail::if_has_no_reset clear(U& value) { static_assert( adapt_detail::is_mutable_ref::value, "not a mutable reference"); apache::thrift::op::clear<>(value.toThrift()); } template static T fromThrift(U&& value) { return T{std::forward(value)}; } template static bool isEmpty(const U& value) { return value.empty(); } }; } // namespace thrift } // namespace apache