f4410729160882199839811caef57415d2d4784c
[platform/framework/web/wrt-commons.git] / modules / core / include / dpl / apply.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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  * @file    apply.h
18  * @author  Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for Apply functionality.
21  */
22 #ifndef DPL_APPLY_H_
23 #define DPL_APPLY_H_
24
25 #ifndef __GXX_EXPERIMENTAL_CXX0X__ // C++11 compatibility check
26 # include <bits/c++0x_warning.h>
27 #else
28
29 #include <tuple>
30 #include <utility>
31
32 namespace DPL
33 {
34 enum class ExtraArgsInsertPolicy
35 {
36     /**
37      * Extra arguments will be add at the end of the argument list
38      * passed to operation call.
39      */
40     Append,
41
42     /**
43      * Extra arguments will be add at the begining of the argument list
44      * passed to operation call.
45      */
46     Prepend
47 };
48
49 template<ExtraArgsInsertPolicy>
50 struct _ApplyDispatchByPolicy;
51
52 template<typename Result = void,
53          ExtraArgsInsertPolicy insertPolicy = ExtraArgsInsertPolicy::Append,
54          typename Operation,
55          typename ... ArgsT,
56          typename ... ArgsE>
57 Result Apply(Operation op,
58              const std::tuple<ArgsT ...>& t,
59              ArgsE && ... extra)
60 {
61     return _ApplyDispatchByPolicy<insertPolicy>::
62             template Apply<Result>(op, t, std::forward<ArgsE>(extra) ...);
63 }
64
65 template<size_t N, size_t M>
66 struct _ApplyTuple
67 {
68     template<typename Result,
69              typename Operation,
70              typename ... ArgsT1,
71              typename ... ArgsT2,
72              typename ... Args>
73     static Result Apply(Operation op,
74                         const std::tuple<ArgsT1 ...>& t1,
75                         const std::tuple<ArgsT2 ...>& t2,
76                         Args && ... args)
77     {
78         return _ApplyTuple<N - 1, M>::
79                 template Apply<Result>(op,
80                                        t1,
81                                        t2,
82                                        std::get<N - 1>(t1),
83                                        std::forward<Args>(args) ...);
84     }
85 };
86
87 template<size_t M>
88 struct _ApplyTuple<0, M>
89 {
90     template<typename Result,
91              typename Operation,
92              typename ... ArgsT1,
93              typename ... ArgsT2,
94              typename ... Args>
95     static Result Apply(Operation op,
96                         const std::tuple<ArgsT1 ...>& t1,
97                         const std::tuple<ArgsT2 ...>& t2,
98                         Args && ... args)
99     {
100         return _ApplyTuple<0, M - 1>::
101                 template Apply<Result>(op,
102                                        t1,
103                                        t2,
104                                        std::get<M - 1>(t2),
105                                        std::forward<Args>(args) ...);
106     }
107 };
108
109 template<>
110 struct _ApplyTuple<0, 0>
111 {
112     template<typename Result,
113              typename Operation,
114              typename ... ArgsT1,
115              typename ... ArgsT2,
116              typename ... Args>
117     static Result Apply(Operation op,
118                         const std::tuple<ArgsT1 ...>&,
119                         const std::tuple<ArgsT2 ...>&,
120                         Args && ... args)
121     {
122         return op(std::forward<Args>(args) ...);
123     }
124 };
125
126 template<size_t N>
127 struct _ApplyArgs
128 {
129     template<typename Result,
130              typename Operation,
131              typename ... ArgsT,
132              typename ... Args>
133     static Result Apply(Operation op,
134             const std::tuple<ArgsT ...>& t,
135             Args && ... args)
136     {
137         return _ApplyArgs<N - 1>::
138                        template Apply<Result>(op,
139                                               t,
140                                               std::get<N - 1>(t),
141                                               std::forward<Args>(args) ...);
142     }
143 };
144
145 template<>
146 struct _ApplyArgs<0>
147 {
148     template<typename Result,
149              typename Operation,
150              typename ... ArgsT,
151              typename ... Args>
152     static Result Apply(Operation op,
153                         const std::tuple<ArgsT ...>&,
154                         Args && ... args)
155     {
156         return op(std::forward<Args>(args) ...);
157     }
158 };
159
160 template<>
161 struct _ApplyDispatchByPolicy<ExtraArgsInsertPolicy::Append>
162 {
163     template<typename Result,
164              typename Operation,
165              typename ... ArgsT,
166              typename ... ArgsE>
167     static Result Apply(Operation op,
168                         const std::tuple<ArgsT ...>& t,
169                         ArgsE && ... extra)
170     {
171         return _ApplyArgs<sizeof ... (ArgsT)>::
172                        template Apply<Result>(op,
173                                               t,
174                                               std::forward<ArgsE>(extra) ...);
175     }
176 };
177
178 template<>
179 struct _ApplyDispatchByPolicy<ExtraArgsInsertPolicy::Prepend>
180 {
181     template<typename Result,
182              typename Operation,
183              typename ... ArgsT,
184              typename ... ArgsE>
185     static Result Apply(Operation op,
186                         const std::tuple<ArgsT ...>& t,
187                         ArgsE && ... extra)
188     {
189         return _ApplyTuple<sizeof ... (ArgsT), sizeof ... (ArgsE)>::
190                        template Apply<Result>(op,
191                                t,
192                                std::make_tuple(std::forward<ArgsE>(extra) ...));
193     }
194 };
195 } // namespace DPL
196
197 #endif // __GXX_EXPERIMENTAL_CXX0X__
198
199 #endif // DPL_APPLY_H_