File indexing completed on 2025-08-28 08:27:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #pragma once
0019
0020 #include <memory>
0021 #include <tuple>
0022 #include <type_traits>
0023
0024 #include "arrow/result.h"
0025 #include "arrow/util/macros.h"
0026
0027 namespace arrow {
0028 namespace internal {
0029
0030 struct Empty {
0031 static Result<Empty> ToResult(Status s) {
0032 if (ARROW_PREDICT_TRUE(s.ok())) {
0033 return Empty{};
0034 }
0035 return s;
0036 }
0037 };
0038
0039
0040
0041 struct call_traits {
0042 public:
0043 template <typename R, typename... A>
0044 static std::false_type is_overloaded_impl(R(A...));
0045
0046 template <typename F>
0047 static std::false_type is_overloaded_impl(decltype(&F::operator())*);
0048
0049 template <typename F>
0050 static std::true_type is_overloaded_impl(...);
0051
0052 template <typename F, typename R, typename... A>
0053 static R return_type_impl(R (F::*)(A...));
0054
0055 template <typename F, typename R, typename... A>
0056 static R return_type_impl(R (F::*)(A...) const);
0057
0058 template <std::size_t I, typename F, typename R, typename... A>
0059 static typename std::tuple_element<I, std::tuple<A...>>::type argument_type_impl(
0060 R (F::*)(A...));
0061
0062 template <std::size_t I, typename F, typename R, typename... A>
0063 static typename std::tuple_element<I, std::tuple<A...>>::type argument_type_impl(
0064 R (F::*)(A...) const);
0065
0066 template <std::size_t I, typename F, typename R, typename... A>
0067 static typename std::tuple_element<I, std::tuple<A...>>::type argument_type_impl(
0068 R (F::*)(A...) &&);
0069
0070 template <typename F, typename R, typename... A>
0071 static std::integral_constant<int, sizeof...(A)> argument_count_impl(R (F::*)(A...));
0072
0073 template <typename F, typename R, typename... A>
0074 static std::integral_constant<int, sizeof...(A)> argument_count_impl(R (F::*)(A...)
0075 const);
0076
0077 template <typename F, typename R, typename... A>
0078 static std::integral_constant<int, sizeof...(A)> argument_count_impl(R (F::*)(A...) &&);
0079
0080
0081
0082
0083 template <typename F>
0084 using is_overloaded =
0085 decltype(is_overloaded_impl<typename std::decay<F>::type>(NULLPTR));
0086
0087 template <typename F, typename T = void>
0088 using enable_if_overloaded = typename std::enable_if<is_overloaded<F>::value, T>::type;
0089
0090 template <typename F, typename T = void>
0091 using disable_if_overloaded =
0092 typename std::enable_if<!is_overloaded<F>::value, T>::type;
0093
0094
0095
0096 template <std::size_t I, typename F>
0097 using argument_type = decltype(argument_type_impl<I>(&std::decay<F>::type::operator()));
0098
0099 template <typename F>
0100 using argument_count = decltype(argument_count_impl(&std::decay<F>::type::operator()));
0101
0102 template <typename F>
0103 using return_type = decltype(return_type_impl(&std::decay<F>::type::operator()));
0104
0105 template <typename F, typename T, typename RT = T>
0106 using enable_if_return =
0107 typename std::enable_if<std::is_same<return_type<F>, T>::value, RT>;
0108
0109 template <typename T, typename R = void>
0110 using enable_if_empty = typename std::enable_if<std::is_same<T, Empty>::value, R>::type;
0111
0112 template <typename T, typename R = void>
0113 using enable_if_not_empty =
0114 typename std::enable_if<!std::is_same<T, Empty>::value, R>::type;
0115 };
0116
0117
0118
0119
0120
0121
0122 template <typename Signature>
0123 class FnOnce;
0124
0125 template <typename R, typename... A>
0126 class FnOnce<R(A...)> {
0127 public:
0128 FnOnce() = default;
0129
0130 template <typename Fn,
0131 typename = typename std::enable_if<std::is_convertible<
0132 decltype(std::declval<Fn&&>()(std::declval<A>()...)), R>::value>::type>
0133 FnOnce(Fn fn) : impl_(new FnImpl<Fn>(std::move(fn))) {
0134 }
0135
0136 explicit operator bool() const { return impl_ != NULLPTR; }
0137
0138 R operator()(A... a) && {
0139 auto bye = std::move(impl_);
0140 return bye->invoke(std::forward<A&&>(a)...);
0141 }
0142
0143 private:
0144 struct Impl {
0145 virtual ~Impl() = default;
0146 virtual R invoke(A&&... a) = 0;
0147 };
0148
0149 template <typename Fn>
0150 struct FnImpl : Impl {
0151 explicit FnImpl(Fn fn) : fn_(std::move(fn)) {}
0152 R invoke(A&&... a) override { return std::move(fn_)(std::forward<A&&>(a)...); }
0153 Fn fn_;
0154 };
0155
0156 std::unique_ptr<Impl> impl_;
0157 };
0158
0159 }
0160 }