1 /** 2 * Copyright 2021 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINDSPORE_CORE_MINDRT_INCLUDE_ASYNC_APPLY_H 18 #define MINDSPORE_CORE_MINDRT_INCLUDE_ASYNC_APPLY_H 19 20 #include <utility> 21 22 namespace mindspore { 23 24 template <typename T, T... Ints> 25 struct IntegerSequenceBase { SizeIntegerSequenceBase26 static constexpr std::size_t Size() noexcept { return sizeof...(Ints); } 27 }; 28 29 namespace internal { 30 31 template <typename T, std::size_t N, std::size_t... Ints> 32 struct IntegerSequence : public IntegerSequence<T, N - 1, N - 1, Ints...> {}; 33 34 template <typename T, std::size_t... Ints> 35 struct IntegerSequence<T, 0, Ints...> { 36 using type = IntegerSequenceBase<T, Ints...>; 37 }; 38 39 } // namespace internal 40 41 template <typename T, std::size_t N> 42 using make_integer_sequence = typename internal::IntegerSequence<T, N>::type; 43 44 template <std::size_t... Ints> 45 using index_sequence = IntegerSequenceBase<std::size_t, Ints...>; 46 47 template <std::size_t N> 48 using make_index_sequence = make_integer_sequence<std::size_t, N>; 49 50 template <class... T> 51 using index_sequence_for = make_index_sequence<sizeof...(T)>; 52 53 template <typename Func, typename Tuple, std::size_t... Ints> 54 auto ApplyHelper(Func &&func, Tuple &&tuple, index_sequence<Ints...>) 55 -> decltype(func(std::get<Ints>(std::forward<Tuple>(tuple))...)) { 56 return func(std::get<Ints>(std::forward<Tuple>(tuple))...); 57 } 58 59 template <typename T, typename Func, typename Tuple, std::size_t... Ints> 60 auto ApplyHelper(T *ptr, Func &&func, Tuple &&tuple, index_sequence<Ints...>) 61 -> decltype((ptr->*func)(std::get<Ints>(std::forward<Tuple>(tuple))...)) { 62 return (ptr->*func)(std::get<Ints>(std::forward<Tuple>(tuple))...); 63 } 64 65 template <typename Func, typename Tuple> 66 auto Apply(Func &&func, Tuple &&tuple) 67 -> decltype(ApplyHelper(std::forward<Func>(func), std::forward<Tuple>(tuple), 68 make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>{})) { 69 return ApplyHelper(std::forward<Func>(func), std::forward<Tuple>(tuple), 70 make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>{}); 71 } 72 73 template <typename T, typename Func, typename Tuple> 74 auto Apply(T *ptr, Func &&func, Tuple &&tuple) 75 -> decltype(ApplyHelper(ptr, std::forward<Func>(func), std::forward<Tuple>(tuple), 76 make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>{})) { 77 return ApplyHelper(ptr, std::forward<Func>(func), std::forward<Tuple>(tuple), 78 make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>{}); 79 } 80 81 } // namespace mindspore 82 83 #endif 84