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
70namespace 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
144namespace 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
154        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
176        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    {
207        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
213        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