Point Cloud Library (PCL)  1.9.1-dev
NCVRuntimeTemplates.hpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (C) 2009-2010, NVIDIA Corporation, all rights reserved.
6  * Third party copyrights are property of their respective owners.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of Willow Garage, Inc. nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id: $
38  * Ported to PCL by Koen Buys : Attention Work in progress!
39  */
40 
41 #ifndef _ncvruntimetemplates_hpp_
42 #define _ncvruntimetemplates_hpp_
43 #if _MSC_VER >= 1200
44 #pragma warning( disable: 4800 )
45 #endif
46 
47 
48 #include <stdarg.h>
49 #include <vector>
50 
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 // The Loki Library
54 // Copyright (c) 2001 by Andrei Alexandrescu
55 // This code accompanies the book:
56 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
57 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
58 // Permission to use, copy, modify, distribute and sell this software for any
59 // purpose is hereby granted without fee, provided that the above copyright
60 // notice appear in all copies and that both that copyright notice and this
61 // permission notice appear in supporting documentation.
62 // The author or Addison-Welsey Longman make no representations about the
63 // suitability of this software for any purpose. It is provided "as is"
64 // without express or implied warranty.
65 // http://loki-lib.sourceforge.net/index.php?n=Main.License
66 ////////////////////////////////////////////////////////////////////////////////
67 
68 namespace Loki
69 {
70  //==============================================================================
71  // class NullType
72  // Used as a placeholder for "no type here"
73  // Useful as an end marker in typelists
74  //==============================================================================
75 
76  class NullType {};
77 
78  //==============================================================================
79  // class template Typelist
80  // The building block of typelists of any length
81  // Use it through the LOKI_TYPELIST_NN macros
82  // Defines nested types:
83  // Head (first element, a non-typelist type by convention)
84  // Tail (second element, can be another typelist)
85  //==============================================================================
86 
87  template <class T, class U>
88  struct Typelist
89  {
90  using Head = T;
91  using Tail = U;
92  };
93 
94  //==============================================================================
95  // class template Int2Type
96  // Converts each integral constant into a unique type
97  // Invocation: Int2Type<v> where v is a compile-time constant integral
98  // Defines 'value', an enum that evaluates to v
99  //==============================================================================
100 
101  template <int v>
102  struct Int2Type
103  {
104  enum { value = v };
105  };
106 
107  namespace TL
108  {
109  //==============================================================================
110  // class template TypeAt
111  // Finds the type at a given index in a typelist
112  // Invocation (TList is a typelist and index is a compile-time integral
113  // constant):
114  // TypeAt<TList, index>::Result
115  // returns the type in position 'index' in TList
116  // If you pass an out-of-bounds index, the result is a compile-time error
117  //==============================================================================
118 
119  template <class TList, unsigned int index> struct TypeAt;
120 
121  template <class Head, class Tail>
122  struct TypeAt<Typelist<Head, Tail>, 0>
123  {
124  using Result = Head;
125  };
126 
127  template <class Head, class Tail, unsigned int i>
128  struct TypeAt<Typelist<Head, Tail>, i>
129  {
130  using Result = typename TypeAt<Tail, i - 1>::Result;
131  };
132  }
133 }
134 
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 // Runtime boolean template instance dispatcher
138 // Cyril Crassin <cyril.crassin@icare3d.org>
139 // NVIDIA, 2010
140 ////////////////////////////////////////////////////////////////////////////////
141 
143 {
144  //This struct is used to transform a list of parameters into template arguments
145  //The idea is to build a typelist containing the arguments
146  //and to pass this typelist to a user defined functor
147  template<typename TList, int NumArguments, class Func>
149  {
150  //Convenience function used by the user
151  //Takes a variable argument list, transforms it into a list
152  static void call(Func *functor, ...)
153  {
154  //Vector used to collect arguments
155  std::vector<int> templateParamList;
156 
157  //Variable argument list manipulation
158  va_list listPointer;
159  va_start(listPointer, functor);
160  //Collect parameters into the list
161  for(int i=0; i<NumArguments; i++)
162  {
163  int val = va_arg(listPointer, int);
164  templateParamList.push_back(val);
165  }
166  va_end(listPointer);
167 
168  //Call the actual typelist building function
169  call(*functor, templateParamList);
170  }
171 
172  //Actual function called recursively to build a typelist based
173  //on a list of values
174  static void call( Func &functor, std::vector<int> &templateParamList)
175  {
176  //Get current parameter value in the list
177  NcvBool val = templateParamList[templateParamList.size() - 1];
178  templateParamList.pop_back();
179 
180  //Select the compile time value to add into the typelist
181  //depending on the runtime variable and make recursive call.
182  //Both versions are really instantiated
183  if (val)
184  {
185  KernelCaller<
187  NumArguments-1, Func >
188  ::call(functor, templateParamList);
189  }
190  else
191  {
192  KernelCaller<
194  NumArguments-1, Func >
195  ::call(functor, templateParamList);
196  }
197  }
198  };
199 
200  //Specialization for 0 value left in the list
201  //-> actual kernel functor call
202  template<class TList, class Func>
203  struct KernelCaller<TList, 0, Func>
204  {
205  static void call(Func &functor)
206  {
207  //Call to the functor's kernel call method
208  functor.call(TList()); //TList instantiated to get the method template parameter resolved
209  }
210 
211  static void call(Func &functor, std::vector<int> &templateParams)
212  {
213  functor.call(TList());
214  }
215  };
216 }
217 
218 #endif //_ncvruntimetemplates_hpp_
static void call(Func &functor, std::vector< int > &templateParams)
static void call(Func *functor,...)
static void call(Func &functor, std::vector< int > &templateParamList)
typename TypeAt< Tail, i - 1 >::Result Result