• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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