tizen 2.4 release
[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 enum class ExtraArgsInsertPolicy
34 {
35     /**
36      * Extra arguments will be add at the end of the argument list
37      * passed to operation call.
38      */
39     Append,
40
41     /**
42      * Extra arguments will be add at the begining of the argument list
43      * passed to operation call.
44      */
45     Prepend
46 };
47
48 template<ExtraArgsInsertPolicy>
49 struct _ApplyDispatchByPolicy;
50
51 template<typename Result = void,
52          ExtraArgsInsertPolicy insertPolicy = ExtraArgsInsertPolicy::Append,
53          typename Operation,
54          typename ... ArgsT,
55          typename ... ArgsE>
56 Result Apply(Operation op,
57              const std::tuple<ArgsT ...>& t,
58              ArgsE && ... extra)
59 {
60     return _ApplyDispatchByPolicy<insertPolicy>::
61                template Apply<Result>(op, t, std::forward<ArgsE>(extra) ...);
62 }
63
64 template<size_t N, size_t M>
65 struct _ApplyTuple
66 {
67     template<typename Result,
68              typename Operation,
69              typename ... ArgsT1,
70              typename ... ArgsT2,
71              typename ... Args>
72     static Result Apply(Operation op,
73                         const std::tuple<ArgsT1 ...>& t1,
74                         const std::tuple<ArgsT2 ...>& t2,
75                         Args && ... args)
76     {
77         return _ApplyTuple<N - 1, M>::
78                    template Apply<Result>(op,
79                                           t1,
80                                           t2,
81                                           std::get<N - 1>(t1),
82                                           std::forward<Args>(args) ...);
83     }
84 };
85
86 template<size_t M>
87 struct _ApplyTuple<0, M>
88 {
89     template<typename Result,
90              typename Operation,
91              typename ... ArgsT1,
92              typename ... ArgsT2,
93              typename ... Args>
94     static Result Apply(Operation op,
95                         const std::tuple<ArgsT1 ...>& t1,
96                         const std::tuple<ArgsT2 ...>& t2,
97                         Args && ... args)
98     {
99         return _ApplyTuple<0, M - 1>::
100                    template Apply<Result>(op,
101                                           t1,
102                                           t2,
103                                           std::get<M - 1>(t2),
104                                           std::forward<Args>(args) ...);
105     }
106 };
107
108 template<>
109 struct _ApplyTuple<0, 0>
110 {
111     template<typename Result,
112              typename Operation,
113              typename ... ArgsT1,
114              typename ... ArgsT2,
115              typename ... Args>
116     static Result Apply(Operation op,
117                         const std::tuple<ArgsT1 ...>&,
118                         const std::tuple<ArgsT2 ...>&,
119                         Args && ... args)
120     {
121         return op(std::forward<Args>(args) ...);
122     }
123 };
124
125 template<size_t N>
126 struct _ApplyArgs
127 {
128     template<typename Result,
129              typename Operation,
130              typename ... ArgsT,
131              typename ... Args>
132     static Result Apply(Operation op,
133                         const std::tuple<ArgsT ...>& t,
134                         Args && ... args)
135     {
136         return _ApplyArgs<N - 1>::
137                    template Apply<Result>(op,
138                                           t,
139                                           std::get<N - 1>(t),
140                                           std::forward<Args>(args) ...);
141     }
142 };
143
144 template<>
145 struct _ApplyArgs<0>
146 {
147     template<typename Result,
148              typename Operation,
149              typename ... ArgsT,
150              typename ... Args>
151     static Result Apply(Operation op,
152                         const std::tuple<ArgsT ...>&,
153                         Args && ... args)
154     {
155         return op(std::forward<Args>(args) ...);
156     }
157 };
158
159 template<>
160 struct _ApplyDispatchByPolicy<ExtraArgsInsertPolicy::Append>
161 {
162     template<typename Result,
163              typename Operation,
164              typename ... ArgsT,
165              typename ... ArgsE>
166     static Result Apply(Operation op,
167                         const std::tuple<ArgsT ...>& t,
168                         ArgsE && ... extra)
169     {
170         return _ApplyArgs<sizeof ... (ArgsT)>::
171                    template Apply<Result>(op,
172                                           t,
173                                           std::forward<ArgsE>(extra) ...);
174     }
175 };
176
177 template<>
178 struct _ApplyDispatchByPolicy<ExtraArgsInsertPolicy::Prepend>
179 {
180     template<typename Result,
181              typename Operation,
182              typename ... ArgsT,
183              typename ... ArgsE>
184     static Result Apply(Operation op,
185                         const std::tuple<ArgsT ...>& t,
186                         ArgsE && ... extra)
187     {
188         return _ApplyTuple<sizeof ... (ArgsT), sizeof ... (ArgsE)>::
189                    template Apply<Result>(op,
190                                           t,
191                                           std::make_tuple(std::forward<ArgsE>(
192                                                               extra) ...));
193     }
194 };
195 } // namespace DPL
196
197 #endif // __GXX_EXPERIMENTAL_CXX0X__
198
199 #endif // DPL_APPLY_H_