merged the trunk r8704:8716
[profile/ivi/opencv.git] / modules / gpu / src / nvidia / core / NCVRuntimeTemplates.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. \r
4 // \r
5 //  By downloading, copying, installing or using the software you agree to this license.\r
6 //  If you do not agree to this license, do not download, install,\r
7 //  copy or use the software.\r
8 //\r
9 //\r
10 //                           License Agreement\r
11 //                For Open Source Computer Vision Library\r
12 //\r
13 // Copyright (C) 2009-2010, NVIDIA Corporation, all rights reserved.\r
14 // Third party copyrights are property of their respective owners.\r
15 //\r
16 // Redistribution and use in source and binary forms, with or without modification,\r
17 // are permitted provided that the following conditions are met:\r
18 //\r
19 //   * Redistribution's of source code must retain the above copyright notice,\r
20 //     this list of conditions and the following disclaimer.\r
21 //\r
22 //   * Redistribution's in binary form must reproduce the above copyright notice,\r
23 //     this list of conditions and the following disclaimer in the documentation\r
24 //     and/or other materials provided with the distribution.\r
25 //\r
26 //   * The name of the copyright holders may not be used to endorse or promote products\r
27 //     derived from this software without specific prior written permission.\r
28 //\r
29 // This software is provided by the copyright holders and contributors "as is" and\r
30 // any express or implied warranties, including, but not limited to, the implied\r
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.\r
32 // In no event shall the Intel Corporation or contributors be liable for any direct,\r
33 // indirect, incidental, special, exemplary, or consequential damages\r
34 // (including, but not limited to, procurement of substitute goods or services;\r
35 // loss of use, data, or profits; or business interruption) however caused\r
36 // and on any theory of liability, whether in contract, strict liability,\r
37 // or tort (including negligence or otherwise) arising in any way out of\r
38 // the use of this software, even if advised of the possibility of such damage.\r
39 //\r
40 //M*/\r
41 \r
42 #ifndef _ncvruntimetemplates_hpp_\r
43 #define _ncvruntimetemplates_hpp_\r
44 #if defined _MSC_VER &&_MSC_VER >= 1200\r
45 #pragma warning( disable: 4800 )\r
46 #endif\r
47 \r
48 \r
49 #include <stdarg.h>\r
50 #include <vector>\r
51 \r
52 \r
53 ////////////////////////////////////////////////////////////////////////////////\r
54 // The Loki Library\r
55 // Copyright (c) 2001 by Andrei Alexandrescu\r
56 // This code accompanies the book:\r
57 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design \r
58 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.\r
59 // Permission to use, copy, modify, distribute and sell this software for any \r
60 //     purpose is hereby granted without fee, provided that the above copyright \r
61 //     notice appear in all copies and that both that copyright notice and this \r
62 //     permission notice appear in supporting documentation.\r
63 // The author or Addison-Welsey Longman make no representations about the \r
64 //     suitability of this software for any purpose. It is provided "as is" \r
65 //     without express or implied warranty.\r
66 // http://loki-lib.sourceforge.net/index.php?n=Main.License\r
67 ////////////////////////////////////////////////////////////////////////////////\r
68 \r
69 namespace Loki\r
70 {\r
71     //==============================================================================\r
72     // class NullType\r
73     // Used as a placeholder for "no type here"\r
74     // Useful as an end marker in typelists \r
75     //==============================================================================\r
76 \r
77     class NullType {};\r
78 \r
79     //==============================================================================\r
80     // class template Typelist\r
81     // The building block of typelists of any length\r
82     // Use it through the LOKI_TYPELIST_NN macros\r
83     // Defines nested types:\r
84     //     Head (first element, a non-typelist type by convention)\r
85     //     Tail (second element, can be another typelist)\r
86     //==============================================================================\r
87 \r
88     template <class T, class U>\r
89     struct Typelist\r
90     {\r
91         typedef T Head;\r
92         typedef U Tail;\r
93     };\r
94 \r
95     //==============================================================================\r
96     // class template Int2Type\r
97     // Converts each integral constant into a unique type\r
98     // Invocation: Int2Type<v> where v is a compile-time constant integral\r
99     // Defines 'value', an enum that evaluates to v\r
100     //==============================================================================\r
101 \r
102     template <int v>\r
103     struct Int2Type\r
104     {\r
105         enum { value = v };\r
106     };\r
107 \r
108     namespace TL\r
109     {\r
110         //==============================================================================\r
111         // class template TypeAt\r
112         // Finds the type at a given index in a typelist\r
113         // Invocation (TList is a typelist and index is a compile-time integral \r
114         //     constant):\r
115         // TypeAt<TList, index>::Result\r
116         // returns the type in position 'index' in TList\r
117         // If you pass an out-of-bounds index, the result is a compile-time error\r
118         //==============================================================================\r
119 \r
120         template <class TList, unsigned int index> struct TypeAt;\r
121 \r
122         template <class Head, class Tail>\r
123         struct TypeAt<Typelist<Head, Tail>, 0>\r
124         {\r
125             typedef Head Result;\r
126         };\r
127 \r
128         template <class Head, class Tail, unsigned int i>\r
129         struct TypeAt<Typelist<Head, Tail>, i>\r
130         {\r
131             typedef typename TypeAt<Tail, i - 1>::Result Result;\r
132         };\r
133     }\r
134 }\r
135 \r
136 \r
137 ////////////////////////////////////////////////////////////////////////////////\r
138 // Runtime boolean template instance dispatcher\r
139 // Cyril Crassin <cyril.crassin@icare3d.org>\r
140 // NVIDIA, 2010\r
141 ////////////////////////////////////////////////////////////////////////////////\r
142 \r
143 namespace NCVRuntimeTemplateBool\r
144 {\r
145     //This struct is used to transform a list of parameters into template arguments\r
146     //The idea is to build a typelist containing the arguments\r
147     //and to pass this typelist to a user defined functor\r
148     template<typename TList, int NumArguments, class Func>\r
149     struct KernelCaller\r
150     {\r
151         //Convenience function used by the user\r
152         //Takes a variable argument list, transforms it into a list\r
153         static void call(Func *functor, ...)\r
154         {\r
155             //Vector used to collect arguments\r
156             std::vector<int> templateParamList;\r
157 \r
158             //Variable argument list manipulation\r
159             va_list listPointer;\r
160             va_start(listPointer, functor);\r
161             //Collect parameters into the list\r
162             for(int i=0; i<NumArguments; i++)\r
163             {\r
164                 int val = va_arg(listPointer, int);\r
165                 templateParamList.push_back(val);\r
166             }\r
167             va_end(listPointer);\r
168 \r
169             //Call the actual typelist building function\r
170             call(*functor, templateParamList);\r
171         }\r
172 \r
173         //Actual function called recursively to build a typelist based\r
174         //on a list of values\r
175         static void call( Func &functor, std::vector<int> &templateParamList)\r
176         {\r
177             //Get current parameter value in the list\r
178             NcvBool val = templateParamList[templateParamList.size() - 1];\r
179             templateParamList.pop_back();\r
180 \r
181             //Select the compile time value to add into the typelist\r
182             //depending on the runtime variable and make recursive call.\r
183             //Both versions are really instantiated\r
184             if (val)\r
185             {\r
186                 KernelCaller<\r
187                     Loki::Typelist<typename Loki::Int2Type<1>, TList >,\r
188                     NumArguments-1, Func >\r
189                     ::call(functor, templateParamList);\r
190             }\r
191             else\r
192             {\r
193                 KernelCaller<\r
194                     Loki::Typelist<typename Loki::Int2Type<0>, TList >,\r
195                     NumArguments-1, Func >\r
196                     ::call(functor, templateParamList);\r
197             }\r
198         }\r
199     };\r
200 \r
201     //Specialization for 0 value left in the list\r
202     //-> actual kernel functor call\r
203     template<class TList, class Func>\r
204     struct KernelCaller<TList, 0, Func>\r
205     {\r
206         static void call(Func &functor)\r
207         {\r
208             //Call to the functor's kernel call method\r
209             functor.call(TList()); //TList instantiated to get the method template parameter resolved\r
210         }\r
211 \r
212         static void call(Func &functor, std::vector<int> &templateParams)\r
213         {\r
214             (void)templateParams;\r
215             functor.call(TList());\r
216         }\r
217     };\r
218 }\r
219 \r
220 #endif //_ncvruntimetemplates_hpp_\r