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