Upstream version 9.38.207.0
[platform/framework/web/crosswalk.git] / src / third_party / khronos / CL / cl.hpp
1 /*******************************************************************************
2  * Copyright (c) 2008-2013 The Khronos Group Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and/or associated documentation files (the
6  * "Materials"), to deal in the Materials without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Materials, and to
9  * permit persons to whom the Materials are furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Materials.
14  *
15  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
22  ******************************************************************************/
23
24 /*! \file
25  *
26  *   \brief C++ bindings for OpenCL 1.0 (rev 48), OpenCL 1.1 (rev 33) and 
27  *       OpenCL 1.2 (rev 15)    
28  *   \author Benedict R. Gaster, Laurent Morichetti and Lee Howes
29  *   
30  *   Additions and fixes from:
31  *       Brian Cole, March 3rd 2010 and April 2012 
32  *       Matt Gruenke, April 2012.
33  *       Bruce Merry, February 2013.
34  *       Tom Deakin and Simon McIntosh-Smith, July 2013
35  *   
36  *   \version 1.2.6
37  *   \date August 2013
38  *
39  *   Optional extension support
40  *
41  *         cl
42  *         cl_ext_device_fission
43  *                              #define USE_CL_DEVICE_FISSION
44  */
45
46 /*! \mainpage
47  * \section intro Introduction
48  * For many large applications C++ is the language of choice and so it seems
49  * reasonable to define C++ bindings for OpenCL.
50  *
51  *
52  * The interface is contained with a single C++ header file \em cl.hpp and all
53  * definitions are contained within the namespace \em cl. There is no additional
54  * requirement to include \em cl.h and to use either the C++ or original C
55  * bindings it is enough to simply include \em cl.hpp.
56  *
57  * The bindings themselves are lightweight and correspond closely to the
58  * underlying C API. Using the C++ bindings introduces no additional execution
59  * overhead.
60  *
61  * For detail documentation on the bindings see:
62  *
63  * The OpenCL C++ Wrapper API 1.2 (revision 09)
64  *  http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf
65  *
66  * \section example Example
67  *
68  * The following example shows a general use case for the C++
69  * bindings, including support for the optional exception feature and
70  * also the supplied vector and string classes, see following sections for
71  * decriptions of these features.
72  *
73  * \code
74  * #define __CL_ENABLE_EXCEPTIONS
75  * 
76  * #if defined(__APPLE__) || defined(__MACOSX)
77  * #include <OpenCL/cl.hpp>
78  * #else
79  * #include <CL/cl.hpp>
80  * #endif
81  * #include <cstdio>
82  * #include <cstdlib>
83  * #include <iostream>
84  * 
85  *  const char * helloStr  = "__kernel void "
86  *                           "hello(void) "
87  *                           "{ "
88  *                           "  "
89  *                           "} ";
90  * 
91  *  int
92  *  main(void)
93  *  {
94  *     cl_int err = CL_SUCCESS;
95  *     try {
96  *
97  *       std::vector<cl::Platform> platforms;
98  *       cl::Platform::get(&platforms);
99  *       if (platforms.size() == 0) {
100  *           std::cout << "Platform size 0\n";
101  *           return -1;
102  *       }
103  *
104  *       cl_context_properties properties[] = 
105  *          { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};
106  *       cl::Context context(CL_DEVICE_TYPE_CPU, properties); 
107  * 
108  *       std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
109  * 
110  *       cl::Program::Sources source(1,
111  *           std::make_pair(helloStr,strlen(helloStr)));
112  *       cl::Program program_ = cl::Program(context, source);
113  *       program_.build(devices);
114  * 
115  *       cl::Kernel kernel(program_, "hello", &err);
116  * 
117  *       cl::Event event;
118  *       cl::CommandQueue queue(context, devices[0], 0, &err);
119  *       queue.enqueueNDRangeKernel(
120  *           kernel, 
121  *           cl::NullRange, 
122  *           cl::NDRange(4,4),
123  *           cl::NullRange,
124  *           NULL,
125  *           &event); 
126  * 
127  *       event.wait();
128  *     }
129  *     catch (cl::Error err) {
130  *        std::cerr 
131  *           << "ERROR: "
132  *           << err.what()
133  *           << "("
134  *           << err.err()
135  *           << ")"
136  *           << std::endl;
137  *     }
138  * 
139  *    return EXIT_SUCCESS;
140  *  }
141  * 
142  * \endcode
143  *
144  */
145 #ifndef CL_HPP_
146 #define CL_HPP_
147
148 #ifdef _WIN32
149
150 #include <windows.h>
151 #include <malloc.h>
152 #include <iterator>
153 #include <intrin.h>
154
155 #if defined(__CL_ENABLE_EXCEPTIONS)
156 #include <exception>
157 #endif // #if defined(__CL_ENABLE_EXCEPTIONS)
158
159 #pragma push_macro("max")
160 #undef max
161 #if defined(USE_DX_INTEROP)
162 #include <CL/cl_d3d10.h>
163 #include <CL/cl_dx9_media_sharing.h>
164 #endif
165 #endif // _WIN32
166
167 // 
168 #if defined(USE_CL_DEVICE_FISSION)
169 #include <CL/cl_ext.h>
170 #endif
171
172 #if defined(__APPLE__) || defined(__MACOSX)
173 #include <OpenGL/OpenGL.h>
174 #include <OpenCL/opencl.h>
175 #include <libkern/OSAtomic.h>
176 #else
177 #include <GL/gl.h>
178 #include <CL/opencl.h>
179 #endif // !__APPLE__
180
181 // To avoid accidentally taking ownership of core OpenCL types
182 // such as cl_kernel constructors are made explicit
183 // under OpenCL 1.2
184 #if defined(CL_VERSION_1_2) && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
185 #define __CL_EXPLICIT_CONSTRUCTORS explicit
186 #else // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
187 #define __CL_EXPLICIT_CONSTRUCTORS 
188 #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
189
190 // Define deprecated prefixes and suffixes to ensure compilation
191 // in case they are not pre-defined
192 #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED)
193 #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED  
194 #endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED)
195 #if !defined(CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED)
196 #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
197 #endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED)
198
199 #if !defined(CL_CALLBACK)
200 #define CL_CALLBACK
201 #endif //CL_CALLBACK
202
203 #include <utility>
204 #include <limits>
205
206 #if !defined(__NO_STD_VECTOR)
207 #include <vector>
208 #endif
209
210 #if !defined(__NO_STD_STRING)
211 #include <string>
212 #endif 
213
214 #if defined(linux) || defined(__APPLE__) || defined(__MACOSX)
215 #include <alloca.h>
216
217 #include <emmintrin.h>
218 #include <xmmintrin.h>
219 #endif // linux
220
221 #include <cstring>
222
223
224 /*! \namespace cl
225  *
226  * \brief The OpenCL C++ bindings are defined within this namespace.
227  *
228  */
229 namespace cl {
230
231 class Memory;
232
233 /**
234  * Deprecated APIs for 1.2
235  */
236 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) 
237 #define __INIT_CL_EXT_FCN_PTR(name) \
238     if(!pfn_##name) { \
239         pfn_##name = (PFN_##name) \
240             clGetExtensionFunctionAddress(#name); \
241         if(!pfn_##name) { \
242         } \
243     }
244 #endif // #if defined(CL_VERSION_1_1)
245
246 #if defined(CL_VERSION_1_2)
247 #define __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, name) \
248     if(!pfn_##name) { \
249         pfn_##name = (PFN_##name) \
250             clGetExtensionFunctionAddressForPlatform(platform, #name); \
251         if(!pfn_##name) { \
252         } \
253     }
254 #endif // #if defined(CL_VERSION_1_1)
255
256 class Program;
257 class Device;
258 class Context;
259 class CommandQueue;
260 class Memory;
261 class Buffer;
262
263 #if defined(__CL_ENABLE_EXCEPTIONS)
264 /*! \brief Exception class 
265  * 
266  *  This may be thrown by API functions when __CL_ENABLE_EXCEPTIONS is defined.
267  */
268 class Error : public std::exception
269 {
270 private:
271     cl_int err_;
272     const char * errStr_;
273 public:
274     /*! \brief Create a new CL error exception for a given error code
275      *  and corresponding message.
276      * 
277      *  \param err error code value.
278      *
279      *  \param errStr a descriptive string that must remain in scope until
280      *                handling of the exception has concluded.  If set, it
281      *                will be returned by what().
282      */
283     Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr)
284     {}
285
286     ~Error() throw() {}
287
288     /*! \brief Get error string associated with exception
289      *
290      * \return A memory pointer to the error message string.
291      */
292     virtual const char * what() const throw ()
293     {
294         if (errStr_ == NULL) {
295             return "empty";
296         }
297         else {
298             return errStr_;
299         }
300     }
301
302     /*! \brief Get error code associated with exception
303      *
304      *  \return The error code.
305      */
306     cl_int err(void) const { return err_; }
307 };
308
309 #define __ERR_STR(x) #x
310 #else
311 #define __ERR_STR(x) NULL
312 #endif // __CL_ENABLE_EXCEPTIONS
313
314
315 namespace detail
316 {
317 #if defined(__CL_ENABLE_EXCEPTIONS)
318 static inline cl_int errHandler (
319     cl_int err,
320     const char * errStr = NULL)
321 {
322     if (err != CL_SUCCESS) {
323         throw Error(err, errStr);
324     }
325     return err;
326 }
327 #else
328 static inline cl_int errHandler (cl_int err, const char * errStr = NULL)
329 {
330     (void) errStr; // suppress unused variable warning
331     return err;
332 }
333 #endif // __CL_ENABLE_EXCEPTIONS
334 }
335
336
337
338 //! \cond DOXYGEN_DETAIL
339 #if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
340 #define __GET_DEVICE_INFO_ERR               __ERR_STR(clGetDeviceInfo)
341 #define __GET_PLATFORM_INFO_ERR             __ERR_STR(clGetPlatformInfo)
342 #define __GET_DEVICE_IDS_ERR                __ERR_STR(clGetDeviceIDs)
343 #define __GET_PLATFORM_IDS_ERR              __ERR_STR(clGetPlatformIDs)
344 #define __GET_CONTEXT_INFO_ERR              __ERR_STR(clGetContextInfo)
345 #define __GET_EVENT_INFO_ERR                __ERR_STR(clGetEventInfo)
346 #define __GET_EVENT_PROFILE_INFO_ERR        __ERR_STR(clGetEventProfileInfo)
347 #define __GET_MEM_OBJECT_INFO_ERR           __ERR_STR(clGetMemObjectInfo)
348 #define __GET_IMAGE_INFO_ERR                __ERR_STR(clGetImageInfo)
349 #define __GET_SAMPLER_INFO_ERR              __ERR_STR(clGetSamplerInfo)
350 #define __GET_KERNEL_INFO_ERR               __ERR_STR(clGetKernelInfo)
351 #if defined(CL_VERSION_1_2)
352 #define __GET_KERNEL_ARG_INFO_ERR               __ERR_STR(clGetKernelArgInfo)
353 #endif // #if defined(CL_VERSION_1_2)
354 #define __GET_KERNEL_WORK_GROUP_INFO_ERR    __ERR_STR(clGetKernelWorkGroupInfo)
355 #define __GET_PROGRAM_INFO_ERR              __ERR_STR(clGetProgramInfo)
356 #define __GET_PROGRAM_BUILD_INFO_ERR        __ERR_STR(clGetProgramBuildInfo)
357 #define __GET_COMMAND_QUEUE_INFO_ERR        __ERR_STR(clGetCommandQueueInfo)
358
359 #define __CREATE_CONTEXT_ERR                __ERR_STR(clCreateContext)
360 #define __CREATE_CONTEXT_FROM_TYPE_ERR      __ERR_STR(clCreateContextFromType)
361 #define __GET_SUPPORTED_IMAGE_FORMATS_ERR   __ERR_STR(clGetSupportedImageFormats)
362
363 #define __CREATE_BUFFER_ERR                 __ERR_STR(clCreateBuffer)
364 #define __COPY_ERR                          __ERR_STR(cl::copy)
365 #define __CREATE_SUBBUFFER_ERR              __ERR_STR(clCreateSubBuffer)
366 #define __CREATE_GL_BUFFER_ERR              __ERR_STR(clCreateFromGLBuffer)
367 #define __CREATE_GL_RENDER_BUFFER_ERR       __ERR_STR(clCreateFromGLBuffer)
368 #define __GET_GL_OBJECT_INFO_ERR            __ERR_STR(clGetGLObjectInfo)
369 #if defined(CL_VERSION_1_2)
370 #define __CREATE_IMAGE_ERR                  __ERR_STR(clCreateImage)
371 #define __CREATE_GL_TEXTURE_ERR             __ERR_STR(clCreateFromGLTexture)
372 #define __IMAGE_DIMENSION_ERR               __ERR_STR(Incorrect image dimensions)
373 #endif // #if defined(CL_VERSION_1_2)
374 #define __CREATE_SAMPLER_ERR                __ERR_STR(clCreateSampler)
375 #define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback)
376
377 #define __CREATE_USER_EVENT_ERR             __ERR_STR(clCreateUserEvent)
378 #define __SET_USER_EVENT_STATUS_ERR         __ERR_STR(clSetUserEventStatus)
379 #define __SET_EVENT_CALLBACK_ERR            __ERR_STR(clSetEventCallback)
380 #define __WAIT_FOR_EVENTS_ERR               __ERR_STR(clWaitForEvents)
381
382 #define __CREATE_KERNEL_ERR                 __ERR_STR(clCreateKernel)
383 #define __SET_KERNEL_ARGS_ERR               __ERR_STR(clSetKernelArg)
384 #define __CREATE_PROGRAM_WITH_SOURCE_ERR    __ERR_STR(clCreateProgramWithSource)
385 #define __CREATE_PROGRAM_WITH_BINARY_ERR    __ERR_STR(clCreateProgramWithBinary)
386 #if defined(CL_VERSION_1_2)
387 #define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR    __ERR_STR(clCreateProgramWithBuiltInKernels)
388 #endif // #if defined(CL_VERSION_1_2)
389 #define __BUILD_PROGRAM_ERR                 __ERR_STR(clBuildProgram)
390 #if defined(CL_VERSION_1_2)
391 #define __COMPILE_PROGRAM_ERR                  __ERR_STR(clCompileProgram)
392
393 #endif // #if defined(CL_VERSION_1_2)
394 #define __CREATE_KERNELS_IN_PROGRAM_ERR     __ERR_STR(clCreateKernelsInProgram)
395
396 #define __CREATE_COMMAND_QUEUE_ERR          __ERR_STR(clCreateCommandQueue)
397 #define __SET_COMMAND_QUEUE_PROPERTY_ERR    __ERR_STR(clSetCommandQueueProperty)
398 #define __ENQUEUE_READ_BUFFER_ERR           __ERR_STR(clEnqueueReadBuffer)
399 #define __ENQUEUE_READ_BUFFER_RECT_ERR      __ERR_STR(clEnqueueReadBufferRect)
400 #define __ENQUEUE_WRITE_BUFFER_ERR          __ERR_STR(clEnqueueWriteBuffer)
401 #define __ENQUEUE_WRITE_BUFFER_RECT_ERR     __ERR_STR(clEnqueueWriteBufferRect)
402 #define __ENQEUE_COPY_BUFFER_ERR            __ERR_STR(clEnqueueCopyBuffer)
403 #define __ENQEUE_COPY_BUFFER_RECT_ERR       __ERR_STR(clEnqueueCopyBufferRect)
404 #define __ENQUEUE_FILL_BUFFER_ERR           __ERR_STR(clEnqueueFillBuffer)
405 #define __ENQUEUE_READ_IMAGE_ERR            __ERR_STR(clEnqueueReadImage)
406 #define __ENQUEUE_WRITE_IMAGE_ERR           __ERR_STR(clEnqueueWriteImage)
407 #define __ENQUEUE_COPY_IMAGE_ERR            __ERR_STR(clEnqueueCopyImage)
408 #define __ENQUEUE_FILL_IMAGE_ERR           __ERR_STR(clEnqueueFillImage)
409 #define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR  __ERR_STR(clEnqueueCopyImageToBuffer)
410 #define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR  __ERR_STR(clEnqueueCopyBufferToImage)
411 #define __ENQUEUE_MAP_BUFFER_ERR            __ERR_STR(clEnqueueMapBuffer)
412 #define __ENQUEUE_MAP_IMAGE_ERR             __ERR_STR(clEnqueueMapImage)
413 #define __ENQUEUE_UNMAP_MEM_OBJECT_ERR      __ERR_STR(clEnqueueUnMapMemObject)
414 #define __ENQUEUE_NDRANGE_KERNEL_ERR        __ERR_STR(clEnqueueNDRangeKernel)
415 #define __ENQUEUE_TASK_ERR                  __ERR_STR(clEnqueueTask)
416 #define __ENQUEUE_NATIVE_KERNEL             __ERR_STR(clEnqueueNativeKernel)
417 #if defined(CL_VERSION_1_2)
418 #define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR   __ERR_STR(clEnqueueMigrateMemObjects)
419 #endif // #if defined(CL_VERSION_1_2)
420
421 #define __ENQUEUE_ACQUIRE_GL_ERR            __ERR_STR(clEnqueueAcquireGLObjects)
422 #define __ENQUEUE_RELEASE_GL_ERR            __ERR_STR(clEnqueueReleaseGLObjects)
423
424
425 #define __RETAIN_ERR                        __ERR_STR(Retain Object)
426 #define __RELEASE_ERR                       __ERR_STR(Release Object)
427 #define __FLUSH_ERR                         __ERR_STR(clFlush)
428 #define __FINISH_ERR                        __ERR_STR(clFinish)
429 #define __VECTOR_CAPACITY_ERR               __ERR_STR(Vector capacity error)
430
431 /**
432  * CL 1.2 version that uses device fission.
433  */
434 #if defined(CL_VERSION_1_2)
435 #define __CREATE_SUB_DEVICES                __ERR_STR(clCreateSubDevices)
436 #else
437 #define __CREATE_SUB_DEVICES                __ERR_STR(clCreateSubDevicesEXT)
438 #endif // #if defined(CL_VERSION_1_2)
439
440 /**
441  * Deprecated APIs for 1.2
442  */
443 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) 
444 #define __ENQUEUE_MARKER_ERR                __ERR_STR(clEnqueueMarker)
445 #define __ENQUEUE_WAIT_FOR_EVENTS_ERR       __ERR_STR(clEnqueueWaitForEvents)
446 #define __ENQUEUE_BARRIER_ERR               __ERR_STR(clEnqueueBarrier)
447 #define __UNLOAD_COMPILER_ERR               __ERR_STR(clUnloadCompiler)
448 #define __CREATE_GL_TEXTURE_2D_ERR          __ERR_STR(clCreateFromGLTexture2D)
449 #define __CREATE_GL_TEXTURE_3D_ERR          __ERR_STR(clCreateFromGLTexture3D)
450 #define __CREATE_IMAGE2D_ERR                __ERR_STR(clCreateImage2D)
451 #define __CREATE_IMAGE3D_ERR                __ERR_STR(clCreateImage3D)
452 #endif // #if defined(CL_VERSION_1_1)
453
454 #endif // __CL_USER_OVERRIDE_ERROR_STRINGS
455 //! \endcond
456
457 /**
458  * CL 1.2 marker and barrier commands
459  */
460 #if defined(CL_VERSION_1_2)
461 #define __ENQUEUE_MARKER_WAIT_LIST_ERR                __ERR_STR(clEnqueueMarkerWithWaitList)
462 #define __ENQUEUE_BARRIER_WAIT_LIST_ERR               __ERR_STR(clEnqueueBarrierWithWaitList)
463 #endif // #if defined(CL_VERSION_1_2)
464
465 #if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING)
466 typedef std::string STRING_CLASS;
467 #elif !defined(__USE_DEV_STRING) 
468
469 /*! \class string
470  * \brief Simple string class, that provides a limited subset of std::string
471  * functionality but avoids many of the issues that come with that class.
472  
473  *  \note Deprecated. Please use std::string as default or
474  *  re-define the string class to match the std::string
475  *  interface by defining STRING_CLASS
476  */
477 class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED string CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
478 {
479 private:
480     ::size_t size_;
481     char * str_;
482 public:
483     //! \brief Constructs an empty string, allocating no memory.
484     string(void) : size_(0), str_(NULL)
485     {
486     }
487
488     /*! \brief Constructs a string populated from an arbitrary value of
489      *  specified size.
490      * 
491      *  An extra '\0' is added, in case none was contained in str.
492      *
493      *  \param str the initial value of the string instance.  Note that '\0'     
494      *             characters receive no special treatment.  If NULL,
495      *             the string is left empty, with a size of 0.
496      *
497      *  \param size the number of characters to copy from str.
498      */
499     string(const char * str, ::size_t size) :
500         size_(size),
501         str_(NULL)
502     {
503         if( size > 0 ) {
504             str_ = new char[size_+1];
505             if (str_ != NULL) {
506                 memcpy(str_, str, size_  * sizeof(char));
507                 str_[size_] = '\0';
508             }
509             else {
510                 size_ = 0;
511             }
512         }
513     }
514
515     /*! \brief Constructs a string populated from a null-terminated value.
516      *
517      *  \param str the null-terminated initial value of the string instance.
518      *             If NULL, the string is left empty, with a size of 0.
519      */
520     string(const char * str) :
521         size_(0),
522         str_(NULL)
523     {
524         if( str ) {
525             size_= ::strlen(str);
526         }
527         if( size_ > 0 ) {
528             str_ = new char[size_ + 1];
529             if (str_ != NULL) {
530                 memcpy(str_, str, (size_ + 1) * sizeof(char));
531             }
532         }
533     }
534
535     void resize( ::size_t n )
536     {
537         if( size_ == n ) {
538             return;
539         }
540         if (n == 0) {
541             if( str_ ) {
542                 delete [] str_;
543             }
544             str_ = NULL;
545             size_ = 0;
546         } 
547         else {
548             char *newString = new char[n + 1];
549             int copySize = n;
550             if( size_ < n ) {
551                 copySize = size_;
552             }
553             size_ = n;
554             
555             if(str_) {
556                 memcpy(newString, str_, (copySize + 1) * sizeof(char));
557             }
558             if( copySize < size_ ) {
559                 memset(newString + copySize, 0, size_ - copySize);
560             }
561             newString[size_] = '\0';
562
563             delete [] str_;
564             str_ = newString;
565         }
566     }
567
568     const char& operator[] ( ::size_t pos ) const
569     {
570         return str_[pos];
571     }
572
573     char& operator[] ( ::size_t pos )
574     {
575         return str_[pos];
576     }
577
578     /*! \brief Copies the value of another string to this one.
579      *
580      *  \param rhs the string to copy.
581      *
582      *  \returns a reference to the modified instance.
583      */
584     string& operator=(const string& rhs)
585     {
586         if (this == &rhs) {
587             return *this;
588         }
589
590         if( str_ != NULL ) {
591             delete [] str_;
592             str_ = NULL;
593             size_ = 0;
594         }
595
596         if (rhs.size_ == 0 || rhs.str_ == NULL) {
597             str_ = NULL;
598             size_ = 0;
599         } 
600         else {
601             str_ = new char[rhs.size_ + 1];
602             size_ = rhs.size_;
603             
604             if (str_ != NULL) {
605                 memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char));
606             }
607             else {
608                 size_ = 0;
609             }
610         }
611
612         return *this;
613     }
614
615     /*! \brief Constructs a string by copying the value of another instance.
616      *
617      *  \param rhs the string to copy.
618      */
619     string(const string& rhs) :
620         size_(0),
621         str_(NULL)
622     {
623         *this = rhs;
624     }
625
626     //! \brief Destructor - frees memory used to hold the current value.
627     ~string()
628     {
629         delete[] str_;
630         str_ = NULL;
631     }
632     
633     //! \brief Queries the length of the string, excluding any added '\0's.
634     ::size_t size(void) const   { return size_; }
635
636     //! \brief Queries the length of the string, excluding any added '\0's.
637     ::size_t length(void) const { return size(); }
638
639     /*! \brief Returns a pointer to the private copy held by this instance,
640      *  or "" if empty/unset.
641      */
642     const char * c_str(void) const { return (str_) ? str_ : "";}
643 };
644 typedef cl::string STRING_CLASS;
645 #endif // #elif !defined(__USE_DEV_STRING) 
646
647 #if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR)
648 #define VECTOR_CLASS std::vector
649 #elif !defined(__USE_DEV_VECTOR) 
650 #define VECTOR_CLASS cl::vector 
651
652 #if !defined(__MAX_DEFAULT_VECTOR_SIZE)
653 #define __MAX_DEFAULT_VECTOR_SIZE 10
654 #endif
655
656 /*! \class vector
657  * \brief Fixed sized vector implementation that mirroring 
658  *
659  *  \note Deprecated. Please use std::vector as default or
660  *  re-define the vector class to match the std::vector
661  *  interface by defining VECTOR_CLASS
662
663  *  \note Not recommended for use with custom objects as
664  *  current implementation will construct N elements
665  *
666  * std::vector functionality.
667  *  \brief Fixed sized vector compatible with std::vector.
668  *
669  *  \note
670  *  This differs from std::vector<> not just in memory allocation,
671  *  but also in terms of when members are constructed, destroyed,
672  *  and assigned instead of being copy constructed.
673  *
674  *  \param T type of element contained in the vector.
675  *
676  *  \param N maximum size of the vector.
677  */
678 template <typename T, unsigned int N = __MAX_DEFAULT_VECTOR_SIZE>
679 class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED vector CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
680 {
681 private:
682     T data_[N];
683     unsigned int size_;
684
685 public:
686     //! \brief Constructs an empty vector with no memory allocated.
687     vector() :  
688         size_(static_cast<unsigned int>(0))
689     {}
690
691     //! \brief Deallocates the vector's memory and destroys all of its elements.
692     ~vector() 
693     {
694         clear();
695     }
696
697     //! \brief Returns the number of elements currently contained.
698     unsigned int size(void) const
699     {
700         return size_;
701     }
702     
703     /*! \brief Empties the vector of all elements.
704      *  \note
705      *  This does not deallocate memory but will invoke destructors
706      *  on contained elements.
707      */
708     void clear()
709     {
710         while(!empty()) {
711             pop_back();
712         }
713     }
714
715     /*! \brief Appends an element after the last valid element.
716      * Calling this on a vector that has reached capacity will throw an 
717      * exception if exceptions are enabled.
718      */
719     void push_back (const T& x)
720     { 
721         if (size() < N) {    
722             new (&data_[size_]) T(x);
723             size_++;
724         } else {
725             detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR);
726         }
727     }
728
729     /*! \brief Removes the last valid element from the vector.
730      * Calling this on an empty vector will throw an exception
731      * if exceptions are enabled.
732      */
733     void pop_back(void)
734     {
735         if (size_ != 0) {
736             --size_;
737             data_[size_].~T();
738         } else {
739             detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR);
740         }
741     }
742   
743     /*! \brief Constructs with a value copied from another.
744      *
745      *  \param vec the vector to copy.
746      */
747     vector(const vector<T, N>& vec) : 
748         size_(vec.size_)
749     {
750         if (size_ != 0) {       
751             assign(vec.begin(), vec.end());
752         }
753     } 
754
755     /*! \brief Constructs with a specified number of initial elements.
756      *
757      *  \param size number of initial elements.
758      *
759      *  \param val value of initial elements.
760      */
761     vector(unsigned int size, const T& val = T()) :
762         size_(0)
763     {
764         for (unsigned int i = 0; i < size; i++) {
765             push_back(val);
766         }
767     }
768
769     /*! \brief Overwrites the current content with that copied from another
770      *         instance.
771      *
772      *  \param rhs vector to copy.
773      *
774      *  \returns a reference to this.
775      */
776     vector<T, N>& operator=(const vector<T, N>& rhs)
777     {
778         if (this == &rhs) {
779             return *this;
780         }
781
782         if (rhs.size_ != 0) {   
783             assign(rhs.begin(), rhs.end());
784         } else {
785             clear();
786         }
787     
788         return *this;
789     }
790
791     /*! \brief Tests equality against another instance.
792      *
793      *  \param vec the vector against which to compare.
794      */
795     bool operator==(vector<T,N> &vec)
796     {
797         if (size() != vec.size()) {
798             return false;
799         }
800
801         for( unsigned int i = 0; i < size(); ++i ) {
802             if( operator[](i) != vec[i] ) {
803                 return false;
804             }
805         }
806         return true;
807     }
808   
809     //! \brief Conversion operator to T*.
810     operator T* ()             { return data_; }
811
812     //! \brief Conversion operator to const T*.
813     operator const T* () const { return data_; }
814    
815     //! \brief Tests whether this instance has any elements.
816     bool empty (void) const
817     {
818         return size_==0;
819     }
820   
821     //! \brief Returns the maximum number of elements this instance can hold.
822     unsigned int max_size (void) const
823     {
824         return N;
825     }
826
827     //! \brief Returns the maximum number of elements this instance can hold.
828     unsigned int capacity () const
829     {
830         return N;
831     }
832
833     /*! \brief Returns a reference to a given element.
834      *
835      *  \param index which element to access.     *
836      *  \note
837      *  The caller is responsible for ensuring index is >= 0 and < size().
838      */
839     T& operator[](int index)
840     {
841         return data_[index];
842     }
843   
844     /*! \brief Returns a const reference to a given element.
845      *
846      *  \param index which element to access.
847      *
848      *  \note
849      *  The caller is responsible for ensuring index is >= 0 and < size().
850      */
851     const T& operator[](int index) const
852     {
853         return data_[index];
854     }
855   
856     /*! \brief Assigns elements of the vector based on a source iterator range.
857      *
858      *  \param start Beginning iterator of source range
859      *  \param end Enditerator of source range
860      *
861      *  \note
862      *  Will throw an exception if exceptions are enabled and size exceeded.
863      */
864     template<class I>
865     void assign(I start, I end)
866     {
867         clear();   
868         while(start != end) {
869             push_back(*start);
870             start++;
871         }
872     }
873
874     /*! \class iterator
875      * \brief Const iterator class for vectors
876      */
877     class iterator
878     {
879     private:
880         const vector<T,N> *vec_;
881         int index_;
882
883         /**
884          * Internal iterator constructor to capture reference
885          * to the vector it iterates over rather than taking 
886          * the vector by copy.
887          */
888         iterator (const vector<T,N> &vec, int index) :
889             vec_(&vec)
890         {            
891             if( !vec.empty() ) {
892                 index_ = index;
893             } else {
894                 index_ = -1;
895             }
896         }
897
898     public:
899         iterator(void) : 
900             index_(-1),
901             vec_(NULL)
902         {
903         }
904
905         iterator(const iterator& rhs) :
906             vec_(rhs.vec_),
907             index_(rhs.index_)
908         {
909         }
910
911         ~iterator(void) {}
912
913         static iterator begin(const cl::vector<T,N> &vec)
914         {
915             iterator i(vec, 0);
916
917             return i;
918         }
919
920         static iterator end(const cl::vector<T,N> &vec)
921         {
922             iterator i(vec, vec.size());
923
924             return i;
925         }
926     
927         bool operator==(iterator i)
928         {
929             return ((vec_ == i.vec_) && 
930                     (index_ == i.index_));
931         }
932
933         bool operator!=(iterator i)
934         {
935             return (!(*this==i));
936         }
937
938         iterator& operator++()
939         {
940             ++index_;
941             return *this;
942         }
943
944         iterator operator++(int)
945         {
946             iterator retVal(*this);
947             ++index_;
948             return retVal;
949         }
950
951         iterator& operator--()
952         {
953             --index_;
954             return *this;
955         }
956
957         iterator operator--(int)
958         {
959             iterator retVal(*this);
960             --index_;
961             return retVal;
962         }
963
964         const T& operator *() const
965         {
966             return (*vec_)[index_];
967         }
968     };
969
970     iterator begin(void)
971     {
972         return iterator::begin(*this);
973     }
974
975     iterator begin(void) const
976     {
977         return iterator::begin(*this);
978     }
979
980     iterator end(void)
981     {
982         return iterator::end(*this);
983     }
984
985     iterator end(void) const
986     {
987         return iterator::end(*this);
988     }
989
990     T& front(void)
991     {
992         return data_[0];
993     }
994
995     T& back(void)
996     {
997         return data_[size_];
998     }
999
1000     const T& front(void) const
1001     {
1002         return data_[0];
1003     }
1004
1005     const T& back(void) const
1006     {
1007         return data_[size_-1];
1008     }
1009 };  
1010 #endif // #if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR)
1011
1012
1013
1014
1015
1016 namespace detail {
1017 #define __DEFAULT_NOT_INITIALIZED 1 
1018 #define __DEFAULT_BEING_INITIALIZED 2
1019 #define __DEFAULT_INITIALIZED 4
1020
1021     /*
1022      * Compare and exchange primitives are needed for handling of defaults
1023     */
1024     inline int compare_exchange(volatile int * dest, int exchange, int comparand)
1025     {
1026 #ifdef _WIN32
1027         return (int)(InterlockedCompareExchange(
1028            (volatile long*)dest, 
1029            (long)exchange, 
1030            (long)comparand));
1031 #elif defined(__APPLE__) || defined(__MACOSX)
1032                 return OSAtomicOr32Orig((uint32_t)exchange, (volatile uint32_t*)dest);
1033 #else // !_WIN32 || defined(__APPLE__) || defined(__MACOSX)
1034         return (__sync_val_compare_and_swap(
1035             dest, 
1036             comparand, 
1037             exchange));
1038 #endif // !_WIN32
1039     }
1040
1041     inline void fence() { _mm_mfence(); }
1042 }; // namespace detail
1043
1044     
1045 /*! \brief class used to interface between C++ and
1046  *  OpenCL C calls that require arrays of size_t values, whose
1047  *  size is known statically.
1048  */
1049 template <int N>
1050 class size_t
1051
1052 private:
1053     ::size_t data_[N];
1054
1055 public:
1056     //! \brief Initialize size_t to all 0s
1057     size_t()
1058     {
1059         for( int i = 0; i < N; ++i ) {
1060             data_[i] = 0;
1061         }
1062     }
1063
1064     ::size_t& operator[](int index)
1065     {
1066         return data_[index];
1067     }
1068
1069     const ::size_t& operator[](int index) const
1070     {
1071         return data_[index];
1072     }
1073
1074     //! \brief Conversion operator to T*.
1075     operator ::size_t* ()             { return data_; }
1076
1077     //! \brief Conversion operator to const T*.
1078     operator const ::size_t* () const { return data_; }
1079 };
1080
1081 namespace detail {
1082
1083 // Generic getInfoHelper. The final parameter is used to guide overload
1084 // resolution: the actual parameter passed is an int, which makes this
1085 // a worse conversion sequence than a specialization that declares the
1086 // parameter as an int.
1087 template<typename Functor, typename T>
1088 inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
1089 {
1090     return f(name, sizeof(T), param, NULL);
1091 }
1092
1093 // Specialized getInfoHelper for VECTOR_CLASS params
1094 template <typename Func, typename T>
1095 inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS<T>* param, long)
1096 {
1097     ::size_t required;
1098     cl_int err = f(name, 0, NULL, &required);
1099     if (err != CL_SUCCESS) {
1100         return err;
1101     }
1102
1103     T* value = (T*) alloca(required);
1104     err = f(name, required, value, NULL);
1105     if (err != CL_SUCCESS) {
1106         return err;
1107     }
1108
1109     param->assign(&value[0], &value[required/sizeof(T)]);
1110     return CL_SUCCESS;
1111 }
1112
1113 /* Specialization for reference-counted types. This depends on the
1114  * existence of Wrapper<T>::cl_type, and none of the other types having the
1115  * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1116  * does not work, because when using a derived type (e.g. Context) the generic
1117  * template will provide a better match.
1118  */
1119 template <typename Func, typename T>
1120 inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS<T>* param, int, typename T::cl_type = 0)
1121 {
1122     ::size_t required;
1123     cl_int err = f(name, 0, NULL, &required);
1124     if (err != CL_SUCCESS) {
1125         return err;
1126     }
1127
1128     typename T::cl_type * value = (typename T::cl_type *) alloca(required);
1129     err = f(name, required, value, NULL);
1130     if (err != CL_SUCCESS) {
1131         return err;
1132     }
1133
1134     ::size_t elements = required / sizeof(typename T::cl_type);
1135     param->assign(&value[0], &value[elements]);
1136     for (::size_t i = 0; i < elements; i++)
1137     {
1138         if (value[i] != NULL)
1139         {
1140             err = (*param)[i].retain();
1141             if (err != CL_SUCCESS) {
1142                 return err;
1143             }
1144         }
1145     }
1146     return CL_SUCCESS;
1147 }
1148
1149 // Specialized for getInfo<CL_PROGRAM_BINARIES>
1150 template <typename Func>
1151 inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS<char *>* param, int)
1152 {
1153     cl_int err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL);
1154
1155     if (err != CL_SUCCESS) {
1156         return err;
1157     }
1158
1159     return CL_SUCCESS;
1160 }
1161
1162 // Specialized GetInfoHelper for STRING_CLASS params
1163 template <typename Func>
1164 inline cl_int getInfoHelper(Func f, cl_uint name, STRING_CLASS* param, long)
1165 {
1166     ::size_t required;
1167     cl_int err = f(name, 0, NULL, &required);
1168     if (err != CL_SUCCESS) {
1169         return err;
1170     }
1171
1172     char* value = (char*) alloca(required);
1173     err = f(name, required, value, NULL);
1174     if (err != CL_SUCCESS) {
1175         return err;
1176     }
1177
1178     *param = value;
1179     return CL_SUCCESS;
1180 }
1181
1182 // Specialized GetInfoHelper for cl::size_t params
1183 template <typename Func, ::size_t N>
1184 inline cl_int getInfoHelper(Func f, cl_uint name, size_t<N>* param, long)
1185 {
1186     ::size_t required;
1187     cl_int err = f(name, 0, NULL, &required);
1188     if (err != CL_SUCCESS) {
1189         return err;
1190     }
1191
1192     ::size_t* value = (::size_t*) alloca(required);
1193     err = f(name, required, value, NULL);
1194     if (err != CL_SUCCESS) {
1195         return err;
1196     }
1197
1198     for(int i = 0; i < N; ++i) {
1199         (*param)[i] = value[i];
1200     }
1201
1202     return CL_SUCCESS;
1203 }
1204
1205 template<typename T> struct ReferenceHandler;
1206
1207 /* Specialization for reference-counted types. This depends on the
1208  * existence of Wrapper<T>::cl_type, and none of the other types having the
1209  * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1210  * does not work, because when using a derived type (e.g. Context) the generic
1211  * template will provide a better match.
1212  */
1213 template<typename Func, typename T>
1214 inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0)
1215 {
1216     typename T::cl_type value;
1217     cl_int err = f(name, sizeof(value), &value, NULL);
1218     if (err != CL_SUCCESS) {
1219         return err;
1220     }
1221     *param = value;
1222     if (value != NULL)
1223     {
1224         err = param->retain();
1225         if (err != CL_SUCCESS) {
1226             return err;
1227         }
1228     }
1229     return CL_SUCCESS;
1230 }
1231
1232 #define __PARAM_NAME_INFO_1_0(F) \
1233     F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \
1234     F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \
1235     F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \
1236     F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \
1237     F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \
1238     \
1239     F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
1240     F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
1241     F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
1242     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
1243     F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \
1244     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \
1245     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
1246     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
1247     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
1248     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
1249     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
1250     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
1251     F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
1252     F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \
1253     F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
1254     F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
1255     F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
1256     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \
1257     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \
1258     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \
1259     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \
1260     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \
1261     F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \
1262     F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \
1263     F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
1264     F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
1265     F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
1266     F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
1267     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
1268     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
1269     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
1270     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
1271     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
1272     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
1273     F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
1274     F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
1275     F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
1276     F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \
1277     F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
1278     F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
1279     F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
1280     F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
1281     F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \
1282     F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \
1283     F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \
1284     F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \
1285     F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \
1286     F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \
1287     F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \
1288     F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \
1289     \
1290     F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
1291     F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS<Device>) \
1292     F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS<cl_context_properties>) \
1293     \
1294     F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
1295     F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
1296     F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
1297     F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_uint) \
1298     \
1299     F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
1300     F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
1301     F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
1302     F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
1303     \
1304     F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
1305     F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
1306     F(cl_mem_info, CL_MEM_SIZE, ::size_t) \
1307     F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
1308     F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
1309     F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
1310     F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
1311     \
1312     F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
1313     F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \
1314     F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \
1315     F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \
1316     F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \
1317     F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \
1318     F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \
1319     \
1320     F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
1321     F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
1322     F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_addressing_mode) \
1323     F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_filter_mode) \
1324     F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_bool) \
1325     \
1326     F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
1327     F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
1328     F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
1329     F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS<Device>) \
1330     F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \
1331     F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \
1332     F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS<char *>) \
1333     \
1334     F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
1335     F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \
1336     F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \
1337     \
1338     F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \
1339     F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
1340     F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
1341     F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
1342     F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
1343     \
1344     F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \
1345     F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \
1346     F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
1347     \
1348     F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
1349     F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
1350     F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
1351     F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
1352
1353 #if defined(CL_VERSION_1_1)
1354 #define __PARAM_NAME_INFO_1_1(F) \
1355     F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
1356     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
1357     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
1358     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
1359     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
1360     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
1361     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
1362     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
1363     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
1364     F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
1365     F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
1366     F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \
1367     F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, STRING_CLASS) \
1368     \
1369     F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
1370     F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \
1371     \
1372     F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \
1373     F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
1374     \
1375     F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
1376 #endif // CL_VERSION_1_1
1377
1378     
1379 #if defined(CL_VERSION_1_2)
1380 #define __PARAM_NAME_INFO_1_2(F) \
1381     F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer) \
1382     \
1383     F(cl_program_info, CL_PROGRAM_NUM_KERNELS, ::size_t) \
1384     F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, STRING_CLASS) \
1385     \
1386     F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \
1387     \
1388     F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, STRING_CLASS) \
1389     \
1390     F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \
1391     F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \
1392     F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, STRING_CLASS) \
1393     F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, STRING_CLASS) \
1394     \
1395     F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl_device_id) \
1396     F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, VECTOR_CLASS<cl_device_partition_property>) \
1397     F(cl_device_info, CL_DEVICE_PARTITION_TYPE, VECTOR_CLASS<cl_device_partition_property>)  \
1398     F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \
1399     F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, ::size_t) \
1400     F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \
1401     F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, STRING_CLASS)
1402 #endif // #if defined(CL_VERSION_1_2)
1403
1404 #if defined(USE_CL_DEVICE_FISSION)
1405 #define __PARAM_NAME_DEVICE_FISSION(F) \
1406     F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \
1407     F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS<cl_device_partition_property_ext>) \
1408     F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS<cl_device_partition_property_ext>) \
1409     F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
1410     F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS<cl_device_partition_property_ext>)
1411 #endif // USE_CL_DEVICE_FISSION
1412
1413 template <typename enum_type, cl_int Name>
1414 struct param_traits {};
1415
1416 #define __CL_DECLARE_PARAM_TRAITS(token, param_name, T) \
1417 struct token;                                        \
1418 template<>                                           \
1419 struct param_traits<detail:: token,param_name>       \
1420 {                                                    \
1421     enum { value = param_name };                     \
1422     typedef T param_type;                            \
1423 };
1424
1425 __PARAM_NAME_INFO_1_0(__CL_DECLARE_PARAM_TRAITS)
1426 #if defined(CL_VERSION_1_1)
1427 __PARAM_NAME_INFO_1_1(__CL_DECLARE_PARAM_TRAITS)
1428 #endif // CL_VERSION_1_1
1429 #if defined(CL_VERSION_1_2)
1430 __PARAM_NAME_INFO_1_2(__CL_DECLARE_PARAM_TRAITS)
1431 #endif // CL_VERSION_1_1
1432
1433 #if defined(USE_CL_DEVICE_FISSION)
1434 __PARAM_NAME_DEVICE_FISSION(__CL_DECLARE_PARAM_TRAITS);
1435 #endif // USE_CL_DEVICE_FISSION
1436
1437 #ifdef CL_PLATFORM_ICD_SUFFIX_KHR
1438 __CL_DECLARE_PARAM_TRAITS(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, STRING_CLASS)
1439 #endif
1440
1441 #ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD
1442 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong)
1443 #endif
1444
1445 #ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
1446 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, VECTOR_CLASS< ::size_t>)
1447 #endif
1448 #ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
1449 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint)
1450 #endif
1451 #ifdef CL_DEVICE_SIMD_WIDTH_AMD
1452 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint)
1453 #endif
1454 #ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD
1455 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint)
1456 #endif
1457 #ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD
1458 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint)
1459 #endif
1460 #ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD
1461 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint)
1462 #endif
1463 #ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD
1464 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint)
1465 #endif
1466 #ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
1467 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint)
1468 #endif
1469 #ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
1470 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint)
1471 #endif
1472 #ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD
1473 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint)
1474 #endif
1475
1476 #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
1477 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint)
1478 #endif
1479 #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
1480 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint)
1481 #endif
1482 #ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV
1483 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint)
1484 #endif
1485 #ifdef CL_DEVICE_WARP_SIZE_NV
1486 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint)
1487 #endif
1488 #ifdef CL_DEVICE_GPU_OVERLAP_NV
1489 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool)
1490 #endif
1491 #ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV
1492 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool)
1493 #endif
1494 #ifdef CL_DEVICE_INTEGRATED_MEMORY_NV
1495 __CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool)
1496 #endif
1497
1498 // Convenience functions
1499
1500 template <typename Func, typename T>
1501 inline cl_int
1502 getInfo(Func f, cl_uint name, T* param)
1503 {
1504     return getInfoHelper(f, name, param, 0);
1505 }
1506
1507 template <typename Func, typename Arg0>
1508 struct GetInfoFunctor0
1509 {
1510     Func f_; const Arg0& arg0_;
1511     cl_int operator ()(
1512         cl_uint param, ::size_t size, void* value, ::size_t* size_ret)
1513     { return f_(arg0_, param, size, value, size_ret); }
1514 };
1515
1516 template <typename Func, typename Arg0, typename Arg1>
1517 struct GetInfoFunctor1
1518 {
1519     Func f_; const Arg0& arg0_; const Arg1& arg1_;
1520     cl_int operator ()(
1521         cl_uint param, ::size_t size, void* value, ::size_t* size_ret)
1522     { return f_(arg0_, arg1_, param, size, value, size_ret); }
1523 };
1524
1525 template <typename Func, typename Arg0, typename T>
1526 inline cl_int
1527 getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
1528 {
1529     GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
1530     return getInfoHelper(f0, name, param, 0);
1531 }
1532
1533 template <typename Func, typename Arg0, typename Arg1, typename T>
1534 inline cl_int
1535 getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
1536 {
1537     GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
1538     return getInfoHelper(f0, name, param, 0);
1539 }
1540
1541 template<typename T>
1542 struct ReferenceHandler
1543 { };
1544
1545 #if defined(CL_VERSION_1_2)
1546 /**
1547  * OpenCL 1.2 devices do have retain/release.
1548  */
1549 template <>
1550 struct ReferenceHandler<cl_device_id>
1551 {
1552     /**
1553      * Retain the device.
1554      * \param device A valid device created using createSubDevices
1555      * \return 
1556      *   CL_SUCCESS if the function executed successfully.
1557      *   CL_INVALID_DEVICE if device was not a valid subdevice
1558      *   CL_OUT_OF_RESOURCES
1559      *   CL_OUT_OF_HOST_MEMORY
1560      */
1561     static cl_int retain(cl_device_id device)
1562     { return ::clRetainDevice(device); }
1563     /**
1564      * Retain the device.
1565      * \param device A valid device created using createSubDevices
1566      * \return 
1567      *   CL_SUCCESS if the function executed successfully.
1568      *   CL_INVALID_DEVICE if device was not a valid subdevice
1569      *   CL_OUT_OF_RESOURCES
1570      *   CL_OUT_OF_HOST_MEMORY
1571      */
1572     static cl_int release(cl_device_id device)
1573     { return ::clReleaseDevice(device); }
1574 };
1575 #else // #if defined(CL_VERSION_1_2)
1576 /**
1577  * OpenCL 1.1 devices do not have retain/release.
1578  */
1579 template <>
1580 struct ReferenceHandler<cl_device_id>
1581 {
1582     // cl_device_id does not have retain().
1583     static cl_int retain(cl_device_id)
1584     { return CL_SUCCESS; }
1585     // cl_device_id does not have release().
1586     static cl_int release(cl_device_id)
1587     { return CL_SUCCESS; }
1588 };
1589 #endif // #if defined(CL_VERSION_1_2)
1590
1591 template <>
1592 struct ReferenceHandler<cl_platform_id>
1593 {
1594     // cl_platform_id does not have retain().
1595     static cl_int retain(cl_platform_id)
1596     { return CL_SUCCESS; }
1597     // cl_platform_id does not have release().
1598     static cl_int release(cl_platform_id)
1599     { return CL_SUCCESS; }
1600 };
1601
1602 template <>
1603 struct ReferenceHandler<cl_context>
1604 {
1605     static cl_int retain(cl_context context)
1606     { return ::clRetainContext(context); }
1607     static cl_int release(cl_context context)
1608     { return ::clReleaseContext(context); }
1609 };
1610
1611 template <>
1612 struct ReferenceHandler<cl_command_queue>
1613 {
1614     static cl_int retain(cl_command_queue queue)
1615     { return ::clRetainCommandQueue(queue); }
1616     static cl_int release(cl_command_queue queue)
1617     { return ::clReleaseCommandQueue(queue); }
1618 };
1619
1620 template <>
1621 struct ReferenceHandler<cl_mem>
1622 {
1623     static cl_int retain(cl_mem memory)
1624     { return ::clRetainMemObject(memory); }
1625     static cl_int release(cl_mem memory)
1626     { return ::clReleaseMemObject(memory); }
1627 };
1628
1629 template <>
1630 struct ReferenceHandler<cl_sampler>
1631 {
1632     static cl_int retain(cl_sampler sampler)
1633     { return ::clRetainSampler(sampler); }
1634     static cl_int release(cl_sampler sampler)
1635     { return ::clReleaseSampler(sampler); }
1636 };
1637
1638 template <>
1639 struct ReferenceHandler<cl_program>
1640 {
1641     static cl_int retain(cl_program program)
1642     { return ::clRetainProgram(program); }
1643     static cl_int release(cl_program program)
1644     { return ::clReleaseProgram(program); }
1645 };
1646
1647 template <>
1648 struct ReferenceHandler<cl_kernel>
1649 {
1650     static cl_int retain(cl_kernel kernel)
1651     { return ::clRetainKernel(kernel); }
1652     static cl_int release(cl_kernel kernel)
1653     { return ::clReleaseKernel(kernel); }
1654 };
1655
1656 template <>
1657 struct ReferenceHandler<cl_event>
1658 {
1659     static cl_int retain(cl_event event)
1660     { return ::clRetainEvent(event); }
1661     static cl_int release(cl_event event)
1662     { return ::clReleaseEvent(event); }
1663 };
1664
1665
1666 // Extracts version number with major in the upper 16 bits, minor in the lower 16
1667 static cl_uint getVersion(const char *versionInfo)
1668 {
1669     int highVersion = 0;
1670     int lowVersion = 0;
1671     int index = 7;
1672     while(versionInfo[index] != '.' ) {
1673         highVersion *= 10;
1674         highVersion += versionInfo[index]-'0';
1675         ++index;
1676     }
1677     ++index;
1678     while(versionInfo[index] != ' ' ) {
1679         lowVersion *= 10;
1680         lowVersion += versionInfo[index]-'0';
1681         ++index;
1682     }
1683     return (highVersion << 16) | lowVersion;
1684 }
1685
1686 static cl_uint getPlatformVersion(cl_platform_id platform)
1687 {
1688     ::size_t size = 0;
1689     clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL, &size);
1690     char *versionInfo = (char *) alloca(size);
1691     clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, &versionInfo[0], &size);
1692     return getVersion(versionInfo);
1693 }
1694
1695 static cl_uint getDevicePlatformVersion(cl_device_id device)
1696 {
1697     cl_platform_id platform;
1698     clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL);
1699     return getPlatformVersion(platform);
1700 }
1701
1702 #if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1703 static cl_uint getContextPlatformVersion(cl_context context)
1704 {
1705     // The platform cannot be queried directly, so we first have to grab a
1706     // device and obtain its context
1707     ::size_t size = 0;
1708     clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size);
1709     if (size == 0)
1710         return 0;
1711     cl_device_id *devices = (cl_device_id *) alloca(size);
1712     clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices, NULL);
1713     return getDevicePlatformVersion(devices[0]);
1714 }
1715 #endif // #if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1716
1717 template <typename T>
1718 class Wrapper
1719 {
1720 public:
1721     typedef T cl_type;
1722
1723 protected:
1724     cl_type object_;
1725
1726 public:
1727     Wrapper() : object_(NULL) { }
1728
1729     Wrapper(const cl_type &obj) : object_(obj) { }
1730
1731     ~Wrapper()
1732     {
1733         if (object_ != NULL) { release(); }
1734     }
1735
1736     Wrapper(const Wrapper<cl_type>& rhs)
1737     {
1738         object_ = rhs.object_;
1739         if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); }
1740     }
1741
1742     Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
1743     {
1744         if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); }
1745         object_ = rhs.object_;
1746         if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); }
1747         return *this;
1748     }
1749
1750     Wrapper<cl_type>& operator = (const cl_type &rhs)
1751     {
1752         if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); }
1753         object_ = rhs;
1754         return *this;
1755     }
1756
1757     cl_type operator ()() const { return object_; }
1758
1759     cl_type& operator ()() { return object_; }
1760
1761 protected:
1762     template<typename Func, typename U>
1763     friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
1764
1765     cl_int retain() const
1766     {
1767         return ReferenceHandler<cl_type>::retain(object_);
1768     }
1769
1770     cl_int release() const
1771     {
1772         return ReferenceHandler<cl_type>::release(object_);
1773     }
1774 };
1775
1776 template <>
1777 class Wrapper<cl_device_id>
1778 {
1779 public:
1780     typedef cl_device_id cl_type;
1781
1782 protected:
1783     cl_type object_;
1784     bool referenceCountable_;
1785
1786     static bool isReferenceCountable(cl_device_id device)
1787     {
1788         bool retVal = false;
1789         if (device != NULL) {
1790             int version = getDevicePlatformVersion(device);
1791             if(version > ((1 << 16) + 1)) {
1792                 retVal = true;
1793             }
1794         }
1795         return retVal;
1796     }
1797
1798 public:
1799     Wrapper() : object_(NULL), referenceCountable_(false) 
1800     { 
1801     }
1802     
1803     Wrapper(const cl_type &obj) : object_(obj), referenceCountable_(false) 
1804     {
1805         referenceCountable_ = isReferenceCountable(obj); 
1806     }
1807
1808     ~Wrapper()
1809     {
1810         if (object_ != NULL) { release(); }
1811     }
1812     
1813     Wrapper(const Wrapper<cl_type>& rhs)
1814     {
1815         object_ = rhs.object_;
1816         referenceCountable_ = isReferenceCountable(object_); 
1817         if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); }
1818     }
1819
1820     Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
1821     {
1822         if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); }
1823         object_ = rhs.object_;
1824         referenceCountable_ = rhs.referenceCountable_;
1825         if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); }
1826         return *this;
1827     }
1828
1829     Wrapper<cl_type>& operator = (const cl_type &rhs)
1830     {
1831         if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); }
1832         object_ = rhs;
1833         referenceCountable_ = isReferenceCountable(object_); 
1834         return *this;
1835     }
1836
1837     cl_type operator ()() const { return object_; }
1838
1839     cl_type& operator ()() { return object_; }
1840
1841 protected:
1842     template<typename Func, typename U>
1843     friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
1844
1845     template<typename Func, typename U>
1846     friend inline cl_int getInfoHelper(Func, cl_uint, VECTOR_CLASS<U>*, int, typename U::cl_type);
1847
1848     cl_int retain() const
1849     {
1850         if( referenceCountable_ ) {
1851             return ReferenceHandler<cl_type>::retain(object_);
1852         }
1853         else {
1854             return CL_SUCCESS;
1855         }
1856     }
1857
1858     cl_int release() const
1859     {
1860         if( referenceCountable_ ) {
1861             return ReferenceHandler<cl_type>::release(object_);
1862         }
1863         else {
1864             return CL_SUCCESS;
1865         }
1866     }
1867 };
1868
1869 } // namespace detail
1870 //! \endcond
1871
1872 /*! \stuct ImageFormat
1873  *  \brief Adds constructors and member functions for cl_image_format.
1874  *
1875  *  \see cl_image_format
1876  */
1877 struct ImageFormat : public cl_image_format
1878 {
1879     //! \brief Default constructor - performs no initialization.
1880     ImageFormat(){}
1881
1882     //! \brief Initializing constructor.
1883     ImageFormat(cl_channel_order order, cl_channel_type type)
1884     {
1885         image_channel_order = order;
1886         image_channel_data_type = type;
1887     }
1888
1889     //! \brief Assignment operator.
1890     ImageFormat& operator = (const ImageFormat& rhs)
1891     {
1892         if (this != &rhs) {
1893             this->image_channel_data_type = rhs.image_channel_data_type;
1894             this->image_channel_order     = rhs.image_channel_order;
1895         }
1896         return *this;
1897     }
1898 };
1899
1900 /*! \brief Class interface for cl_device_id.
1901  *
1902  *  \note Copies of these objects are inexpensive, since they don't 'own'
1903  *        any underlying resources or data structures.
1904  *
1905  *  \see cl_device_id
1906  */
1907 class Device : public detail::Wrapper<cl_device_id>
1908 {
1909 public:
1910     //! \brief Default constructor - initializes to NULL.
1911     Device() : detail::Wrapper<cl_type>() { }
1912
1913     /*! \brief Copy constructor.
1914      * 
1915      *  This simply copies the device ID value, which is an inexpensive operation.
1916      */
1917     Device(const Device& device) : detail::Wrapper<cl_type>(device) { }
1918
1919     /*! \brief Constructor from cl_device_id.
1920      * 
1921      *  This simply copies the device ID value, which is an inexpensive operation.
1922      */
1923     Device(const cl_device_id &device) : detail::Wrapper<cl_type>(device) { }
1924
1925     /*! \brief Returns the first device on the default context.
1926      *
1927      *  \see Context::getDefault()
1928      */
1929     static Device getDefault(cl_int * err = NULL);
1930
1931     /*! \brief Assignment operator from Device.
1932      * 
1933      *  This simply copies the device ID value, which is an inexpensive operation.
1934      */
1935     Device& operator = (const Device& rhs)
1936     {
1937         if (this != &rhs) {
1938             detail::Wrapper<cl_type>::operator=(rhs);
1939         }
1940         return *this;
1941     }
1942
1943     /*! \brief Assignment operator from cl_device_id.
1944      * 
1945      *  This simply copies the device ID value, which is an inexpensive operation.
1946      */
1947     Device& operator = (const cl_device_id& rhs)
1948     {
1949         detail::Wrapper<cl_type>::operator=(rhs);
1950         return *this;
1951     }
1952
1953     //! \brief Wrapper for clGetDeviceInfo().
1954     template <typename T>
1955     cl_int getInfo(cl_device_info name, T* param) const
1956     {
1957         return detail::errHandler(
1958             detail::getInfo(&::clGetDeviceInfo, object_, name, param),
1959             __GET_DEVICE_INFO_ERR);
1960     }
1961
1962     //! \brief Wrapper for clGetDeviceInfo() that returns by value.
1963     template <cl_int name> typename
1964     detail::param_traits<detail::cl_device_info, name>::param_type
1965     getInfo(cl_int* err = NULL) const
1966     {
1967         typename detail::param_traits<
1968             detail::cl_device_info, name>::param_type param;
1969         cl_int result = getInfo(name, &param);
1970         if (err != NULL) {
1971             *err = result;
1972         }
1973         return param;
1974     }
1975
1976     /**
1977      * CL 1.2 version
1978      */
1979 #if defined(CL_VERSION_1_2)
1980     //! \brief Wrapper for clCreateSubDevicesEXT().
1981     cl_int createSubDevices(
1982         const cl_device_partition_property * properties,
1983         VECTOR_CLASS<Device>* devices)
1984     {
1985         cl_uint n = 0;
1986         cl_int err = clCreateSubDevices(object_, properties, 0, NULL, &n);
1987         if (err != CL_SUCCESS) {
1988             return detail::errHandler(err, __CREATE_SUB_DEVICES);
1989         }
1990
1991         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
1992         err = clCreateSubDevices(object_, properties, n, ids, NULL);
1993         if (err != CL_SUCCESS) {
1994             return detail::errHandler(err, __CREATE_SUB_DEVICES);
1995         }
1996
1997         devices->assign(&ids[0], &ids[n]);
1998         return CL_SUCCESS;
1999     }
2000 #endif // #if defined(CL_VERSION_1_2)
2001
2002 /**
2003  * CL 1.1 version that uses device fission.
2004  */
2005 #if defined(CL_VERSION_1_1)
2006 #if defined(USE_CL_DEVICE_FISSION)
2007     cl_int createSubDevices(
2008         const cl_device_partition_property_ext * properties,
2009         VECTOR_CLASS<Device>* devices)
2010     {
2011         typedef CL_API_ENTRY cl_int 
2012             ( CL_API_CALL * PFN_clCreateSubDevicesEXT)(
2013                 cl_device_id /*in_device*/,
2014                 const cl_device_partition_property_ext * /* properties */,
2015                 cl_uint /*num_entries*/,
2016                 cl_device_id * /*out_devices*/,
2017                 cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1;
2018
2019         static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL;
2020         __INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT);
2021
2022         cl_uint n = 0;
2023         cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n);
2024         if (err != CL_SUCCESS) {
2025             return detail::errHandler(err, __CREATE_SUB_DEVICES);
2026         }
2027
2028         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
2029         err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL);
2030         if (err != CL_SUCCESS) {
2031             return detail::errHandler(err, __CREATE_SUB_DEVICES);
2032         }
2033
2034         devices->assign(&ids[0], &ids[n]);
2035         return CL_SUCCESS;
2036     }
2037 #endif // #if defined(USE_CL_DEVICE_FISSION)
2038 #endif // #if defined(CL_VERSION_1_1)
2039 };
2040
2041 /*! \brief Class interface for cl_platform_id.
2042  *
2043  *  \note Copies of these objects are inexpensive, since they don't 'own'
2044  *        any underlying resources or data structures.
2045  *
2046  *  \see cl_platform_id
2047  */
2048 class Platform : public detail::Wrapper<cl_platform_id>
2049 {
2050 public:
2051     //! \brief Default constructor - initializes to NULL.
2052     Platform() : detail::Wrapper<cl_type>()  { }
2053
2054     /*! \brief Copy constructor.
2055      * 
2056      *  This simply copies the platform ID value, which is an inexpensive operation.
2057      */
2058     Platform(const Platform& platform) : detail::Wrapper<cl_type>(platform) { }
2059
2060     /*! \brief Constructor from cl_platform_id.
2061      * 
2062      *  This simply copies the platform ID value, which is an inexpensive operation.
2063      */
2064     Platform(const cl_platform_id &platform) : detail::Wrapper<cl_type>(platform) { }
2065
2066     /*! \brief Assignment operator from Platform.
2067      * 
2068      *  This simply copies the platform ID value, which is an inexpensive operation.
2069      */
2070     Platform& operator = (const Platform& rhs)
2071     {
2072         if (this != &rhs) {
2073             detail::Wrapper<cl_type>::operator=(rhs);
2074         }
2075         return *this;
2076     }
2077
2078     /*! \brief Assignment operator from cl_platform_id.
2079      * 
2080      *  This simply copies the platform ID value, which is an inexpensive operation.
2081      */
2082     Platform& operator = (const cl_platform_id& rhs)
2083     {
2084         detail::Wrapper<cl_type>::operator=(rhs);
2085         return *this;
2086     }
2087
2088     //! \brief Wrapper for clGetPlatformInfo().
2089     cl_int getInfo(cl_platform_info name, STRING_CLASS* param) const
2090     {
2091         return detail::errHandler(
2092             detail::getInfo(&::clGetPlatformInfo, object_, name, param),
2093             __GET_PLATFORM_INFO_ERR);
2094     }
2095
2096     //! \brief Wrapper for clGetPlatformInfo() that returns by value.
2097     template <cl_int name> typename
2098     detail::param_traits<detail::cl_platform_info, name>::param_type
2099     getInfo(cl_int* err = NULL) const
2100     {
2101         typename detail::param_traits<
2102             detail::cl_platform_info, name>::param_type param;
2103         cl_int result = getInfo(name, &param);
2104         if (err != NULL) {
2105             *err = result;
2106         }
2107         return param;
2108     }
2109
2110     /*! \brief Gets a list of devices for this platform.
2111      * 
2112      *  Wraps clGetDeviceIDs().
2113      */
2114     cl_int getDevices(
2115         cl_device_type type,
2116         VECTOR_CLASS<Device>* devices) const
2117     {
2118         cl_uint n = 0;
2119         if( devices == NULL ) {
2120             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2121         }
2122         cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n);
2123         if (err != CL_SUCCESS) {
2124             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2125         }
2126
2127         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
2128         err = ::clGetDeviceIDs(object_, type, n, ids, NULL);
2129         if (err != CL_SUCCESS) {
2130             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2131         }
2132
2133         devices->assign(&ids[0], &ids[n]);
2134         return CL_SUCCESS;
2135     }
2136
2137 #if defined(USE_DX_INTEROP)
2138    /*! \brief Get the list of available D3D10 devices.
2139      *
2140      *  \param d3d_device_source.
2141      *
2142      *  \param d3d_object.
2143      *
2144      *  \param d3d_device_set.
2145      *
2146      *  \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device
2147      *  values returned in devices can be used to identify a specific OpenCL
2148      *  device. If \a devices argument is NULL, this argument is ignored.
2149      *
2150      *  \return One of the following values:
2151      *    - CL_SUCCESS if the function is executed successfully.
2152      *
2153      *  The application can query specific capabilities of the OpenCL device(s)
2154      *  returned by cl::getDevices. This can be used by the application to
2155      *  determine which device(s) to use.
2156      *
2157      * \note In the case that exceptions are enabled and a return value
2158      * other than CL_SUCCESS is generated, then cl::Error exception is
2159      * generated.
2160      */
2161     cl_int getDevices(
2162         cl_d3d10_device_source_khr d3d_device_source,
2163         void *                     d3d_object,
2164         cl_d3d10_device_set_khr    d3d_device_set,
2165         VECTOR_CLASS<Device>* devices) const
2166     {
2167         typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
2168             cl_platform_id platform, 
2169             cl_d3d10_device_source_khr d3d_device_source, 
2170             void * d3d_object,
2171             cl_d3d10_device_set_khr d3d_device_set,
2172             cl_uint num_entries,
2173             cl_device_id * devices,
2174             cl_uint* num_devices);
2175
2176         if( devices == NULL ) {
2177             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2178         }
2179
2180         static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL;
2181         __INIT_CL_EXT_FCN_PTR_PLATFORM(object_, clGetDeviceIDsFromD3D10KHR);
2182
2183         cl_uint n = 0;
2184         cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
2185             object_, 
2186             d3d_device_source, 
2187             d3d_object,
2188             d3d_device_set, 
2189             0, 
2190             NULL, 
2191             &n);
2192         if (err != CL_SUCCESS) {
2193             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2194         }
2195
2196         cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id));
2197         err = pfn_clGetDeviceIDsFromD3D10KHR(
2198             object_, 
2199             d3d_device_source, 
2200             d3d_object,
2201             d3d_device_set,
2202             n, 
2203             ids, 
2204             NULL);
2205         if (err != CL_SUCCESS) {
2206             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2207         }
2208
2209         devices->assign(&ids[0], &ids[n]);
2210         return CL_SUCCESS;
2211     }
2212 #endif
2213
2214     /*! \brief Gets a list of available platforms.
2215      * 
2216      *  Wraps clGetPlatformIDs().
2217      */
2218     static cl_int get(
2219         VECTOR_CLASS<Platform>* platforms)
2220     {
2221         cl_uint n = 0;
2222
2223         if( platforms == NULL ) {
2224             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2225         }
2226
2227         cl_int err = ::clGetPlatformIDs(0, NULL, &n);
2228         if (err != CL_SUCCESS) {
2229             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2230         }
2231
2232         cl_platform_id* ids = (cl_platform_id*) alloca(
2233             n * sizeof(cl_platform_id));
2234         err = ::clGetPlatformIDs(n, ids, NULL);
2235         if (err != CL_SUCCESS) {
2236             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2237         }
2238
2239         platforms->assign(&ids[0], &ids[n]);
2240         return CL_SUCCESS;
2241     }
2242
2243     /*! \brief Gets the first available platform.
2244      * 
2245      *  Wraps clGetPlatformIDs(), returning the first result.
2246      */
2247     static cl_int get(
2248         Platform * platform)
2249     {
2250         cl_uint n = 0;
2251
2252         if( platform == NULL ) {
2253             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2254         }
2255
2256         cl_int err = ::clGetPlatformIDs(0, NULL, &n);
2257         if (err != CL_SUCCESS) {
2258             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2259         }
2260
2261         cl_platform_id* ids = (cl_platform_id*) alloca(
2262             n * sizeof(cl_platform_id));
2263         err = ::clGetPlatformIDs(n, ids, NULL);
2264         if (err != CL_SUCCESS) {
2265             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2266         }
2267
2268         *platform = ids[0];
2269         return CL_SUCCESS;
2270     }
2271
2272     /*! \brief Gets the first available platform, returning it by value.
2273      * 
2274      *  Wraps clGetPlatformIDs(), returning the first result.
2275      */
2276     static Platform get(
2277         cl_int * errResult = NULL)
2278     {
2279         Platform platform;
2280         cl_uint n = 0;
2281         cl_int err = ::clGetPlatformIDs(0, NULL, &n);
2282         if (err != CL_SUCCESS) {
2283             detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2284             if (errResult != NULL) {
2285                 *errResult = err;
2286             }
2287         }
2288
2289         cl_platform_id* ids = (cl_platform_id*) alloca(
2290             n * sizeof(cl_platform_id));
2291         err = ::clGetPlatformIDs(n, ids, NULL);
2292
2293         if (err != CL_SUCCESS) {
2294             detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2295         }
2296
2297         if (errResult != NULL) {
2298             *errResult = err;
2299         }
2300         
2301         return ids[0];
2302     }
2303
2304     static Platform getDefault( 
2305         cl_int *errResult = NULL )
2306     {
2307         return get(errResult);
2308     }
2309
2310     
2311 #if defined(CL_VERSION_1_2)
2312     //! \brief Wrapper for clUnloadCompiler().
2313     cl_int
2314     unloadCompiler()
2315     {
2316         return ::clUnloadPlatformCompiler(object_);
2317     }
2318 #endif // #if defined(CL_VERSION_1_2)
2319 }; // class Platform
2320
2321 /**
2322  * Deprecated APIs for 1.2
2323  */
2324 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2))
2325 /**
2326  * Unload the OpenCL compiler.
2327  * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead.
2328  */
2329 inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int
2330 UnloadCompiler() CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
2331 inline cl_int
2332 UnloadCompiler()
2333 {
2334     return ::clUnloadCompiler();
2335 }
2336 #endif // #if defined(CL_VERSION_1_1)
2337
2338 /*! \brief Class interface for cl_context.
2339  *
2340  *  \note Copies of these objects are shallow, meaning that the copy will refer
2341  *        to the same underlying cl_context as the original.  For details, see
2342  *        clRetainContext() and clReleaseContext().
2343  *
2344  *  \see cl_context
2345  */
2346 class Context 
2347     : public detail::Wrapper<cl_context>
2348 {
2349 private:
2350     static volatile int default_initialized_;
2351     static Context default_;
2352     static volatile cl_int default_error_;
2353 public:
2354     /*! \brief Destructor.
2355      *
2356      *  This calls clReleaseContext() on the value held by this instance.
2357      */
2358     ~Context() { }
2359
2360     /*! \brief Constructs a context including a list of specified devices.
2361      *
2362      *  Wraps clCreateContext().
2363      */
2364     Context(
2365         const VECTOR_CLASS<Device>& devices,
2366         cl_context_properties* properties = NULL,
2367         void (CL_CALLBACK * notifyFptr)(
2368             const char *,
2369             const void *,
2370             ::size_t,
2371             void *) = NULL,
2372         void* data = NULL,
2373         cl_int* err = NULL)
2374     {
2375         cl_int error;
2376
2377         ::size_t numDevices = devices.size();
2378         cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id));
2379         for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
2380             deviceIDs[deviceIndex] = (devices[deviceIndex])();
2381         }
2382
2383         object_ = ::clCreateContext(
2384             properties, (cl_uint) numDevices,
2385             deviceIDs,
2386             notifyFptr, data, &error);
2387
2388         detail::errHandler(error, __CREATE_CONTEXT_ERR);
2389         if (err != NULL) {
2390             *err = error;
2391         }
2392     }
2393
2394     Context(
2395         const Device& device,
2396         cl_context_properties* properties = NULL,
2397         void (CL_CALLBACK * notifyFptr)(
2398             const char *,
2399             const void *,
2400             ::size_t,
2401             void *) = NULL,
2402         void* data = NULL,
2403         cl_int* err = NULL)
2404     {
2405         cl_int error;
2406
2407         cl_device_id deviceID = device();
2408
2409         object_ = ::clCreateContext(
2410             properties, 1,
2411             &deviceID,
2412             notifyFptr, data, &error);
2413
2414         detail::errHandler(error, __CREATE_CONTEXT_ERR);
2415         if (err != NULL) {
2416             *err = error;
2417         }
2418     }
2419
2420     /*! \brief Constructs a context including all or a subset of devices of a specified type.
2421      *
2422      *  Wraps clCreateContextFromType().
2423      */
2424     Context(
2425         cl_device_type type,
2426         cl_context_properties* properties = NULL,
2427         void (CL_CALLBACK * notifyFptr)(
2428             const char *,
2429             const void *,
2430             ::size_t,
2431             void *) = NULL,
2432         void* data = NULL,
2433         cl_int* err = NULL)
2434     {
2435         cl_int error;
2436
2437 #if !defined(__APPLE__) || !defined(__MACOS)
2438         cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 };
2439
2440         if (properties == NULL) {
2441             // Get a valid platform ID as we cannot send in a blank one
2442             VECTOR_CLASS<Platform> platforms;
2443             error = Platform::get(&platforms);
2444             if (error != CL_SUCCESS) {
2445                 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
2446                 if (err != NULL) {
2447                     *err = error;
2448                 }
2449                 return;
2450             }
2451
2452             // Check the platforms we found for a device of our specified type
2453             cl_context_properties platform_id = 0;
2454             for (unsigned int i = 0; i < platforms.size(); i++) {
2455
2456                 VECTOR_CLASS<Device> devices;
2457
2458 #if defined(__CL_ENABLE_EXCEPTIONS)
2459                 try {
2460 #endif
2461
2462                     error = platforms[i].getDevices(type, &devices);
2463
2464 #if defined(__CL_ENABLE_EXCEPTIONS)
2465                 } catch (Error) {}
2466     // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type
2467     // We do error checking next anyway, and can throw there if needed
2468 #endif
2469
2470                 // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND
2471                 if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) {
2472                     detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
2473                     if (err != NULL) {
2474                         *err = error;
2475                     }
2476                 }
2477
2478                 if (devices.size() > 0) {
2479                     platform_id = (cl_context_properties)platforms[i]();
2480                     break;
2481                 }
2482             }
2483
2484             if (platform_id == 0) {
2485                 detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR);
2486                 if (err != NULL) {
2487                     *err = CL_DEVICE_NOT_FOUND;
2488                 }
2489                 return;
2490             }
2491
2492             prop[1] = platform_id;
2493             properties = &prop[0];
2494         }
2495 #endif
2496         object_ = ::clCreateContextFromType(
2497             properties, type, notifyFptr, data, &error);
2498
2499         detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
2500         if (err != NULL) {
2501             *err = error;
2502         }
2503     }
2504
2505     /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT.
2506      *
2507      *  \note All calls to this function return the same cl_context as the first.
2508      */
2509     static Context getDefault(cl_int * err = NULL) 
2510     {
2511         int state = detail::compare_exchange(
2512             &default_initialized_, 
2513             __DEFAULT_BEING_INITIALIZED, __DEFAULT_NOT_INITIALIZED);
2514         
2515         if (state & __DEFAULT_INITIALIZED) {
2516             if (err != NULL) {
2517                 *err = default_error_;
2518             }
2519             return default_;
2520         }
2521
2522         if (state & __DEFAULT_BEING_INITIALIZED) {
2523               // Assume writes will propagate eventually...
2524               while(default_initialized_ != __DEFAULT_INITIALIZED) {
2525                   detail::fence();
2526               }
2527
2528             if (err != NULL) {
2529                 *err = default_error_;
2530             }
2531             return default_;
2532         }
2533
2534         cl_int error;
2535         default_ = Context(
2536             CL_DEVICE_TYPE_DEFAULT,
2537             NULL,
2538             NULL,
2539             NULL,
2540             &error);
2541
2542         detail::fence();
2543
2544         default_error_ = error;
2545         // Assume writes will propagate eventually...
2546         default_initialized_ = __DEFAULT_INITIALIZED;
2547
2548         detail::fence();
2549
2550         if (err != NULL) {
2551             *err = default_error_;
2552         }
2553         return default_;
2554
2555     }
2556
2557     //! \brief Default constructor - initializes to NULL.
2558     Context() : detail::Wrapper<cl_type>() { }
2559
2560     /*! \brief Copy constructor.
2561      * 
2562      *  This calls clRetainContext() on the parameter's cl_context.
2563      */
2564     Context(const Context& context) : detail::Wrapper<cl_type>(context) { }
2565
2566     /*! \brief Constructor from cl_context - takes ownership.
2567      * 
2568      *  This effectively transfers ownership of a refcount on the cl_context
2569      *  into the new Context object.
2570      */
2571     __CL_EXPLICIT_CONSTRUCTORS Context(const cl_context& context) : detail::Wrapper<cl_type>(context) { }
2572
2573     /*! \brief Assignment operator from Context.
2574      * 
2575      *  This calls clRetainContext() on the parameter and clReleaseContext() on
2576      *  the previous value held by this instance.
2577      */
2578     Context& operator = (const Context& rhs)
2579     {
2580         if (this != &rhs) {
2581             detail::Wrapper<cl_type>::operator=(rhs);
2582         }
2583         return *this;
2584     }
2585
2586     /*! \brief Assignment operator from cl_context - takes ownership.
2587      * 
2588      *  This effectively transfers ownership of a refcount on the rhs and calls
2589      *  clReleaseContext() on the value previously held by this instance.
2590      */
2591     Context& operator = (const cl_context& rhs)
2592     {
2593         detail::Wrapper<cl_type>::operator=(rhs);
2594         return *this;
2595     }
2596
2597     //! \brief Wrapper for clGetContextInfo().
2598     template <typename T>
2599     cl_int getInfo(cl_context_info name, T* param) const
2600     {
2601         return detail::errHandler(
2602             detail::getInfo(&::clGetContextInfo, object_, name, param),
2603             __GET_CONTEXT_INFO_ERR);
2604     }
2605
2606     //! \brief Wrapper for clGetContextInfo() that returns by value.
2607     template <cl_int name> typename
2608     detail::param_traits<detail::cl_context_info, name>::param_type
2609     getInfo(cl_int* err = NULL) const
2610     {
2611         typename detail::param_traits<
2612             detail::cl_context_info, name>::param_type param;
2613         cl_int result = getInfo(name, &param);
2614         if (err != NULL) {
2615             *err = result;
2616         }
2617         return param;
2618     }
2619
2620     /*! \brief Gets a list of supported image formats.
2621      *  
2622      *  Wraps clGetSupportedImageFormats().
2623      */
2624     cl_int getSupportedImageFormats(
2625         cl_mem_flags flags,
2626         cl_mem_object_type type,
2627         VECTOR_CLASS<ImageFormat>* formats) const
2628     {
2629         cl_uint numEntries;
2630         cl_int err = ::clGetSupportedImageFormats(
2631            object_, 
2632            flags,
2633            type, 
2634            0, 
2635            NULL, 
2636            &numEntries);
2637         if (err != CL_SUCCESS) {
2638             return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
2639         }
2640
2641         ImageFormat* value = (ImageFormat*)
2642             alloca(numEntries * sizeof(ImageFormat));
2643         err = ::clGetSupportedImageFormats(
2644             object_, 
2645             flags, 
2646             type, 
2647             numEntries,
2648             (cl_image_format*) value, 
2649             NULL);
2650         if (err != CL_SUCCESS) {
2651             return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
2652         }
2653
2654         formats->assign(&value[0], &value[numEntries]);
2655         return CL_SUCCESS;
2656     }
2657 };
2658
2659 inline Device Device::getDefault(cl_int * err)
2660 {
2661     cl_int error;
2662     Device device;
2663
2664     Context context = Context::getDefault(&error);
2665     detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
2666
2667     if (error != CL_SUCCESS) {
2668         if (err != NULL) {
2669             *err = error;
2670         }
2671     }
2672     else {
2673         device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
2674         if (err != NULL) {
2675             *err = CL_SUCCESS;
2676         }
2677     }
2678
2679     return device;
2680 }
2681
2682
2683 #ifdef _WIN32
2684 __declspec(selectany) volatile int Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED;
2685 __declspec(selectany) Context Context::default_;
2686 __declspec(selectany) volatile cl_int Context::default_error_ = CL_SUCCESS;
2687 #else
2688 __attribute__((weak)) volatile int Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED;
2689 __attribute__((weak)) Context Context::default_;
2690 __attribute__((weak)) volatile cl_int Context::default_error_ = CL_SUCCESS;
2691 #endif
2692
2693 /*! \brief Class interface for cl_event.
2694  *
2695  *  \note Copies of these objects are shallow, meaning that the copy will refer
2696  *        to the same underlying cl_event as the original.  For details, see
2697  *        clRetainEvent() and clReleaseEvent().
2698  *
2699  *  \see cl_event
2700  */
2701 class Event : public detail::Wrapper<cl_event>
2702 {
2703 public:
2704     /*! \brief Destructor.
2705      *
2706      *  This calls clReleaseEvent() on the value held by this instance.
2707      */
2708     ~Event() { }
2709  
2710     //! \brief Default constructor - initializes to NULL.
2711     Event() : detail::Wrapper<cl_type>() { }
2712
2713     /*! \brief Copy constructor.
2714      * 
2715      *  This calls clRetainEvent() on the parameter's cl_event.
2716      */
2717     Event(const Event& event) : detail::Wrapper<cl_type>(event) { }
2718
2719     /*! \brief Constructor from cl_event - takes ownership.
2720      * 
2721      *  This effectively transfers ownership of a refcount on the cl_event
2722      *  into the new Event object.
2723      */
2724     Event(const cl_event& event) : detail::Wrapper<cl_type>(event) { }
2725
2726     /*! \brief Assignment operator from cl_event - takes ownership.
2727      *
2728      *  This effectively transfers ownership of a refcount on the rhs and calls
2729      *  clReleaseEvent() on the value previously held by this instance.
2730      */
2731     Event& operator = (const Event& rhs)
2732     {
2733         if (this != &rhs) {
2734             detail::Wrapper<cl_type>::operator=(rhs);
2735         }
2736         return *this;
2737     }
2738
2739     /*! \brief Assignment operator from cl_event.
2740      * 
2741      *  This calls clRetainEvent() on the parameter and clReleaseEvent() on
2742      *  the previous value held by this instance.
2743      */
2744     Event& operator = (const cl_event& rhs)
2745     {
2746         detail::Wrapper<cl_type>::operator=(rhs);
2747         return *this;
2748     }
2749
2750     //! \brief Wrapper for clGetEventInfo().
2751     template <typename T>
2752     cl_int getInfo(cl_event_info name, T* param) const
2753     {
2754         return detail::errHandler(
2755             detail::getInfo(&::clGetEventInfo, object_, name, param),
2756             __GET_EVENT_INFO_ERR);
2757     }
2758
2759     //! \brief Wrapper for clGetEventInfo() that returns by value.
2760     template <cl_int name> typename
2761     detail::param_traits<detail::cl_event_info, name>::param_type
2762     getInfo(cl_int* err = NULL) const
2763     {
2764         typename detail::param_traits<
2765             detail::cl_event_info, name>::param_type param;
2766         cl_int result = getInfo(name, &param);
2767         if (err != NULL) {
2768             *err = result;
2769         }
2770         return param;
2771     }
2772
2773     //! \brief Wrapper for clGetEventProfilingInfo().
2774     template <typename T>
2775     cl_int getProfilingInfo(cl_profiling_info name, T* param) const
2776     {
2777         return detail::errHandler(detail::getInfo(
2778             &::clGetEventProfilingInfo, object_, name, param),
2779             __GET_EVENT_PROFILE_INFO_ERR);
2780     }
2781
2782     //! \brief Wrapper for clGetEventProfilingInfo() that returns by value.
2783     template <cl_int name> typename
2784     detail::param_traits<detail::cl_profiling_info, name>::param_type
2785     getProfilingInfo(cl_int* err = NULL) const
2786     {
2787         typename detail::param_traits<
2788             detail::cl_profiling_info, name>::param_type param;
2789         cl_int result = getProfilingInfo(name, &param);
2790         if (err != NULL) {
2791             *err = result;
2792         }
2793         return param;
2794     }
2795
2796     /*! \brief Blocks the calling thread until this event completes.
2797      * 
2798      *  Wraps clWaitForEvents().
2799      */
2800     cl_int wait() const
2801     {
2802         return detail::errHandler(
2803             ::clWaitForEvents(1, &object_),
2804             __WAIT_FOR_EVENTS_ERR);
2805     }
2806
2807 #if defined(CL_VERSION_1_1)
2808     /*! \brief Registers a user callback function for a specific command execution status.
2809      *
2810      *  Wraps clSetEventCallback().
2811      */
2812     cl_int setCallback(
2813         cl_int type,
2814         void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),              
2815         void * user_data = NULL)
2816     {
2817         return detail::errHandler(
2818             ::clSetEventCallback(
2819                 object_,
2820                 type,
2821                 pfn_notify,
2822                 user_data), 
2823             __SET_EVENT_CALLBACK_ERR);
2824     }
2825 #endif
2826
2827     /*! \brief Blocks the calling thread until every event specified is complete.
2828      * 
2829      *  Wraps clWaitForEvents().
2830      */
2831     static cl_int
2832     waitForEvents(const VECTOR_CLASS<Event>& events)
2833     {
2834         return detail::errHandler(
2835             ::clWaitForEvents(
2836                 (cl_uint) events.size(), (cl_event*)&events.front()),
2837             __WAIT_FOR_EVENTS_ERR);
2838     }
2839 };
2840
2841 #if defined(CL_VERSION_1_1)
2842 /*! \brief Class interface for user events (a subset of cl_event's).
2843  * 
2844  *  See Event for details about copy semantics, etc.
2845  */
2846 class UserEvent : public Event
2847 {
2848 public:
2849     /*! \brief Constructs a user event on a given context.
2850      *
2851      *  Wraps clCreateUserEvent().
2852      */
2853     UserEvent(
2854         const Context& context,
2855         cl_int * err = NULL)
2856     {
2857         cl_int error;
2858         object_ = ::clCreateUserEvent(
2859             context(),
2860             &error);
2861
2862         detail::errHandler(error, __CREATE_USER_EVENT_ERR);
2863         if (err != NULL) {
2864             *err = error;
2865         }
2866     }
2867
2868     //! \brief Default constructor - initializes to NULL.
2869     UserEvent() : Event() { }
2870
2871     //! \brief Copy constructor - performs shallow copy.
2872     UserEvent(const UserEvent& event) : Event(event) { }
2873
2874     //! \brief Assignment Operator - performs shallow copy.
2875     UserEvent& operator = (const UserEvent& rhs)
2876     {
2877         if (this != &rhs) {
2878             Event::operator=(rhs);
2879         }
2880         return *this;
2881     }
2882
2883     /*! \brief Sets the execution status of a user event object.
2884      *
2885      *  Wraps clSetUserEventStatus().
2886      */
2887     cl_int setStatus(cl_int status)
2888     {
2889         return detail::errHandler(
2890             ::clSetUserEventStatus(object_,status), 
2891             __SET_USER_EVENT_STATUS_ERR);
2892     }
2893 };
2894 #endif
2895
2896 /*! \brief Blocks the calling thread until every event specified is complete.
2897  * 
2898  *  Wraps clWaitForEvents().
2899  */
2900 inline static cl_int
2901 WaitForEvents(const VECTOR_CLASS<Event>& events)
2902 {
2903     return detail::errHandler(
2904         ::clWaitForEvents(
2905             (cl_uint) events.size(), (cl_event*)&events.front()),
2906         __WAIT_FOR_EVENTS_ERR);
2907 }
2908
2909 /*! \brief Class interface for cl_mem.
2910  *
2911  *  \note Copies of these objects are shallow, meaning that the copy will refer
2912  *        to the same underlying cl_mem as the original.  For details, see
2913  *        clRetainMemObject() and clReleaseMemObject().
2914  *
2915  *  \see cl_mem
2916  */
2917 class Memory : public detail::Wrapper<cl_mem>
2918 {
2919 public:
2920  
2921     /*! \brief Destructor.
2922      *
2923      *  This calls clReleaseMemObject() on the value held by this instance.
2924      */
2925     ~Memory() {}
2926
2927     //! \brief Default constructor - initializes to NULL.
2928     Memory() : detail::Wrapper<cl_type>() { }
2929
2930     /*! \brief Copy constructor - performs shallow copy.
2931      * 
2932      *  This calls clRetainMemObject() on the parameter's cl_mem.
2933      */
2934     Memory(const Memory& memory) : detail::Wrapper<cl_type>(memory) { }
2935
2936     /*! \brief Constructor from cl_mem - takes ownership.
2937      * 
2938      *  This effectively transfers ownership of a refcount on the cl_mem
2939      *  into the new Memory object.
2940      */
2941     __CL_EXPLICIT_CONSTRUCTORS Memory(const cl_mem& memory) : detail::Wrapper<cl_type>(memory) { }
2942
2943     /*! \brief Assignment operator from Memory.
2944      * 
2945      *  This calls clRetainMemObject() on the parameter and clReleaseMemObject()
2946      *  on the previous value held by this instance.
2947      */
2948     Memory& operator = (const Memory& rhs)
2949     {
2950         if (this != &rhs) {
2951             detail::Wrapper<cl_type>::operator=(rhs);
2952         }
2953         return *this;
2954     }
2955
2956     /*! \brief Assignment operator from cl_mem - takes ownership.
2957      *
2958      *  This effectively transfers ownership of a refcount on the rhs and calls
2959      *  clReleaseMemObject() on the value previously held by this instance.
2960      */
2961     Memory& operator = (const cl_mem& rhs)
2962     {
2963         detail::Wrapper<cl_type>::operator=(rhs);
2964         return *this;
2965     }
2966
2967     //! \brief Wrapper for clGetMemObjectInfo().
2968     template <typename T>
2969     cl_int getInfo(cl_mem_info name, T* param) const
2970     {
2971         return detail::errHandler(
2972             detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
2973             __GET_MEM_OBJECT_INFO_ERR);
2974     }
2975
2976     //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
2977     template <cl_int name> typename
2978     detail::param_traits<detail::cl_mem_info, name>::param_type
2979     getInfo(cl_int* err = NULL) const
2980     {
2981         typename detail::param_traits<
2982             detail::cl_mem_info, name>::param_type param;
2983         cl_int result = getInfo(name, &param);
2984         if (err != NULL) {
2985             *err = result;
2986         }
2987         return param;
2988     }
2989
2990 #if defined(CL_VERSION_1_1)
2991     /*! \brief Registers a callback function to be called when the memory object
2992      *         is no longer needed.
2993      *
2994      *  Wraps clSetMemObjectDestructorCallback().
2995      *
2996      *  Repeated calls to this function, for a given cl_mem value, will append
2997      *  to the list of functions called (in reverse order) when memory object's
2998      *  resources are freed and the memory object is deleted.
2999      *
3000      *  \note
3001      *  The registered callbacks are associated with the underlying cl_mem
3002      *  value - not the Memory class instance.
3003      */
3004     cl_int setDestructorCallback(
3005         void (CL_CALLBACK * pfn_notify)(cl_mem, void *),                
3006         void * user_data = NULL)
3007     {
3008         return detail::errHandler(
3009             ::clSetMemObjectDestructorCallback(
3010                 object_,
3011                 pfn_notify,
3012                 user_data), 
3013             __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
3014     }
3015 #endif
3016
3017 };
3018
3019 // Pre-declare copy functions
3020 class Buffer;
3021 template< typename IteratorType >
3022 cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3023 template< typename IteratorType >
3024 cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3025 template< typename IteratorType >
3026 cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3027 template< typename IteratorType >
3028 cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3029
3030
3031 /*! \brief Class interface for Buffer Memory Objects.
3032  * 
3033  *  See Memory for details about copy semantics, etc.
3034  *
3035  *  \see Memory
3036  */
3037 class Buffer : public Memory
3038 {
3039 public:
3040
3041     /*! \brief Constructs a Buffer in a specified context.
3042      *
3043      *  Wraps clCreateBuffer().
3044      *
3045      *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
3046      *                  specified.  Note alignment & exclusivity requirements.
3047      */
3048     Buffer(
3049         const Context& context,
3050         cl_mem_flags flags,
3051         ::size_t size,
3052         void* host_ptr = NULL,
3053         cl_int* err = NULL)
3054     {
3055         cl_int error;
3056         object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
3057
3058         detail::errHandler(error, __CREATE_BUFFER_ERR);
3059         if (err != NULL) {
3060             *err = error;
3061         }
3062     }
3063
3064     /*! \brief Constructs a Buffer in the default context.
3065      *
3066      *  Wraps clCreateBuffer().
3067      *
3068      *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
3069      *                  specified.  Note alignment & exclusivity requirements.
3070      *
3071      *  \see Context::getDefault()
3072      */
3073     Buffer(
3074          cl_mem_flags flags,
3075         ::size_t size,
3076         void* host_ptr = NULL,
3077         cl_int* err = NULL)
3078     {
3079         cl_int error;
3080
3081         Context context = Context::getDefault(err);
3082
3083         object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
3084
3085         detail::errHandler(error, __CREATE_BUFFER_ERR);
3086         if (err != NULL) {
3087             *err = error;
3088         }
3089     }
3090
3091     /*!
3092      * \brief Construct a Buffer from a host container via iterators.
3093      * IteratorType must be random access.
3094      * If useHostPtr is specified iterators must represent contiguous data.
3095      */
3096     template< typename IteratorType >
3097     Buffer(
3098         IteratorType startIterator,
3099         IteratorType endIterator,
3100         bool readOnly,
3101         bool useHostPtr = false,
3102         cl_int* err = NULL)
3103     {
3104         typedef typename std::iterator_traits<IteratorType>::value_type DataType;
3105         cl_int error;
3106
3107         cl_mem_flags flags = 0;
3108         if( readOnly ) {
3109             flags |= CL_MEM_READ_ONLY;
3110         }
3111         else {
3112             flags |= CL_MEM_READ_WRITE;
3113         }
3114         if( useHostPtr ) {
3115             flags |= CL_MEM_USE_HOST_PTR;
3116         }
3117         
3118         ::size_t size = sizeof(DataType)*(endIterator - startIterator);
3119
3120         Context context = Context::getDefault(err);
3121
3122         if( useHostPtr ) {
3123             object_ = ::clCreateBuffer(context(), flags, size, static_cast<DataType*>(&*startIterator), &error);
3124         } else {
3125             object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
3126         }
3127
3128         detail::errHandler(error, __CREATE_BUFFER_ERR);
3129         if (err != NULL) {
3130             *err = error;
3131         }
3132
3133         if( !useHostPtr ) {
3134             error = cl::copy(startIterator, endIterator, *this);
3135             detail::errHandler(error, __CREATE_BUFFER_ERR);
3136             if (err != NULL) {
3137                 *err = error;
3138             }
3139         }
3140     }
3141
3142     /*!
3143      * \brief Construct a Buffer from a host container via iterators using a specified context.
3144      * IteratorType must be random access.
3145      * If useHostPtr is specified iterators must represent contiguous data.
3146      */
3147     template< typename IteratorType >
3148     Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator,
3149         bool readOnly, bool useHostPtr = false, cl_int* err = NULL);
3150
3151     //! \brief Default constructor - initializes to NULL.
3152     Buffer() : Memory() { }
3153
3154     /*! \brief Copy constructor - performs shallow copy.
3155      *
3156      *  See Memory for further details.
3157      */
3158     Buffer(const Buffer& buffer) : Memory(buffer) { }
3159
3160     /*! \brief Constructor from cl_mem - takes ownership.
3161      *
3162      *  See Memory for further details.
3163      */
3164     __CL_EXPLICIT_CONSTRUCTORS Buffer(const cl_mem& buffer) : Memory(buffer) { }
3165
3166     /*! \brief Assignment from Buffer - performs shallow copy.
3167      *
3168      *  See Memory for further details.
3169      */
3170     Buffer& operator = (const Buffer& rhs)
3171     {
3172         if (this != &rhs) {
3173             Memory::operator=(rhs);
3174         }
3175         return *this;
3176     }
3177
3178     /*! \brief Assignment from cl_mem - performs shallow copy.
3179      *
3180      *  See Memory for further details.
3181      */
3182     Buffer& operator = (const cl_mem& rhs)
3183     {
3184         Memory::operator=(rhs);
3185         return *this;
3186     }
3187
3188 #if defined(CL_VERSION_1_1)
3189     /*! \brief Creates a new buffer object from this.
3190      *
3191      *  Wraps clCreateSubBuffer().
3192      */
3193     Buffer createSubBuffer(
3194         cl_mem_flags flags,
3195         cl_buffer_create_type buffer_create_type,
3196         const void * buffer_create_info,
3197         cl_int * err = NULL)
3198     {
3199         Buffer result;
3200         cl_int error;
3201         result.object_ = ::clCreateSubBuffer(
3202             object_, 
3203             flags, 
3204             buffer_create_type, 
3205             buffer_create_info, 
3206             &error);
3207
3208         detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
3209         if (err != NULL) {
3210             *err = error;
3211         }
3212
3213         return result;
3214     }           
3215 #endif
3216 };
3217
3218 #if defined (USE_DX_INTEROP)
3219 /*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's.
3220  *
3221  *  This is provided to facilitate interoperability with Direct3D.
3222  * 
3223  *  See Memory for details about copy semantics, etc.
3224  *
3225  *  \see Memory
3226  */
3227 class BufferD3D10 : public Buffer
3228 {
3229 public:
3230     typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
3231     cl_context context, cl_mem_flags flags, ID3D10Buffer*  buffer,
3232     cl_int* errcode_ret);
3233
3234     /*! \brief Constructs a BufferD3D10, in a specified context, from a
3235      *         given ID3D10Buffer.
3236      *
3237      *  Wraps clCreateFromD3D10BufferKHR().
3238      */
3239     BufferD3D10(
3240         const Context& context,
3241         cl_mem_flags flags,
3242         ID3D10Buffer* bufobj,
3243         cl_int * err = NULL)
3244     {
3245         static PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR = NULL;
3246
3247 #if defined(CL_VERSION_1_2)
3248         vector<cl_context_properties> props = context.getInfo<CL_CONTEXT_PROPERTIES>();
3249         cl_platform platform = -1;
3250         for( int i = 0; i < props.size(); ++i ) {
3251             if( props[i] == CL_CONTEXT_PLATFORM ) {
3252                 platform = props[i+1];
3253             }
3254         }
3255         __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clCreateFromD3D10BufferKHR);
3256 #endif
3257 #if defined(CL_VERSION_1_1)
3258         __INIT_CL_EXT_FCN_PTR(clCreateFromD3D10BufferKHR);
3259 #endif
3260
3261         cl_int error;
3262         object_ = pfn_clCreateFromD3D10BufferKHR(
3263             context(),
3264             flags,
3265             bufobj,
3266             &error);
3267
3268         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
3269         if (err != NULL) {
3270             *err = error;
3271         }
3272     }
3273
3274     //! \brief Default constructor - initializes to NULL.
3275     BufferD3D10() : Buffer() { }
3276
3277     /*! \brief Copy constructor - performs shallow copy.
3278      *
3279      *  See Memory for further details.
3280      */
3281     BufferD3D10(const BufferD3D10& buffer) : Buffer(buffer) { }
3282
3283     /*! \brief Constructor from cl_mem - takes ownership.
3284      *
3285      *  See Memory for further details.
3286      */
3287     __CL_EXPLICIT_CONSTRUCTORS BufferD3D10(const cl_mem& buffer) : Buffer(buffer) { }
3288
3289     /*! \brief Assignment from BufferD3D10 - performs shallow copy.
3290      *
3291      *  See Memory for further details.
3292      */
3293     BufferD3D10& operator = (const BufferD3D10& rhs)
3294     {
3295         if (this != &rhs) {
3296             Buffer::operator=(rhs);
3297         }
3298         return *this;
3299     }
3300
3301     /*! \brief Assignment from cl_mem - performs shallow copy.
3302      *
3303      *  See Memory for further details.
3304      */
3305     BufferD3D10& operator = (const cl_mem& rhs)
3306     {
3307         Buffer::operator=(rhs);
3308         return *this;
3309     }
3310 };
3311 #endif
3312
3313 /*! \brief Class interface for GL Buffer Memory Objects.
3314  *
3315  *  This is provided to facilitate interoperability with OpenGL.
3316  * 
3317  *  See Memory for details about copy semantics, etc.
3318  * 
3319  *  \see Memory
3320  */
3321 class BufferGL : public Buffer
3322 {
3323 public:
3324     /*! \brief Constructs a BufferGL in a specified context, from a given
3325      *         GL buffer.
3326      *
3327      *  Wraps clCreateFromGLBuffer().
3328      */
3329     BufferGL(
3330         const Context& context,
3331         cl_mem_flags flags,
3332         GLuint bufobj,
3333         cl_int * err = NULL)
3334     {
3335         cl_int error;
3336         object_ = ::clCreateFromGLBuffer(
3337             context(),
3338             flags,
3339             bufobj,
3340             &error);
3341
3342         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
3343         if (err != NULL) {
3344             *err = error;
3345         }
3346     }
3347
3348     //! \brief Default constructor - initializes to NULL.
3349     BufferGL() : Buffer() { }
3350
3351     /*! \brief Copy constructor - performs shallow copy.
3352      *
3353      *  See Memory for further details.
3354      */
3355     BufferGL(const BufferGL& buffer) : Buffer(buffer) { }
3356
3357     /*! \brief Constructor from cl_mem - takes ownership.
3358      *
3359      *  See Memory for further details.
3360      */
3361     __CL_EXPLICIT_CONSTRUCTORS BufferGL(const cl_mem& buffer) : Buffer(buffer) { }
3362
3363     /*! \brief Assignment from BufferGL - performs shallow copy.
3364      *
3365      *  See Memory for further details.
3366      */
3367     BufferGL& operator = (const BufferGL& rhs)
3368     {
3369         if (this != &rhs) {
3370             Buffer::operator=(rhs);
3371         }
3372         return *this;
3373     }
3374
3375     /*! \brief Assignment from cl_mem - performs shallow copy.
3376      *
3377      *  See Memory for further details.
3378      */
3379     BufferGL& operator = (const cl_mem& rhs)
3380     {
3381         Buffer::operator=(rhs);
3382         return *this;
3383     }
3384
3385     //! \brief Wrapper for clGetGLObjectInfo().
3386     cl_int getObjectInfo(
3387         cl_gl_object_type *type,
3388         GLuint * gl_object_name)
3389     {
3390         return detail::errHandler(
3391             ::clGetGLObjectInfo(object_,type,gl_object_name),
3392             __GET_GL_OBJECT_INFO_ERR);
3393     }
3394 };
3395
3396 /*! \brief Class interface for GL Render Buffer Memory Objects.
3397  *
3398  *  This is provided to facilitate interoperability with OpenGL.
3399  * 
3400  *  See Memory for details about copy semantics, etc.
3401  * 
3402  *  \see Memory
3403  */
3404 class BufferRenderGL : public Buffer
3405 {
3406 public:
3407     /*! \brief Constructs a BufferRenderGL in a specified context, from a given
3408      *         GL Renderbuffer.
3409      *
3410      *  Wraps clCreateFromGLRenderbuffer().
3411      */
3412     BufferRenderGL(
3413         const Context& context,
3414         cl_mem_flags flags,
3415         GLuint bufobj,
3416         cl_int * err = NULL)
3417     {
3418         cl_int error;
3419         object_ = ::clCreateFromGLRenderbuffer(
3420             context(),
3421             flags,
3422             bufobj,
3423             &error);
3424
3425         detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR);
3426         if (err != NULL) {
3427             *err = error;
3428         }
3429     }
3430
3431     //! \brief Default constructor - initializes to NULL.
3432     BufferRenderGL() : Buffer() { }
3433
3434     /*! \brief Copy constructor - performs shallow copy.
3435      *
3436      *  See Memory for further details.
3437      */
3438     BufferRenderGL(const BufferGL& buffer) : Buffer(buffer) { }
3439
3440     /*! \brief Constructor from cl_mem - takes ownership.
3441      *
3442      *  See Memory for further details.
3443      */
3444     __CL_EXPLICIT_CONSTRUCTORS BufferRenderGL(const cl_mem& buffer) : Buffer(buffer) { }
3445
3446     /*! \brief Assignment from BufferGL - performs shallow copy.
3447      *
3448      *  See Memory for further details.
3449      */
3450     BufferRenderGL& operator = (const BufferRenderGL& rhs)
3451     {
3452         if (this != &rhs) {
3453             Buffer::operator=(rhs);
3454         }
3455         return *this;
3456     }
3457
3458     /*! \brief Assignment from cl_mem - performs shallow copy.
3459      *
3460      *  See Memory for further details.
3461      */
3462     BufferRenderGL& operator = (const cl_mem& rhs)
3463     {
3464         Buffer::operator=(rhs);
3465         return *this;
3466     }
3467
3468     //! \brief Wrapper for clGetGLObjectInfo().
3469     cl_int getObjectInfo(
3470         cl_gl_object_type *type,
3471         GLuint * gl_object_name)
3472     {
3473         return detail::errHandler(
3474             ::clGetGLObjectInfo(object_,type,gl_object_name),
3475             __GET_GL_OBJECT_INFO_ERR);
3476     }
3477 };
3478
3479 /*! \brief C++ base class for Image Memory objects.
3480  *
3481  *  See Memory for details about copy semantics, etc.
3482  * 
3483  *  \see Memory
3484  */
3485 class Image : public Memory
3486 {
3487 protected:
3488     //! \brief Default constructor - initializes to NULL.
3489     Image() : Memory() { }
3490
3491     /*! \brief Copy constructor - performs shallow copy.
3492      *
3493      *  See Memory for further details.
3494      */
3495     Image(const Image& image) : Memory(image) { }
3496
3497     /*! \brief Constructor from cl_mem - takes ownership.
3498      *
3499      *  See Memory for further details.
3500      */
3501     __CL_EXPLICIT_CONSTRUCTORS Image(const cl_mem& image) : Memory(image) { }
3502
3503     /*! \brief Assignment from Image - performs shallow copy.
3504      *
3505      *  See Memory for further details.
3506      */
3507     Image& operator = (const Image& rhs)
3508     {
3509         if (this != &rhs) {
3510             Memory::operator=(rhs);
3511         }
3512         return *this;
3513     }
3514
3515     /*! \brief Assignment from cl_mem - performs shallow copy.
3516      *
3517      *  See Memory for further details.
3518      */
3519     Image& operator = (const cl_mem& rhs)
3520     {
3521         Memory::operator=(rhs);
3522         return *this;
3523     }
3524
3525 public:
3526     //! \brief Wrapper for clGetImageInfo().
3527     template <typename T>
3528     cl_int getImageInfo(cl_image_info name, T* param) const
3529     {
3530         return detail::errHandler(
3531             detail::getInfo(&::clGetImageInfo, object_, name, param),
3532             __GET_IMAGE_INFO_ERR);
3533     }
3534     
3535     //! \brief Wrapper for clGetImageInfo() that returns by value.
3536     template <cl_int name> typename
3537     detail::param_traits<detail::cl_image_info, name>::param_type
3538     getImageInfo(cl_int* err = NULL) const
3539     {
3540         typename detail::param_traits<
3541             detail::cl_image_info, name>::param_type param;
3542         cl_int result = getImageInfo(name, &param);
3543         if (err != NULL) {
3544             *err = result;
3545         }
3546         return param;
3547     }
3548 };
3549
3550 #if defined(CL_VERSION_1_2)
3551 /*! \brief Class interface for 1D Image Memory objects.
3552  *
3553  *  See Memory for details about copy semantics, etc.
3554  * 
3555  *  \see Memory
3556  */
3557 class Image1D : public Image
3558 {
3559 public:
3560     /*! \brief Constructs a 1D Image in a specified context.
3561      *
3562      *  Wraps clCreateImage().
3563      */
3564     Image1D(
3565         const Context& context,
3566         cl_mem_flags flags,
3567         ImageFormat format,
3568         ::size_t width,
3569         void* host_ptr = NULL,
3570         cl_int* err = NULL)
3571     {
3572         cl_int error;
3573         cl_image_desc desc =
3574         {
3575             CL_MEM_OBJECT_IMAGE1D,
3576             width,
3577             0, 0, 0, 0, 0, 0, 0, 0
3578         };
3579         object_ = ::clCreateImage(
3580             context(), 
3581             flags, 
3582             &format, 
3583             &desc, 
3584             host_ptr, 
3585             &error);
3586
3587         detail::errHandler(error, __CREATE_IMAGE_ERR);
3588         if (err != NULL) {
3589             *err = error;
3590         }
3591     }
3592
3593     //! \brief Default constructor - initializes to NULL.
3594     Image1D() { }
3595
3596     /*! \brief Copy constructor - performs shallow copy.
3597      *
3598      *  See Memory for further details.
3599      */
3600     Image1D(const Image1D& image1D) : Image(image1D) { }
3601
3602     /*! \brief Constructor from cl_mem - takes ownership.
3603      *
3604      *  See Memory for further details.
3605      */
3606     __CL_EXPLICIT_CONSTRUCTORS Image1D(const cl_mem& image1D) : Image(image1D) { }
3607
3608     /*! \brief Assignment from Image1D - performs shallow copy.
3609      *
3610      *  See Memory for further details.
3611      */
3612     Image1D& operator = (const Image1D& rhs)
3613     {
3614         if (this != &rhs) {
3615             Image::operator=(rhs);
3616         }
3617         return *this;
3618     }
3619
3620     /*! \brief Assignment from cl_mem - performs shallow copy.
3621      *
3622      *  See Memory for further details.
3623      */
3624     Image1D& operator = (const cl_mem& rhs)
3625     {
3626         Image::operator=(rhs);
3627         return *this;
3628     }
3629 };
3630
3631 /*! \class Image1DBuffer
3632  * \brief Image interface for 1D buffer images.
3633  */
3634 class Image1DBuffer : public Image
3635 {
3636 public:
3637     Image1DBuffer(
3638         const Context& context,
3639         cl_mem_flags flags,
3640         ImageFormat format,
3641         ::size_t width,
3642         const Buffer &buffer,
3643         cl_int* err = NULL)
3644     {
3645         cl_int error;
3646         cl_image_desc desc =
3647         {
3648             CL_MEM_OBJECT_IMAGE1D_BUFFER,
3649             width,
3650             0, 0, 0, 0, 0, 0, 0,
3651             buffer()
3652         };
3653         object_ = ::clCreateImage(
3654             context(), 
3655             flags, 
3656             &format, 
3657             &desc, 
3658             NULL, 
3659             &error);
3660
3661         detail::errHandler(error, __CREATE_IMAGE_ERR);
3662         if (err != NULL) {
3663             *err = error;
3664         }
3665     }
3666
3667     Image1DBuffer() { }
3668
3669     Image1DBuffer(const Image1DBuffer& image1D) : Image(image1D) { }
3670
3671     __CL_EXPLICIT_CONSTRUCTORS Image1DBuffer(const cl_mem& image1D) : Image(image1D) { }
3672
3673     Image1DBuffer& operator = (const Image1DBuffer& rhs)
3674     {
3675         if (this != &rhs) {
3676             Image::operator=(rhs);
3677         }
3678         return *this;
3679     }
3680
3681     Image1DBuffer& operator = (const cl_mem& rhs)
3682     {
3683         Image::operator=(rhs);
3684         return *this;
3685     }
3686 };
3687
3688 /*! \class Image1DArray
3689  * \brief Image interface for arrays of 1D images.
3690  */
3691 class Image1DArray : public Image
3692 {
3693 public:
3694     Image1DArray(
3695         const Context& context,
3696         cl_mem_flags flags,
3697         ImageFormat format,
3698         ::size_t arraySize,
3699         ::size_t width,
3700         ::size_t rowPitch,
3701         void* host_ptr = NULL,
3702         cl_int* err = NULL)
3703     {
3704         cl_int error;
3705         cl_image_desc desc =
3706         {
3707             CL_MEM_OBJECT_IMAGE1D_ARRAY,
3708             width,
3709             0, 0,  // height, depth (unused)
3710             arraySize,
3711             rowPitch,
3712             0, 0, 0, 0
3713         };
3714         object_ = ::clCreateImage(
3715             context(), 
3716             flags, 
3717             &format, 
3718             &desc, 
3719             host_ptr, 
3720             &error);
3721
3722         detail::errHandler(error, __CREATE_IMAGE_ERR);
3723         if (err != NULL) {
3724             *err = error;
3725         }
3726     }
3727
3728     Image1DArray() { }
3729
3730     Image1DArray(const Image1DArray& imageArray) : Image(imageArray) { }
3731
3732     __CL_EXPLICIT_CONSTRUCTORS Image1DArray(const cl_mem& imageArray) : Image(imageArray) { }
3733
3734     Image1DArray& operator = (const Image1DArray& rhs)
3735     {
3736         if (this != &rhs) {
3737             Image::operator=(rhs);
3738         }
3739         return *this;
3740     }
3741
3742     Image1DArray& operator = (const cl_mem& rhs)
3743     {
3744         Image::operator=(rhs);
3745         return *this;
3746     }
3747 };
3748 #endif // #if defined(CL_VERSION_1_2)
3749
3750
3751 /*! \brief Class interface for 2D Image Memory objects.
3752  *
3753  *  See Memory for details about copy semantics, etc.
3754  * 
3755  *  \see Memory
3756  */
3757 class Image2D : public Image
3758 {
3759 public:
3760     /*! \brief Constructs a 1D Image in a specified context.
3761      *
3762      *  Wraps clCreateImage().
3763      */
3764     Image2D(
3765         const Context& context,
3766         cl_mem_flags flags,
3767         ImageFormat format,
3768         ::size_t width,
3769         ::size_t height,
3770         ::size_t row_pitch = 0,
3771         void* host_ptr = NULL,
3772         cl_int* err = NULL)
3773     {
3774         cl_int error;
3775         bool useCreateImage;
3776
3777 #if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3778         // Run-time decision based on the actual platform
3779         {
3780             cl_uint version = detail::getContextPlatformVersion(context());
3781             useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
3782         }
3783 #elif defined(CL_VERSION_1_2)
3784         useCreateImage = true;
3785 #else
3786         useCreateImage = false;
3787 #endif
3788
3789 #if defined(CL_VERSION_1_2)
3790         if (useCreateImage)
3791         {
3792             cl_image_desc desc =
3793             {
3794                 CL_MEM_OBJECT_IMAGE2D,
3795                 width,
3796                 height,
3797                 0, 0, // depth, array size (unused)
3798                 row_pitch,
3799                 0, 0, 0, 0
3800             };
3801             object_ = ::clCreateImage(
3802                 context(),
3803                 flags,
3804                 &format,
3805                 &desc,
3806                 host_ptr,
3807                 &error);
3808
3809             detail::errHandler(error, __CREATE_IMAGE_ERR);
3810             if (err != NULL) {
3811                 *err = error;
3812             }
3813         }
3814 #endif // #if defined(CL_VERSION_1_2)
3815 #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3816         if (!useCreateImage)
3817         {
3818             object_ = ::clCreateImage2D(
3819                 context(), flags,&format, width, height, row_pitch, host_ptr, &error);
3820
3821             detail::errHandler(error, __CREATE_IMAGE2D_ERR);
3822             if (err != NULL) {
3823                 *err = error;
3824             }
3825         }
3826 #endif // #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3827     }
3828
3829     //! \brief Default constructor - initializes to NULL.
3830     Image2D() { }
3831
3832     /*! \brief Copy constructor - performs shallow copy.
3833      *
3834      *  See Memory for further details.
3835      */
3836     Image2D(const Image2D& image2D) : Image(image2D) { }
3837
3838     /*! \brief Constructor from cl_mem - takes ownership.
3839      *
3840      *  See Memory for further details.
3841      */
3842     __CL_EXPLICIT_CONSTRUCTORS Image2D(const cl_mem& image2D) : Image(image2D) { }
3843
3844     /*! \brief Assignment from Image2D - performs shallow copy.
3845      *
3846      *  See Memory for further details.
3847      */
3848     Image2D& operator = (const Image2D& rhs)
3849     {
3850         if (this != &rhs) {
3851             Image::operator=(rhs);
3852         }
3853         return *this;
3854     }
3855
3856     /*! \brief Assignment from cl_mem - performs shallow copy.
3857      *
3858      *  See Memory for further details.
3859      */
3860     Image2D& operator = (const cl_mem& rhs)
3861     {
3862         Image::operator=(rhs);
3863         return *this;
3864     }
3865 };
3866
3867
3868 #if !defined(CL_VERSION_1_2)
3869 /*! \brief Class interface for GL 2D Image Memory objects.
3870  *
3871  *  This is provided to facilitate interoperability with OpenGL.
3872  * 
3873  *  See Memory for details about copy semantics, etc.
3874  * 
3875  *  \see Memory
3876  *  \note Deprecated for OpenCL 1.2. Please use ImageGL instead.
3877  */
3878 class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED Image2DGL CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED : public Image2D
3879 {
3880 public:
3881     /*! \brief Constructs an Image2DGL in a specified context, from a given
3882      *         GL Texture.
3883      *
3884      *  Wraps clCreateFromGLTexture2D().
3885      */
3886     Image2DGL(
3887         const Context& context,
3888         cl_mem_flags flags,
3889         GLenum target,
3890         GLint  miplevel,
3891         GLuint texobj,
3892         cl_int * err = NULL)
3893     {
3894         cl_int error;
3895         object_ = ::clCreateFromGLTexture2D(
3896             context(),
3897             flags,
3898             target,
3899             miplevel,
3900             texobj,
3901             &error);
3902
3903         detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR);
3904         if (err != NULL) {
3905             *err = error;
3906         }
3907
3908     }
3909     
3910     //! \brief Default constructor - initializes to NULL.
3911     Image2DGL() : Image2D() { }
3912
3913     /*! \brief Copy constructor - performs shallow copy.
3914      *
3915      *  See Memory for further details.
3916      */
3917     Image2DGL(const Image2DGL& image) : Image2D(image) { }
3918
3919     /*! \brief Constructor from cl_mem - takes ownership.
3920      *
3921      *  See Memory for further details.
3922      */
3923     __CL_EXPLICIT_CONSTRUCTORS Image2DGL(const cl_mem& image) : Image2D(image) { }
3924
3925     /*! \brief Assignment from Image2DGL - performs shallow copy.
3926      *
3927      *  See Memory for further details.
3928      */
3929     Image2DGL& operator = (const Image2DGL& rhs)
3930     {
3931         if (this != &rhs) {
3932             Image2D::operator=(rhs);
3933         }
3934         return *this;
3935     }
3936
3937     /*! \brief Assignment from cl_mem - performs shallow copy.
3938      *
3939      *  See Memory for further details.
3940      */
3941     Image2DGL& operator = (const cl_mem& rhs)
3942     {
3943         Image2D::operator=(rhs);
3944         return *this;
3945     }
3946 };
3947 #endif // #if !defined(CL_VERSION_1_2)
3948
3949 #if defined(CL_VERSION_1_2)
3950 /*! \class Image2DArray
3951  * \brief Image interface for arrays of 2D images.
3952  */
3953 class Image2DArray : public Image
3954 {
3955 public:
3956     Image2DArray(
3957         const Context& context,
3958         cl_mem_flags flags,
3959         ImageFormat format,
3960         ::size_t arraySize,
3961         ::size_t width,
3962         ::size_t height,
3963         ::size_t rowPitch,
3964         ::size_t slicePitch,
3965         void* host_ptr = NULL,
3966         cl_int* err = NULL)
3967     {
3968         cl_int error;
3969         cl_image_desc desc =
3970         {
3971             CL_MEM_OBJECT_IMAGE2D_ARRAY,
3972             width,
3973             height,
3974             0,       // depth (unused)
3975             arraySize,
3976             rowPitch,
3977             slicePitch,
3978             0, 0, 0
3979         };
3980         object_ = ::clCreateImage(
3981             context(), 
3982             flags, 
3983             &format, 
3984             &desc, 
3985             host_ptr, 
3986             &error);
3987
3988         detail::errHandler(error, __CREATE_IMAGE_ERR);
3989         if (err != NULL) {
3990             *err = error;
3991         }
3992     }
3993
3994     Image2DArray() { }
3995
3996     Image2DArray(const Image2DArray& imageArray) : Image(imageArray) { }
3997
3998     __CL_EXPLICIT_CONSTRUCTORS Image2DArray(const cl_mem& imageArray) : Image(imageArray) { }
3999
4000     Image2DArray& operator = (const Image2DArray& rhs)
4001     {
4002         if (this != &rhs) {
4003             Image::operator=(rhs);
4004         }
4005         return *this;
4006     }
4007
4008     Image2DArray& operator = (const cl_mem& rhs)
4009     {
4010         Image::operator=(rhs);
4011         return *this;
4012     }
4013 };
4014 #endif // #if defined(CL_VERSION_1_2)
4015
4016 /*! \brief Class interface for 3D Image Memory objects.
4017  *
4018  *  See Memory for details about copy semantics, etc.
4019  * 
4020  *  \see Memory
4021  */
4022 class Image3D : public Image
4023 {
4024 public:
4025     /*! \brief Constructs a 3D Image in a specified context.
4026      *
4027      *  Wraps clCreateImage().
4028      */
4029     Image3D(
4030         const Context& context,
4031         cl_mem_flags flags,
4032         ImageFormat format,
4033         ::size_t width,
4034         ::size_t height,
4035         ::size_t depth,
4036         ::size_t row_pitch = 0,
4037         ::size_t slice_pitch = 0,
4038         void* host_ptr = NULL,
4039         cl_int* err = NULL)
4040     {
4041         cl_int error;
4042         bool useCreateImage;
4043
4044 #if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
4045         // Run-time decision based on the actual platform
4046         {
4047             cl_uint version = detail::getContextPlatformVersion(context());
4048             useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
4049         }
4050 #elif defined(CL_VERSION_1_2)
4051         useCreateImage = true;
4052 #else
4053         useCreateImage = false;
4054 #endif
4055
4056 #if defined(CL_VERSION_1_2)
4057         if (useCreateImage)
4058         {
4059             cl_image_desc desc =
4060             {
4061                 CL_MEM_OBJECT_IMAGE3D,
4062                 width,
4063                 height,
4064                 depth,
4065                 0,      // array size (unused)
4066                 row_pitch,
4067                 slice_pitch,
4068                 0, 0, 0
4069             };
4070             object_ = ::clCreateImage(
4071                 context(), 
4072                 flags, 
4073                 &format, 
4074                 &desc, 
4075                 host_ptr, 
4076                 &error);
4077
4078             detail::errHandler(error, __CREATE_IMAGE_ERR);
4079             if (err != NULL) {
4080                 *err = error;
4081             }
4082         }
4083 #endif  // #if defined(CL_VERSION_1_2)
4084 #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
4085         if (!useCreateImage)
4086         {
4087             object_ = ::clCreateImage3D(
4088                 context(), flags, &format, width, height, depth, row_pitch,
4089                 slice_pitch, host_ptr, &error);
4090
4091             detail::errHandler(error, __CREATE_IMAGE3D_ERR);
4092             if (err != NULL) {
4093                 *err = error;
4094             }
4095         }
4096 #endif // #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
4097     }
4098
4099     //! \brief Default constructor - initializes to NULL.
4100     Image3D() { }
4101
4102     /*! \brief Copy constructor - performs shallow copy.
4103      *
4104      *  See Memory for further details.
4105      */
4106     Image3D(const Image3D& image3D) : Image(image3D) { }
4107
4108     /*! \brief Constructor from cl_mem - takes ownership.
4109      *
4110      *  See Memory for further details.
4111      */
4112     __CL_EXPLICIT_CONSTRUCTORS Image3D(const cl_mem& image3D) : Image(image3D) { }
4113
4114     /*! \brief Assignment from Image3D - performs shallow copy.
4115      *
4116      *  See Memory for further details.
4117      */
4118     Image3D& operator = (const Image3D& rhs)
4119     {
4120         if (this != &rhs) {
4121             Image::operator=(rhs);
4122         }
4123         return *this;
4124     }
4125
4126     /*! \brief Assignment from cl_mem - performs shallow copy.
4127      *
4128      *  See Memory for further details.
4129      */
4130     Image3D& operator = (const cl_mem& rhs)
4131     {
4132         Image::operator=(rhs);
4133         return *this;
4134     }
4135 };
4136
4137 #if !defined(CL_VERSION_1_2)
4138 /*! \brief Class interface for GL 3D Image Memory objects.
4139  *
4140  *  This is provided to facilitate interoperability with OpenGL.
4141  * 
4142  *  See Memory for details about copy semantics, etc.
4143  * 
4144  *  \see Memory
4145  */
4146 class Image3DGL : public Image3D
4147 {
4148 public:
4149     /*! \brief Constructs an Image3DGL in a specified context, from a given
4150      *         GL Texture.
4151      *
4152      *  Wraps clCreateFromGLTexture3D().
4153      */
4154     Image3DGL(
4155         const Context& context,
4156         cl_mem_flags flags,
4157         GLenum target,
4158         GLint  miplevel,
4159         GLuint texobj,
4160         cl_int * err = NULL)
4161     {
4162         cl_int error;
4163         object_ = ::clCreateFromGLTexture3D(
4164             context(),
4165             flags,
4166             target,
4167             miplevel,
4168             texobj,
4169             &error);
4170
4171         detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR);
4172         if (err != NULL) {
4173             *err = error;
4174         }
4175     }
4176
4177     //! \brief Default constructor - initializes to NULL.
4178     Image3DGL() : Image3D() { }
4179
4180     /*! \brief Copy constructor - performs shallow copy.
4181      *
4182      *  See Memory for further details.
4183      */
4184     Image3DGL(const Image3DGL& image) : Image3D(image) { }
4185
4186     /*! \brief Constructor from cl_mem - takes ownership.
4187      *
4188      *  See Memory for further details.
4189      */
4190     __CL_EXPLICIT_CONSTRUCTORS Image3DGL(const cl_mem& image) : Image3D(image) { }
4191
4192     /*! \brief Assignment from Image3DGL - performs shallow copy.
4193      *
4194      *  See Memory for further details.
4195      */
4196     Image3DGL& operator = (const Image3DGL& rhs)
4197     {
4198         if (this != &rhs) {
4199             Image3D::operator=(rhs);
4200         }
4201         return *this;
4202     }
4203
4204     /*! \brief Assignment from cl_mem - performs shallow copy.
4205      *
4206      *  See Memory for further details.
4207      */
4208     Image3DGL& operator = (const cl_mem& rhs)
4209     {
4210         Image3D::operator=(rhs);
4211         return *this;
4212     }
4213 };
4214 #endif // #if !defined(CL_VERSION_1_2)
4215
4216 #if defined(CL_VERSION_1_2)
4217 /*! \class ImageGL
4218  * \brief general image interface for GL interop.
4219  * We abstract the 2D and 3D GL images into a single instance here
4220  * that wraps all GL sourced images on the grounds that setup information
4221  * was performed by OpenCL anyway.
4222  */
4223 class ImageGL : public Image
4224 {
4225 public:
4226     ImageGL(
4227         const Context& context,
4228         cl_mem_flags flags,
4229         GLenum target,
4230         GLint  miplevel,
4231         GLuint texobj,
4232         cl_int * err = NULL)
4233     {
4234         cl_int error;
4235         object_ = ::clCreateFromGLTexture(
4236             context(), 
4237             flags, 
4238             target,
4239             miplevel,
4240             texobj,
4241             &error);
4242
4243         detail::errHandler(error, __CREATE_GL_TEXTURE_ERR);
4244         if (err != NULL) {
4245             *err = error;
4246         }
4247     }
4248
4249     ImageGL() : Image() { }
4250
4251     ImageGL(const ImageGL& image) : Image(image) { }
4252
4253     __CL_EXPLICIT_CONSTRUCTORS ImageGL(const cl_mem& image) : Image(image) { }
4254
4255     ImageGL& operator = (const ImageGL& rhs)
4256     {
4257         if (this != &rhs) {
4258             Image::operator=(rhs);
4259         }
4260         return *this;
4261     }
4262
4263     ImageGL& operator = (const cl_mem& rhs)
4264     {
4265         Image::operator=(rhs);
4266         return *this;
4267     }
4268 };
4269 #endif // #if defined(CL_VERSION_1_2)
4270
4271 /*! \brief Class interface for cl_sampler.
4272  *
4273  *  \note Copies of these objects are shallow, meaning that the copy will refer
4274  *        to the same underlying cl_sampler as the original.  For details, see
4275  *        clRetainSampler() and clReleaseSampler().
4276  *
4277  *  \see cl_sampler 
4278  */
4279 class Sampler : public detail::Wrapper<cl_sampler>
4280 {
4281 public:
4282     /*! \brief Destructor.
4283      *
4284      *  This calls clReleaseSampler() on the value held by this instance.
4285      */
4286     ~Sampler() { }
4287
4288     //! \brief Default constructor - initializes to NULL.
4289     Sampler() { }
4290
4291     /*! \brief Constructs a Sampler in a specified context.
4292      *
4293      *  Wraps clCreateSampler().
4294      */
4295     Sampler(
4296         const Context& context,
4297         cl_bool normalized_coords,
4298         cl_addressing_mode addressing_mode,
4299         cl_filter_mode filter_mode,
4300         cl_int* err = NULL)
4301     {
4302         cl_int error;
4303         object_ = ::clCreateSampler(
4304             context(), 
4305             normalized_coords,
4306             addressing_mode,
4307             filter_mode,
4308             &error);
4309
4310         detail::errHandler(error, __CREATE_SAMPLER_ERR);
4311         if (err != NULL) {
4312             *err = error;
4313         }
4314     }
4315
4316     /*! \brief Copy constructor - performs shallow copy.
4317      * 
4318      *  This calls clRetainSampler() on the parameter's cl_sampler.
4319      */
4320     Sampler(const Sampler& sampler) : detail::Wrapper<cl_type>(sampler) { }
4321
4322     /*! \brief Constructor from cl_sampler - takes ownership.
4323      * 
4324      *  This effectively transfers ownership of a refcount on the cl_sampler
4325      *  into the new Sampler object.
4326      */
4327     Sampler(const cl_sampler& sampler) : detail::Wrapper<cl_type>(sampler) { }
4328
4329     /*! \brief Assignment operator from Sampler.
4330      * 
4331      *  This calls clRetainSampler() on the parameter and clReleaseSampler()
4332      *  on the previous value held by this instance.
4333      */
4334     Sampler& operator = (const Sampler& rhs)
4335     {
4336         if (this != &rhs) {
4337             detail::Wrapper<cl_type>::operator=(rhs);
4338         }
4339         return *this;
4340     }
4341
4342     /*! \brief Assignment operator from cl_sampler - takes ownership.
4343      *
4344      *  This effectively transfers ownership of a refcount on the rhs and calls
4345      *  clReleaseSampler() on the value previously held by this instance.
4346      */
4347     Sampler& operator = (const cl_sampler& rhs)
4348     {
4349         detail::Wrapper<cl_type>::operator=(rhs);
4350         return *this;
4351     }
4352
4353     //! \brief Wrapper for clGetSamplerInfo().
4354     template <typename T>
4355     cl_int getInfo(cl_sampler_info name, T* param) const
4356     {
4357         return detail::errHandler(
4358             detail::getInfo(&::clGetSamplerInfo, object_, name, param),
4359             __GET_SAMPLER_INFO_ERR);
4360     }
4361
4362     //! \brief Wrapper for clGetSamplerInfo() that returns by value.
4363     template <cl_int name> typename
4364     detail::param_traits<detail::cl_sampler_info, name>::param_type
4365     getInfo(cl_int* err = NULL) const
4366     {
4367         typename detail::param_traits<
4368             detail::cl_sampler_info, name>::param_type param;
4369         cl_int result = getInfo(name, &param);
4370         if (err != NULL) {
4371             *err = result;
4372         }
4373         return param;
4374     }
4375 };
4376
4377 class Program;
4378 class CommandQueue;
4379 class Kernel;
4380
4381 //! \brief Class interface for specifying NDRange values.
4382 class NDRange
4383 {
4384 private:
4385     size_t<3> sizes_;
4386     cl_uint dimensions_;
4387
4388 public:
4389     //! \brief Default constructor - resulting range has zero dimensions.
4390     NDRange()
4391         : dimensions_(0)
4392     { }
4393
4394     //! \brief Constructs one-dimensional range.
4395     NDRange(::size_t size0)
4396         : dimensions_(1)
4397     {
4398         sizes_[0] = size0;
4399     }
4400
4401     //! \brief Constructs two-dimensional range.
4402     NDRange(::size_t size0, ::size_t size1)
4403         : dimensions_(2)
4404     {
4405         sizes_[0] = size0;
4406         sizes_[1] = size1;
4407     }
4408
4409     //! \brief Constructs three-dimensional range.
4410     NDRange(::size_t size0, ::size_t size1, ::size_t size2)
4411         : dimensions_(3)
4412     {
4413         sizes_[0] = size0;
4414         sizes_[1] = size1;
4415         sizes_[2] = size2;
4416     }
4417
4418     /*! \brief Conversion operator to const ::size_t *.
4419      *  
4420      *  \returns a pointer to the size of the first dimension.
4421      */
4422     operator const ::size_t*() const { 
4423         return (const ::size_t*) sizes_; 
4424     }
4425
4426     //! \brief Queries the number of dimensions in the range.
4427     ::size_t dimensions() const { return dimensions_; }
4428 };
4429
4430 //! \brief A zero-dimensional range.
4431 static const NDRange NullRange;
4432
4433 //! \brief Local address wrapper for use with Kernel::setArg
4434 struct LocalSpaceArg
4435 {
4436     ::size_t size_;
4437 };
4438
4439 namespace detail {
4440
4441 template <typename T>
4442 struct KernelArgumentHandler
4443 {
4444     static ::size_t size(const T&) { return sizeof(T); }
4445     static T* ptr(T& value) { return &value; }
4446 };
4447
4448 template <>
4449 struct KernelArgumentHandler<LocalSpaceArg>
4450 {
4451     static ::size_t size(const LocalSpaceArg& value) { return value.size_; }
4452     static void* ptr(LocalSpaceArg&) { return NULL; }
4453 };
4454
4455
4456 //! \endcond
4457
4458 /*! __local
4459  * \brief Helper function for generating LocalSpaceArg objects.
4460  * Deprecated. Replaced with Local.
4461  */
4462 inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED LocalSpaceArg
4463 __local(::size_t size) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
4464 inline LocalSpaceArg
4465 __local(::size_t size)
4466 {
4467     LocalSpaceArg ret = { size };
4468     return ret;
4469 }
4470
4471 /*! Local
4472  * \brief Helper function for generating LocalSpaceArg objects.
4473  */
4474 inline LocalSpaceArg
4475 Local(::size_t size)
4476 {
4477     LocalSpaceArg ret = { size };
4478     return ret;
4479 }
4480
4481 //class KernelFunctor;
4482
4483 /*! \brief Class interface for cl_kernel.
4484  *
4485  *  \note Copies of these objects are shallow, meaning that the copy will refer
4486  *        to the same underlying cl_kernel as the original.  For details, see
4487  *        clRetainKernel() and clReleaseKernel().
4488  *
4489  *  \see cl_kernel
4490  */
4491 class Kernel : public detail::Wrapper<cl_kernel>
4492 {
4493 public:
4494     inline Kernel(const Program& program, const char* name, cl_int* err = NULL);
4495
4496     /*! \brief Destructor.
4497      *
4498      *  This calls clReleaseKernel() on the value held by this instance.
4499      */
4500     ~Kernel() { }
4501
4502     //! \brief Default constructor - initializes to NULL.
4503     Kernel() { }
4504
4505     /*! \brief Copy constructor - performs shallow copy.
4506      * 
4507      *  This calls clRetainKernel() on the parameter's cl_kernel.
4508      */
4509     Kernel(const Kernel& kernel) : detail::Wrapper<cl_type>(kernel) { }
4510
4511     /*! \brief Constructor from cl_kernel - takes ownership.
4512      * 
4513      *  This effectively transfers ownership of a refcount on the cl_kernel
4514      *  into the new Kernel object.
4515      */
4516     __CL_EXPLICIT_CONSTRUCTORS Kernel(const cl_kernel& kernel) : detail::Wrapper<cl_type>(kernel) { }
4517
4518     /*! \brief Assignment operator from Kernel.
4519      * 
4520      *  This calls clRetainKernel() on the parameter and clReleaseKernel()
4521      *  on the previous value held by this instance.
4522      */
4523     Kernel& operator = (const Kernel& rhs)
4524     {
4525         if (this != &rhs) {
4526             detail::Wrapper<cl_type>::operator=(rhs);
4527         }
4528         return *this;
4529     }
4530
4531     /*! \brief Assignment operator from cl_kernel - takes ownership.
4532      *
4533      *  This effectively transfers ownership of a refcount on the rhs and calls
4534      *  clReleaseKernel() on the value previously held by this instance.
4535      */
4536     Kernel& operator = (const cl_kernel& rhs)
4537     {
4538         detail::Wrapper<cl_type>::operator=(rhs);
4539         return *this;
4540     }
4541
4542     template <typename T>
4543     cl_int getInfo(cl_kernel_info name, T* param) const
4544     {
4545         return detail::errHandler(
4546             detail::getInfo(&::clGetKernelInfo, object_, name, param),
4547             __GET_KERNEL_INFO_ERR);
4548     }
4549
4550     template <cl_int name> typename
4551     detail::param_traits<detail::cl_kernel_info, name>::param_type
4552     getInfo(cl_int* err = NULL) const
4553     {
4554         typename detail::param_traits<
4555             detail::cl_kernel_info, name>::param_type param;
4556         cl_int result = getInfo(name, &param);
4557         if (err != NULL) {
4558             *err = result;
4559         }
4560         return param;
4561     }
4562
4563 #if defined(CL_VERSION_1_2)
4564     template <typename T>
4565     cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const
4566     {
4567         return detail::errHandler(
4568             detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param),
4569             __GET_KERNEL_ARG_INFO_ERR);
4570     }
4571
4572     template <cl_int name> typename
4573     detail::param_traits<detail::cl_kernel_arg_info, name>::param_type
4574     getArgInfo(cl_uint argIndex, cl_int* err = NULL) const
4575     {
4576         typename detail::param_traits<
4577             detail::cl_kernel_arg_info, name>::param_type param;
4578         cl_int result = getArgInfo(argIndex, name, &param);
4579         if (err != NULL) {
4580             *err = result;
4581         }
4582         return param;
4583     }
4584 #endif // #if defined(CL_VERSION_1_2)
4585
4586     template <typename T>
4587     cl_int getWorkGroupInfo(
4588         const Device& device, cl_kernel_work_group_info name, T* param) const
4589     {
4590         return detail::errHandler(
4591             detail::getInfo(
4592                 &::clGetKernelWorkGroupInfo, object_, device(), name, param),
4593                 __GET_KERNEL_WORK_GROUP_INFO_ERR);
4594     }
4595
4596     template <cl_int name> typename
4597     detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type
4598         getWorkGroupInfo(const Device& device, cl_int* err = NULL) const
4599     {
4600         typename detail::param_traits<
4601         detail::cl_kernel_work_group_info, name>::param_type param;
4602         cl_int result = getWorkGroupInfo(device, name, &param);
4603         if (err != NULL) {
4604             *err = result;
4605         }
4606         return param;
4607     }
4608
4609     template <typename T>
4610     cl_int setArg(cl_uint index, T value)
4611     {
4612         return detail::errHandler(
4613             ::clSetKernelArg(
4614                 object_,
4615                 index,
4616                 detail::KernelArgumentHandler<T>::size(value),
4617                 detail::KernelArgumentHandler<T>::ptr(value)),
4618             __SET_KERNEL_ARGS_ERR);
4619     }
4620
4621     cl_int setArg(cl_uint index, ::size_t size, void* argPtr)
4622     {
4623         return detail::errHandler(
4624             ::clSetKernelArg(object_, index, size, argPtr),
4625             __SET_KERNEL_ARGS_ERR);
4626     }
4627 };
4628
4629 /*! \class Program
4630  * \brief Program interface that implements cl_program.
4631  */
4632 class Program : public detail::Wrapper<cl_program>
4633 {
4634 public:
4635     typedef VECTOR_CLASS<std::pair<const void*, ::size_t> > Binaries;
4636     typedef VECTOR_CLASS<std::pair<const char*, ::size_t> > Sources;
4637
4638     Program(
4639         const STRING_CLASS& source,
4640                 bool build = false,
4641         cl_int* err = NULL)
4642     {
4643         cl_int error;
4644
4645         const char * strings = source.c_str();
4646         const ::size_t length  = source.size();
4647
4648         Context context = Context::getDefault(err);
4649
4650         object_ = ::clCreateProgramWithSource(
4651             context(), (cl_uint)1, &strings, &length, &error);
4652
4653         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
4654
4655         if (error == CL_SUCCESS && build) {
4656
4657             error = ::clBuildProgram(
4658                 object_,
4659                 0,
4660                 NULL,
4661                 "",
4662                 NULL,
4663                 NULL);
4664
4665             detail::errHandler(error, __BUILD_PROGRAM_ERR);
4666         }
4667
4668         if (err != NULL) {
4669             *err = error;
4670         }
4671     }
4672
4673     Program(
4674         const Context& context,
4675         const STRING_CLASS& source,
4676         bool build = false,
4677         cl_int* err = NULL)
4678     {
4679         cl_int error;
4680
4681         const char * strings = source.c_str();
4682         const ::size_t length  = source.size();
4683
4684         object_ = ::clCreateProgramWithSource(
4685             context(), (cl_uint)1, &strings, &length, &error);
4686
4687         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
4688
4689         if (error == CL_SUCCESS && build) {
4690
4691             error = ::clBuildProgram(
4692                 object_,
4693                 0,
4694                 NULL,
4695                 "",
4696                 NULL,
4697                 NULL);
4698
4699             detail::errHandler(error, __BUILD_PROGRAM_ERR);
4700         }
4701
4702         if (err != NULL) {
4703             *err = error;
4704         }
4705     }
4706
4707     Program(
4708         const Context& context,
4709         const Sources& sources,
4710         cl_int* err = NULL)
4711     {
4712         cl_int error;
4713
4714         const ::size_t n = (::size_t)sources.size();
4715         ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t));
4716         const char** strings = (const char**) alloca(n * sizeof(const char*));
4717
4718         for (::size_t i = 0; i < n; ++i) {
4719             strings[i] = sources[(int)i].first;
4720             lengths[i] = sources[(int)i].second;
4721         }
4722
4723         object_ = ::clCreateProgramWithSource(
4724             context(), (cl_uint)n, strings, lengths, &error);
4725
4726         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
4727         if (err != NULL) {
4728             *err = error;
4729         }
4730     }
4731
4732     /**
4733      * Construct a program object from a list of devices and a per-device list of binaries.
4734      * \param context A valid OpenCL context in which to construct the program.
4735      * \param devices A vector of OpenCL device objects for which the program will be created.
4736      * \param binaries A vector of pairs of a pointer to a binary object and its length.
4737      * \param binaryStatus An optional vector that on completion will be resized to
4738      *   match the size of binaries and filled with values to specify if each binary
4739      *   was successfully loaded.
4740      *   Set to CL_SUCCESS if the binary was successfully loaded.
4741      *   Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is NULL.
4742      *   Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device.
4743      * \param err if non-NULL will be set to CL_SUCCESS on successful operation or one of the following errors:
4744      *   CL_INVALID_CONTEXT if context is not a valid context.
4745      *   CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices; 
4746      *     or if any entry in binaries is NULL or has length 0.
4747      *   CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context.
4748      *   CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device.
4749      *   CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host.
4750      */
4751     Program(
4752         const Context& context,
4753         const VECTOR_CLASS<Device>& devices,
4754         const Binaries& binaries,
4755         VECTOR_CLASS<cl_int>* binaryStatus = NULL,
4756         cl_int* err = NULL)
4757     {
4758         cl_int error;
4759         
4760         const ::size_t numDevices = devices.size();
4761         
4762         // Catch size mismatch early and return
4763         if(binaries.size() != numDevices) {
4764             error = CL_INVALID_VALUE;
4765             detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
4766             if (err != NULL) {
4767                 *err = error;
4768             }
4769             return;
4770         }
4771
4772         ::size_t* lengths = (::size_t*) alloca(numDevices * sizeof(::size_t));
4773         const unsigned char** images = (const unsigned char**) alloca(numDevices * sizeof(const unsigned char**));
4774
4775         for (::size_t i = 0; i < numDevices; ++i) {
4776             images[i] = (const unsigned char*)binaries[i].first;
4777             lengths[i] = binaries[(int)i].second;
4778         }
4779
4780         cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id));
4781         for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
4782             deviceIDs[deviceIndex] = (devices[deviceIndex])();
4783         }
4784
4785         if(binaryStatus) {
4786             binaryStatus->resize(numDevices);
4787         }
4788         
4789         object_ = ::clCreateProgramWithBinary(
4790             context(), (cl_uint) devices.size(),
4791             deviceIDs,
4792             lengths, images, binaryStatus != NULL
4793                ? &binaryStatus->front()
4794                : NULL, &error);
4795
4796         detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
4797         if (err != NULL) {
4798             *err = error;
4799         }
4800     }
4801
4802     
4803 #if defined(CL_VERSION_1_2)
4804     /**
4805      * Create program using builtin kernels.
4806      * \param kernelNames Semi-colon separated list of builtin kernel names
4807      */
4808     Program(
4809         const Context& context,
4810         const VECTOR_CLASS<Device>& devices,
4811         const STRING_CLASS& kernelNames,
4812         cl_int* err = NULL)
4813     {
4814         cl_int error;
4815
4816
4817         ::size_t numDevices = devices.size();
4818         cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id));
4819         for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
4820             deviceIDs[deviceIndex] = (devices[deviceIndex])();
4821         }
4822         
4823         object_ = ::clCreateProgramWithBuiltInKernels(
4824             context(), 
4825             (cl_uint) devices.size(),
4826             deviceIDs,
4827             kernelNames.c_str(), 
4828             &error);
4829
4830         detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR);
4831         if (err != NULL) {
4832             *err = error;
4833         }
4834     }
4835 #endif // #if defined(CL_VERSION_1_2)
4836
4837     Program() { }
4838
4839     Program(const Program& program) : detail::Wrapper<cl_type>(program) { }
4840
4841     __CL_EXPLICIT_CONSTRUCTORS Program(const cl_program& program) : detail::Wrapper<cl_type>(program) { }
4842
4843     Program& operator = (const Program& rhs)
4844     {
4845         if (this != &rhs) {
4846             detail::Wrapper<cl_type>::operator=(rhs);
4847         }
4848         return *this;
4849     }
4850
4851     Program& operator = (const cl_program& rhs)
4852     {
4853         detail::Wrapper<cl_type>::operator=(rhs);
4854         return *this;
4855     }
4856
4857     cl_int build(
4858         const VECTOR_CLASS<Device>& devices,
4859         const char* options = NULL,
4860         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
4861         void* data = NULL) const
4862     {
4863         ::size_t numDevices = devices.size();
4864         cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id));
4865         for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
4866             deviceIDs[deviceIndex] = (devices[deviceIndex])();
4867         }
4868
4869         return detail::errHandler(
4870             ::clBuildProgram(
4871                 object_,
4872                 (cl_uint)
4873                 devices.size(),
4874                 deviceIDs,
4875                 options,
4876                 notifyFptr,
4877                 data),
4878                 __BUILD_PROGRAM_ERR);
4879     }
4880
4881     cl_int build(
4882         const char* options = NULL,
4883         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
4884         void* data = NULL) const
4885     {
4886         return detail::errHandler(
4887             ::clBuildProgram(
4888                 object_,
4889                 0,
4890                 NULL,
4891                 options,
4892                 notifyFptr,
4893                 data),
4894                 __BUILD_PROGRAM_ERR);
4895     }
4896
4897 #if defined(CL_VERSION_1_2)
4898         cl_int compile(
4899         const char* options = NULL,
4900         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
4901         void* data = NULL) const
4902     {
4903         return detail::errHandler(
4904             ::clCompileProgram(
4905                 object_,
4906                 0,
4907                 NULL,
4908                 options,
4909                                 0,
4910                                 NULL,
4911                                 NULL,
4912                 notifyFptr,
4913                 data),
4914                 __COMPILE_PROGRAM_ERR);
4915     }
4916 #endif
4917
4918     template <typename T>
4919     cl_int getInfo(cl_program_info name, T* param) const
4920     {
4921         return detail::errHandler(
4922             detail::getInfo(&::clGetProgramInfo, object_, name, param),
4923             __GET_PROGRAM_INFO_ERR);
4924     }
4925
4926     template <cl_int name> typename
4927     detail::param_traits<detail::cl_program_info, name>::param_type
4928     getInfo(cl_int* err = NULL) const
4929     {
4930         typename detail::param_traits<
4931             detail::cl_program_info, name>::param_type param;
4932         cl_int result = getInfo(name, &param);
4933         if (err != NULL) {
4934             *err = result;
4935         }
4936         return param;
4937     }
4938
4939     template <typename T>
4940     cl_int getBuildInfo(
4941         const Device& device, cl_program_build_info name, T* param) const
4942     {
4943         return detail::errHandler(
4944             detail::getInfo(
4945                 &::clGetProgramBuildInfo, object_, device(), name, param),
4946                 __GET_PROGRAM_BUILD_INFO_ERR);
4947     }
4948
4949     template <cl_int name> typename
4950     detail::param_traits<detail::cl_program_build_info, name>::param_type
4951     getBuildInfo(const Device& device, cl_int* err = NULL) const
4952     {
4953         typename detail::param_traits<
4954             detail::cl_program_build_info, name>::param_type param;
4955         cl_int result = getBuildInfo(device, name, &param);
4956         if (err != NULL) {
4957             *err = result;
4958         }
4959         return param;
4960     }
4961
4962     cl_int createKernels(VECTOR_CLASS<Kernel>* kernels)
4963     {
4964         cl_uint numKernels;
4965         cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels);
4966         if (err != CL_SUCCESS) {
4967             return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
4968         }
4969
4970         Kernel* value = (Kernel*) alloca(numKernels * sizeof(Kernel));
4971         err = ::clCreateKernelsInProgram(
4972             object_, numKernels, (cl_kernel*) value, NULL);
4973         if (err != CL_SUCCESS) {
4974             return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
4975         }
4976
4977         kernels->assign(&value[0], &value[numKernels]);
4978         return CL_SUCCESS;
4979     }
4980 };
4981
4982 #if defined(CL_VERSION_1_2)
4983 inline Program linkProgram(
4984     Program input1,
4985     Program input2,
4986     const char* options = NULL,
4987     void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
4988     void* data = NULL,
4989     cl_int* err = NULL) 
4990 {
4991     cl_int err_local = CL_SUCCESS;
4992
4993     cl_program programs[2] = { input1(), input2() };
4994
4995     Context ctx = input1.getInfo<CL_PROGRAM_CONTEXT>();
4996
4997     cl_program prog = ::clLinkProgram(
4998         ctx(),
4999         0,
5000         NULL,
5001         options,
5002         2,
5003         programs,
5004         notifyFptr,
5005         data,
5006         &err_local);
5007
5008     detail::errHandler(err_local,__COMPILE_PROGRAM_ERR);
5009     if (err != NULL) {
5010         *err = err_local;
5011     }
5012
5013     return Program(prog);
5014 }
5015
5016 inline Program linkProgram(
5017     VECTOR_CLASS<Program> inputPrograms,
5018     const char* options = NULL,
5019     void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
5020     void* data = NULL,
5021     cl_int* err = NULL) 
5022 {
5023     cl_int err_local = CL_SUCCESS;
5024
5025     cl_program * programs = (cl_program*) alloca(inputPrograms.size() * sizeof(cl_program));
5026
5027     if (programs != NULL) {
5028         for (unsigned int i = 0; i < inputPrograms.size(); i++) {
5029           programs[i] = inputPrograms[i]();
5030         }
5031     } 
5032
5033     cl_program prog = ::clLinkProgram(
5034         Context::getDefault()(),
5035         0,
5036         NULL,
5037         options,
5038         (cl_uint)inputPrograms.size(),
5039         programs,
5040         notifyFptr,
5041         data,
5042         &err_local);
5043
5044     detail::errHandler(err_local,__COMPILE_PROGRAM_ERR);
5045     if (err != NULL) {
5046         *err = err_local;
5047     }
5048
5049     return Program(prog);
5050 }
5051 #endif
5052
5053 template<>
5054 inline VECTOR_CLASS<char *> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err) const
5055 {
5056     VECTOR_CLASS< ::size_t> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>();
5057     VECTOR_CLASS<char *> binaries;
5058     for (VECTOR_CLASS< ::size_t>::iterator s = sizes.begin(); s != sizes.end(); ++s) 
5059     {
5060         char *ptr = NULL;
5061         if (*s != 0) 
5062             ptr = new char[*s];
5063         binaries.push_back(ptr);
5064     }
5065     
5066     cl_int result = getInfo(CL_PROGRAM_BINARIES, &binaries);
5067     if (err != NULL) {
5068         *err = result;
5069     }
5070     return binaries;
5071 }
5072
5073 inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
5074 {
5075     cl_int error;
5076
5077     object_ = ::clCreateKernel(program(), name, &error);
5078     detail::errHandler(error, __CREATE_KERNEL_ERR);
5079
5080     if (err != NULL) {
5081         *err = error;
5082     }
5083
5084 }
5085
5086 /*! \class CommandQueue
5087  * \brief CommandQueue interface for cl_command_queue.
5088  */
5089 class CommandQueue : public detail::Wrapper<cl_command_queue>
5090 {
5091 private:
5092     static volatile int default_initialized_;
5093     static CommandQueue default_;
5094     static volatile cl_int default_error_;
5095 public:
5096    CommandQueue(
5097         cl_command_queue_properties properties,
5098         cl_int* err = NULL)
5099     {
5100         cl_int error;
5101
5102         Context context = Context::getDefault(&error);
5103         detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5104
5105         if (error != CL_SUCCESS) {
5106             if (err != NULL) {
5107                 *err = error;
5108             }
5109         }
5110         else {
5111             Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
5112
5113             object_ = ::clCreateCommandQueue(
5114                 context(), device(), properties, &error);
5115
5116             detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5117             if (err != NULL) {
5118                 *err = error;
5119             }
5120         }
5121     }
5122     /*!
5123     * \brief Constructs a CommandQueue for an implementation defined device in the given context
5124     */
5125     explicit CommandQueue(
5126         const Context& context,
5127         cl_command_queue_properties properties = 0,
5128         cl_int* err = NULL)
5129     {
5130         cl_int error;
5131         VECTOR_CLASS<cl::Device> devices;
5132         error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
5133
5134         detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5135
5136         if (error != CL_SUCCESS)
5137         {
5138             if (err != NULL) {
5139                 *err = error;
5140             }
5141             return;
5142         }
5143
5144         object_ = ::clCreateCommandQueue(context(), devices[0](), properties, &error);
5145
5146         detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5147
5148         if (err != NULL) {
5149             *err = error;
5150         }
5151
5152     }
5153
5154     CommandQueue(
5155         const Context& context,
5156         const Device& device,
5157         cl_command_queue_properties properties = 0,
5158         cl_int* err = NULL)
5159     {
5160         cl_int error;
5161         object_ = ::clCreateCommandQueue(
5162             context(), device(), properties, &error);
5163
5164         detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5165         if (err != NULL) {
5166             *err = error;
5167         }
5168     }
5169
5170     static CommandQueue getDefault(cl_int * err = NULL) 
5171     {
5172         int state = detail::compare_exchange(
5173             &default_initialized_, 
5174             __DEFAULT_BEING_INITIALIZED, __DEFAULT_NOT_INITIALIZED);
5175         
5176         if (state & __DEFAULT_INITIALIZED) {
5177             if (err != NULL) {
5178                 *err = default_error_;
5179             }
5180             return default_;
5181         }
5182
5183         if (state & __DEFAULT_BEING_INITIALIZED) {
5184               // Assume writes will propagate eventually...
5185               while(default_initialized_ != __DEFAULT_INITIALIZED) {
5186                   detail::fence();
5187               }
5188
5189             if (err != NULL) {
5190                 *err = default_error_;
5191             }
5192             return default_;
5193         }
5194
5195         cl_int error;
5196
5197         Context context = Context::getDefault(&error);
5198         detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5199
5200         if (error != CL_SUCCESS) {
5201             if (err != NULL) {
5202                 *err = error;
5203             }
5204         }
5205         else {
5206             Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
5207
5208             default_ = CommandQueue(context, device, 0, &error);
5209
5210             detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
5211             if (err != NULL) {
5212                 *err = error;
5213             }
5214         }
5215
5216         detail::fence();
5217
5218         default_error_ = error;
5219         // Assume writes will propagate eventually...
5220         default_initialized_ = __DEFAULT_INITIALIZED;
5221
5222         detail::fence();
5223
5224         if (err != NULL) {
5225             *err = default_error_;
5226         }
5227         return default_;
5228
5229     }
5230
5231     CommandQueue() { }
5232
5233     CommandQueue(const CommandQueue& commandQueue) : detail::Wrapper<cl_type>(commandQueue) { }
5234
5235     CommandQueue(const cl_command_queue& commandQueue) : detail::Wrapper<cl_type>(commandQueue) { }
5236
5237     CommandQueue& operator = (const CommandQueue& rhs)
5238     {
5239         if (this != &rhs) {
5240             detail::Wrapper<cl_type>::operator=(rhs);
5241         }
5242         return *this;
5243     }
5244
5245     CommandQueue& operator = (const cl_command_queue& rhs)
5246     {
5247         detail::Wrapper<cl_type>::operator=(rhs);
5248         return *this;
5249     }
5250
5251     template <typename T>
5252     cl_int getInfo(cl_command_queue_info name, T* param) const
5253     {
5254         return detail::errHandler(
5255             detail::getInfo(
5256                 &::clGetCommandQueueInfo, object_, name, param),
5257                 __GET_COMMAND_QUEUE_INFO_ERR);
5258     }
5259
5260     template <cl_int name> typename
5261     detail::param_traits<detail::cl_command_queue_info, name>::param_type
5262     getInfo(cl_int* err = NULL) const
5263     {
5264         typename detail::param_traits<
5265             detail::cl_command_queue_info, name>::param_type param;
5266         cl_int result = getInfo(name, &param);
5267         if (err != NULL) {
5268             *err = result;
5269         }
5270         return param;
5271     }
5272
5273     cl_int enqueueReadBuffer(
5274         const Buffer& buffer,
5275         cl_bool blocking,
5276         ::size_t offset,
5277         ::size_t size,
5278         void* ptr,
5279         const VECTOR_CLASS<Event>* events = NULL,
5280         Event* event = NULL) const
5281     {
5282         cl_event tmp;
5283         cl_int err = detail::errHandler(
5284             ::clEnqueueReadBuffer(
5285                 object_, buffer(), blocking, offset, size,
5286                 ptr,
5287                 (events != NULL) ? (cl_uint) events->size() : 0,
5288                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5289                 (event != NULL) ? &tmp : NULL),
5290             __ENQUEUE_READ_BUFFER_ERR);
5291
5292         if (event != NULL && err == CL_SUCCESS)
5293             *event = tmp;
5294
5295         return err;
5296     }
5297
5298     cl_int enqueueWriteBuffer(
5299         const Buffer& buffer,
5300         cl_bool blocking,
5301         ::size_t offset,
5302         ::size_t size,
5303         const void* ptr,
5304         const VECTOR_CLASS<Event>* events = NULL,
5305         Event* event = NULL) const
5306     {
5307         cl_event tmp;
5308         cl_int err = detail::errHandler(
5309             ::clEnqueueWriteBuffer(
5310                 object_, buffer(), blocking, offset, size,
5311                 ptr,
5312                 (events != NULL) ? (cl_uint) events->size() : 0,
5313                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5314                 (event != NULL) ? &tmp : NULL),
5315                 __ENQUEUE_WRITE_BUFFER_ERR);
5316
5317         if (event != NULL && err == CL_SUCCESS)
5318             *event = tmp;
5319
5320         return err;
5321     }
5322
5323     cl_int enqueueCopyBuffer(
5324         const Buffer& src,
5325         const Buffer& dst,
5326         ::size_t src_offset,
5327         ::size_t dst_offset,
5328         ::size_t size,
5329         const VECTOR_CLASS<Event>* events = NULL,
5330         Event* event = NULL) const
5331     {
5332         cl_event tmp;
5333         cl_int err = detail::errHandler(
5334             ::clEnqueueCopyBuffer(
5335                 object_, src(), dst(), src_offset, dst_offset, size,
5336                 (events != NULL) ? (cl_uint) events->size() : 0,
5337                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5338                 (event != NULL) ? &tmp : NULL),
5339             __ENQEUE_COPY_BUFFER_ERR);
5340
5341         if (event != NULL && err == CL_SUCCESS)
5342             *event = tmp;
5343
5344         return err;
5345     }
5346
5347     cl_int enqueueReadBufferRect(
5348         const Buffer& buffer,
5349         cl_bool blocking,
5350         const size_t<3>& buffer_offset,
5351         const size_t<3>& host_offset,
5352         const size_t<3>& region,
5353         ::size_t buffer_row_pitch,
5354         ::size_t buffer_slice_pitch,
5355         ::size_t host_row_pitch,
5356         ::size_t host_slice_pitch,
5357         void *ptr,
5358         const VECTOR_CLASS<Event>* events = NULL,
5359         Event* event = NULL) const
5360     {
5361         cl_event tmp;
5362         cl_int err = detail::errHandler(
5363             ::clEnqueueReadBufferRect(
5364                 object_, 
5365                 buffer(), 
5366                 blocking, 
5367                 (const ::size_t *)buffer_offset,
5368                 (const ::size_t *)host_offset,
5369                 (const ::size_t *)region,
5370                 buffer_row_pitch,
5371                 buffer_slice_pitch,
5372                 host_row_pitch,
5373                 host_slice_pitch,
5374                 ptr,
5375                 (events != NULL) ? (cl_uint) events->size() : 0,
5376                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5377                 (event != NULL) ? &tmp : NULL),
5378                 __ENQUEUE_READ_BUFFER_RECT_ERR);
5379
5380         if (event != NULL && err == CL_SUCCESS)
5381             *event = tmp;
5382
5383         return err;
5384     }
5385
5386     cl_int enqueueWriteBufferRect(
5387         const Buffer& buffer,
5388         cl_bool blocking,
5389         const size_t<3>& buffer_offset,
5390         const size_t<3>& host_offset,
5391         const size_t<3>& region,
5392         ::size_t buffer_row_pitch,
5393         ::size_t buffer_slice_pitch,
5394         ::size_t host_row_pitch,
5395         ::size_t host_slice_pitch,
5396         void *ptr,
5397         const VECTOR_CLASS<Event>* events = NULL,
5398         Event* event = NULL) const
5399     {
5400         cl_event tmp;
5401         cl_int err = detail::errHandler(
5402             ::clEnqueueWriteBufferRect(
5403                 object_, 
5404                 buffer(), 
5405                 blocking, 
5406                 (const ::size_t *)buffer_offset,
5407                 (const ::size_t *)host_offset,
5408                 (const ::size_t *)region,
5409                 buffer_row_pitch,
5410                 buffer_slice_pitch,
5411                 host_row_pitch,
5412                 host_slice_pitch,
5413                 ptr,
5414                 (events != NULL) ? (cl_uint) events->size() : 0,
5415                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5416                 (event != NULL) ? &tmp : NULL),
5417                 __ENQUEUE_WRITE_BUFFER_RECT_ERR);
5418
5419         if (event != NULL && err == CL_SUCCESS)
5420             *event = tmp;
5421
5422         return err;
5423     }
5424
5425     cl_int enqueueCopyBufferRect(
5426         const Buffer& src,
5427         const Buffer& dst,
5428         const size_t<3>& src_origin,
5429         const size_t<3>& dst_origin,
5430         const size_t<3>& region,
5431         ::size_t src_row_pitch,
5432         ::size_t src_slice_pitch,
5433         ::size_t dst_row_pitch,
5434         ::size_t dst_slice_pitch,
5435         const VECTOR_CLASS<Event>* events = NULL,
5436         Event* event = NULL) const
5437     {
5438         cl_event tmp;
5439         cl_int err = detail::errHandler(
5440             ::clEnqueueCopyBufferRect(
5441                 object_, 
5442                 src(), 
5443                 dst(), 
5444                 (const ::size_t *)src_origin, 
5445                 (const ::size_t *)dst_origin, 
5446                 (const ::size_t *)region,
5447                 src_row_pitch,
5448                 src_slice_pitch,
5449                 dst_row_pitch,
5450                 dst_slice_pitch,
5451                 (events != NULL) ? (cl_uint) events->size() : 0,
5452                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5453                 (event != NULL) ? &tmp : NULL),
5454             __ENQEUE_COPY_BUFFER_RECT_ERR);
5455
5456         if (event != NULL && err == CL_SUCCESS)
5457             *event = tmp;
5458
5459         return err;
5460     }
5461
5462 #if defined(CL_VERSION_1_2)
5463     /**
5464      * Enqueue a command to fill a buffer object with a pattern
5465      * of a given size. The pattern is specified a as vector.
5466      * \tparam PatternType The datatype of the pattern field. 
5467      *     The pattern type must be an accepted OpenCL data type.
5468      */
5469     template<typename PatternType>
5470     cl_int enqueueFillBuffer(
5471         const Buffer& buffer,
5472         PatternType pattern,
5473         ::size_t offset,
5474         ::size_t size,
5475         const VECTOR_CLASS<Event>* events = NULL,
5476         Event* event = NULL) const
5477     {
5478         cl_event tmp;
5479         cl_int err = detail::errHandler(
5480             ::clEnqueueFillBuffer(
5481                 object_, 
5482                 buffer(),
5483                 static_cast<void*>(&pattern),
5484                 sizeof(PatternType), 
5485                 offset, 
5486                 size,
5487                 (events != NULL) ? (cl_uint) events->size() : 0,
5488                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5489                 (event != NULL) ? &tmp : NULL),
5490                 __ENQUEUE_FILL_BUFFER_ERR);
5491
5492         if (event != NULL && err == CL_SUCCESS)
5493             *event = tmp;
5494
5495         return err;
5496     }
5497 #endif // #if defined(CL_VERSION_1_2)
5498
5499     cl_int enqueueReadImage(
5500         const Image& image,
5501         cl_bool blocking,
5502         const size_t<3>& origin,
5503         const size_t<3>& region,
5504         ::size_t row_pitch,
5505         ::size_t slice_pitch,
5506         void* ptr,
5507         const VECTOR_CLASS<Event>* events = NULL,
5508         Event* event = NULL) const
5509     {
5510         cl_event tmp;
5511         cl_int err = detail::errHandler(
5512             ::clEnqueueReadImage(
5513                 object_, image(), blocking, (const ::size_t *) origin,
5514                 (const ::size_t *) region, row_pitch, slice_pitch, ptr,
5515                 (events != NULL) ? (cl_uint) events->size() : 0,
5516                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5517                 (event != NULL) ? &tmp : NULL),
5518             __ENQUEUE_READ_IMAGE_ERR);
5519
5520         if (event != NULL && err == CL_SUCCESS)
5521             *event = tmp;
5522
5523         return err;
5524     }
5525
5526     cl_int enqueueWriteImage(
5527         const Image& image,
5528         cl_bool blocking,
5529         const size_t<3>& origin,
5530         const size_t<3>& region,
5531         ::size_t row_pitch,
5532         ::size_t slice_pitch,
5533         void* ptr,
5534         const VECTOR_CLASS<Event>* events = NULL,
5535         Event* event = NULL) const
5536     {
5537         cl_event tmp;
5538         cl_int err = detail::errHandler(
5539             ::clEnqueueWriteImage(
5540                 object_, image(), blocking, (const ::size_t *) origin,
5541                 (const ::size_t *) region, row_pitch, slice_pitch, ptr,
5542                 (events != NULL) ? (cl_uint) events->size() : 0,
5543                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5544                 (event != NULL) ? &tmp : NULL),
5545             __ENQUEUE_WRITE_IMAGE_ERR);
5546
5547         if (event != NULL && err == CL_SUCCESS)
5548             *event = tmp;
5549
5550         return err;
5551     }
5552
5553     cl_int enqueueCopyImage(
5554         const Image& src,
5555         const Image& dst,
5556         const size_t<3>& src_origin,
5557         const size_t<3>& dst_origin,
5558         const size_t<3>& region,
5559         const VECTOR_CLASS<Event>* events = NULL,
5560         Event* event = NULL) const
5561     {
5562         cl_event tmp;
5563         cl_int err = detail::errHandler(
5564             ::clEnqueueCopyImage(
5565                 object_, src(), dst(), (const ::size_t *) src_origin,
5566                 (const ::size_t *)dst_origin, (const ::size_t *) region,
5567                 (events != NULL) ? (cl_uint) events->size() : 0,
5568                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5569                 (event != NULL) ? &tmp : NULL),
5570             __ENQUEUE_COPY_IMAGE_ERR);
5571
5572         if (event != NULL && err == CL_SUCCESS)
5573             *event = tmp;
5574
5575         return err;
5576     }
5577
5578 #if defined(CL_VERSION_1_2)
5579     /**
5580      * Enqueue a command to fill an image object with a specified color.
5581      * \param fillColor is the color to use to fill the image.
5582      *     This is a four component RGBA floating-point color value if
5583      *     the image channel data type is not an unnormalized signed or
5584      *     unsigned data type.
5585      */
5586     cl_int enqueueFillImage(
5587         const Image& image,
5588         cl_float4 fillColor,
5589         const size_t<3>& origin,
5590         const size_t<3>& region,
5591         const VECTOR_CLASS<Event>* events = NULL,
5592         Event* event = NULL) const
5593     {
5594         cl_event tmp;
5595         cl_int err = detail::errHandler(
5596             ::clEnqueueFillImage(
5597                 object_, 
5598                 image(),
5599                 static_cast<void*>(&fillColor), 
5600                 (const ::size_t *) origin, 
5601                 (const ::size_t *) region,
5602                 (events != NULL) ? (cl_uint) events->size() : 0,
5603                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5604                 (event != NULL) ? &tmp : NULL),
5605                 __ENQUEUE_FILL_IMAGE_ERR);
5606
5607         if (event != NULL && err == CL_SUCCESS)
5608             *event = tmp;
5609
5610         return err;
5611     }
5612
5613     /**
5614      * Enqueue a command to fill an image object with a specified color.
5615      * \param fillColor is the color to use to fill the image.
5616      *     This is a four component RGBA signed integer color value if
5617      *     the image channel data type is an unnormalized signed integer
5618      *     type.
5619      */
5620     cl_int enqueueFillImage(
5621         const Image& image,
5622         cl_int4 fillColor,
5623         const size_t<3>& origin,
5624         const size_t<3>& region,
5625         const VECTOR_CLASS<Event>* events = NULL,
5626         Event* event = NULL) const
5627     {
5628         cl_event tmp;
5629         cl_int err = detail::errHandler(
5630             ::clEnqueueFillImage(
5631                 object_, 
5632                 image(),
5633                 static_cast<void*>(&fillColor), 
5634                 (const ::size_t *) origin, 
5635                 (const ::size_t *) region,
5636                 (events != NULL) ? (cl_uint) events->size() : 0,
5637                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5638                 (event != NULL) ? &tmp : NULL),
5639                 __ENQUEUE_FILL_IMAGE_ERR);
5640
5641         if (event != NULL && err == CL_SUCCESS)
5642             *event = tmp;
5643
5644         return err;
5645     }
5646
5647     /**
5648      * Enqueue a command to fill an image object with a specified color.
5649      * \param fillColor is the color to use to fill the image.
5650      *     This is a four component RGBA unsigned integer color value if
5651      *     the image channel data type is an unnormalized unsigned integer
5652      *     type.
5653      */
5654     cl_int enqueueFillImage(
5655         const Image& image,
5656         cl_uint4 fillColor,
5657         const size_t<3>& origin,
5658         const size_t<3>& region,
5659         const VECTOR_CLASS<Event>* events = NULL,
5660         Event* event = NULL) const
5661     {
5662         cl_event tmp;
5663         cl_int err = detail::errHandler(
5664             ::clEnqueueFillImage(
5665                 object_, 
5666                 image(),
5667                 static_cast<void*>(&fillColor), 
5668                 (const ::size_t *) origin, 
5669                 (const ::size_t *) region,
5670                 (events != NULL) ? (cl_uint) events->size() : 0,
5671                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5672                 (event != NULL) ? &tmp : NULL),
5673                 __ENQUEUE_FILL_IMAGE_ERR);
5674
5675         if (event != NULL && err == CL_SUCCESS)
5676             *event = tmp;
5677
5678         return err;
5679     }
5680 #endif // #if defined(CL_VERSION_1_2)
5681
5682     cl_int enqueueCopyImageToBuffer(
5683         const Image& src,
5684         const Buffer& dst,
5685         const size_t<3>& src_origin,
5686         const size_t<3>& region,
5687         ::size_t dst_offset,
5688         const VECTOR_CLASS<Event>* events = NULL,
5689         Event* event = NULL) const
5690     {
5691         cl_event tmp;
5692         cl_int err = detail::errHandler(
5693             ::clEnqueueCopyImageToBuffer(
5694                 object_, src(), dst(), (const ::size_t *) src_origin,
5695                 (const ::size_t *) region, dst_offset,
5696                 (events != NULL) ? (cl_uint) events->size() : 0,
5697                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5698                 (event != NULL) ? &tmp : NULL),
5699             __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR);
5700
5701         if (event != NULL && err == CL_SUCCESS)
5702             *event = tmp;
5703
5704         return err;
5705     }
5706
5707     cl_int enqueueCopyBufferToImage(
5708         const Buffer& src,
5709         const Image& dst,
5710         ::size_t src_offset,
5711         const size_t<3>& dst_origin,
5712         const size_t<3>& region,
5713         const VECTOR_CLASS<Event>* events = NULL,
5714         Event* event = NULL) const
5715     {
5716         cl_event tmp;
5717         cl_int err = detail::errHandler(
5718             ::clEnqueueCopyBufferToImage(
5719                 object_, src(), dst(), src_offset,
5720                 (const ::size_t *) dst_origin, (const ::size_t *) region,
5721                 (events != NULL) ? (cl_uint) events->size() : 0,
5722                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5723                 (event != NULL) ? &tmp : NULL),
5724             __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR);
5725
5726         if (event != NULL && err == CL_SUCCESS)
5727             *event = tmp;
5728
5729         return err;
5730     }
5731
5732     void* enqueueMapBuffer(
5733         const Buffer& buffer,
5734         cl_bool blocking,
5735         cl_map_flags flags,
5736         ::size_t offset,
5737         ::size_t size,
5738         const VECTOR_CLASS<Event>* events = NULL,
5739         Event* event = NULL,
5740         cl_int* err = NULL) const
5741     {
5742         cl_int error;
5743         void * result = ::clEnqueueMapBuffer(
5744             object_, buffer(), blocking, flags, offset, size,
5745             (events != NULL) ? (cl_uint) events->size() : 0,
5746             (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5747             (cl_event*) event,
5748             &error);
5749
5750         detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
5751         if (err != NULL) {
5752             *err = error;
5753         }
5754         return result;
5755     }
5756
5757     void* enqueueMapImage(
5758         const Image& buffer,
5759         cl_bool blocking,
5760         cl_map_flags flags,
5761         const size_t<3>& origin,
5762         const size_t<3>& region,
5763         ::size_t * row_pitch,
5764         ::size_t * slice_pitch,
5765         const VECTOR_CLASS<Event>* events = NULL,
5766         Event* event = NULL,
5767         cl_int* err = NULL) const
5768     {
5769         cl_int error;
5770         void * result = ::clEnqueueMapImage(
5771             object_, buffer(), blocking, flags,
5772             (const ::size_t *) origin, (const ::size_t *) region,
5773             row_pitch, slice_pitch,
5774             (events != NULL) ? (cl_uint) events->size() : 0,
5775             (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5776             (cl_event*) event,
5777             &error);
5778
5779         detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR);
5780         if (err != NULL) {
5781               *err = error;
5782         }
5783         return result;
5784     }
5785
5786     cl_int enqueueUnmapMemObject(
5787         const Memory& memory,
5788         void* mapped_ptr,
5789         const VECTOR_CLASS<Event>* events = NULL,
5790         Event* event = NULL) const
5791     {
5792         cl_event tmp;
5793         cl_int err = detail::errHandler(
5794             ::clEnqueueUnmapMemObject(
5795                 object_, memory(), mapped_ptr,
5796                 (events != NULL) ? (cl_uint) events->size() : 0,
5797                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5798                 (event != NULL) ? &tmp : NULL),
5799             __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
5800
5801         if (event != NULL && err == CL_SUCCESS)
5802             *event = tmp;
5803
5804         return err;
5805     }
5806
5807 #if defined(CL_VERSION_1_2)
5808     /**
5809      * Enqueues a marker command which waits for either a list of events to complete, 
5810      * or all previously enqueued commands to complete.
5811      *
5812      * Enqueues a marker command which waits for either a list of events to complete, 
5813      * or if the list is empty it waits for all commands previously enqueued in command_queue 
5814      * to complete before it completes. This command returns an event which can be waited on, 
5815      * i.e. this event can be waited on to insure that all events either in the event_wait_list 
5816      * or all previously enqueued commands, queued before this command to command_queue, 
5817      * have completed.
5818      */
5819     cl_int enqueueMarkerWithWaitList(
5820         const VECTOR_CLASS<Event> *events = 0,
5821         Event *event = 0)
5822     {
5823         cl_event tmp;
5824         cl_int err = detail::errHandler(
5825             ::clEnqueueMarkerWithWaitList(
5826                 object_,
5827                 (events != NULL) ? (cl_uint) events->size() : 0,
5828                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5829                 (event != NULL) ? &tmp : NULL),
5830             __ENQUEUE_MARKER_WAIT_LIST_ERR);
5831
5832         if (event != NULL && err == CL_SUCCESS)
5833             *event = tmp;
5834
5835         return err;
5836     }
5837
5838     /**
5839      * A synchronization point that enqueues a barrier operation.
5840      *
5841      * Enqueues a barrier command which waits for either a list of events to complete, 
5842      * or if the list is empty it waits for all commands previously enqueued in command_queue 
5843      * to complete before it completes. This command blocks command execution, that is, any 
5844      * following commands enqueued after it do not execute until it completes. This command 
5845      * returns an event which can be waited on, i.e. this event can be waited on to insure that 
5846      * all events either in the event_wait_list or all previously enqueued commands, queued 
5847      * before this command to command_queue, have completed.
5848      */
5849     cl_int enqueueBarrierWithWaitList(
5850         const VECTOR_CLASS<Event> *events = 0,
5851         Event *event = 0)
5852     {
5853         cl_event tmp;
5854         cl_int err = detail::errHandler(
5855             ::clEnqueueBarrierWithWaitList(
5856                 object_,
5857                 (events != NULL) ? (cl_uint) events->size() : 0,
5858                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5859                 (event != NULL) ? &tmp : NULL),
5860             __ENQUEUE_BARRIER_WAIT_LIST_ERR);
5861
5862         if (event != NULL && err == CL_SUCCESS)
5863             *event = tmp;
5864
5865         return err;
5866     }
5867     
5868     /**
5869      * Enqueues a command to indicate with which device a set of memory objects
5870      * should be associated.
5871      */
5872     cl_int enqueueMigrateMemObjects(
5873         const VECTOR_CLASS<Memory> &memObjects,
5874         cl_mem_migration_flags flags,
5875         const VECTOR_CLASS<Event>* events = NULL,
5876         Event* event = NULL
5877         )
5878     {
5879         cl_event tmp;
5880         
5881         cl_mem* localMemObjects = static_cast<cl_mem*>(alloca(memObjects.size() * sizeof(cl_mem)));
5882         for( int i = 0; i < (int)memObjects.size(); ++i ) {
5883             localMemObjects[i] = memObjects[i]();
5884         }
5885
5886
5887         cl_int err = detail::errHandler(
5888             ::clEnqueueMigrateMemObjects(
5889                 object_, 
5890                 (cl_uint)memObjects.size(), 
5891                 static_cast<const cl_mem*>(localMemObjects),
5892                 flags,
5893                 (events != NULL) ? (cl_uint) events->size() : 0,
5894                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5895                 (event != NULL) ? &tmp : NULL),
5896             __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
5897
5898         if (event != NULL && err == CL_SUCCESS)
5899             *event = tmp;
5900
5901         return err;
5902     }
5903 #endif // #if defined(CL_VERSION_1_2)
5904
5905     cl_int enqueueNDRangeKernel(
5906         const Kernel& kernel,
5907         const NDRange& offset,
5908         const NDRange& global,
5909         const NDRange& local = NullRange,
5910         const VECTOR_CLASS<Event>* events = NULL,
5911         Event* event = NULL) const
5912     {
5913         cl_event tmp;
5914         cl_int err = detail::errHandler(
5915             ::clEnqueueNDRangeKernel(
5916                 object_, kernel(), (cl_uint) global.dimensions(),
5917                 offset.dimensions() != 0 ? (const ::size_t*) offset : NULL,
5918                 (const ::size_t*) global,
5919                 local.dimensions() != 0 ? (const ::size_t*) local : NULL,
5920                 (events != NULL) ? (cl_uint) events->size() : 0,
5921                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5922                 (event != NULL) ? &tmp : NULL),
5923             __ENQUEUE_NDRANGE_KERNEL_ERR);
5924
5925         if (event != NULL && err == CL_SUCCESS)
5926             *event = tmp;
5927
5928         return err;
5929     }
5930
5931     cl_int enqueueTask(
5932         const Kernel& kernel,
5933         const VECTOR_CLASS<Event>* events = NULL,
5934         Event* event = NULL) const
5935     {
5936         cl_event tmp;
5937         cl_int err = detail::errHandler(
5938             ::clEnqueueTask(
5939                 object_, kernel(),
5940                 (events != NULL) ? (cl_uint) events->size() : 0,
5941                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5942                 (event != NULL) ? &tmp : NULL),
5943             __ENQUEUE_TASK_ERR);
5944
5945         if (event != NULL && err == CL_SUCCESS)
5946             *event = tmp;
5947
5948         return err;
5949     }
5950
5951     cl_int enqueueNativeKernel(
5952         void (CL_CALLBACK *userFptr)(void *),
5953         std::pair<void*, ::size_t> args,
5954         const VECTOR_CLASS<Memory>* mem_objects = NULL,
5955         const VECTOR_CLASS<const void*>* mem_locs = NULL,
5956         const VECTOR_CLASS<Event>* events = NULL,
5957         Event* event = NULL) const
5958     {
5959         cl_mem * mems = (mem_objects != NULL && mem_objects->size() > 0) 
5960             ? (cl_mem*) alloca(mem_objects->size() * sizeof(cl_mem))
5961             : NULL;
5962
5963         if (mems != NULL) {
5964             for (unsigned int i = 0; i < mem_objects->size(); i++) {
5965                 mems[i] = ((*mem_objects)[i])();
5966             }
5967         }
5968
5969         cl_event tmp;
5970         cl_int err = detail::errHandler(
5971             ::clEnqueueNativeKernel(
5972                 object_, userFptr, args.first, args.second,
5973                 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
5974                 mems,
5975                 (mem_locs != NULL) ? (const void **) &mem_locs->front() : NULL,
5976                 (events != NULL) ? (cl_uint) events->size() : 0,
5977                 (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
5978                 (event != NULL) ? &tmp : NULL),
5979             __ENQUEUE_NATIVE_KERNEL);
5980
5981         if (event != NULL && err == CL_SUCCESS)
5982             *event = tmp;
5983
5984         return err;
5985     }
5986
5987 /**
5988  * Deprecated APIs for 1.2
5989  */
5990 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) 
5991     CL_EXT_PREFIX__VERSION_1_1_DEPRECATED 
5992     cl_int enqueueMarker(Event* event = NULL) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
5993     {
5994         return detail::errHandler(
5995             ::clEnqueueMarker(object_, (cl_event*) event),
5996             __ENQUEUE_MARKER_ERR);
5997     }
5998
5999     CL_EXT_PREFIX__VERSION_1_1_DEPRECATED
6000     cl_int enqueueWaitForEvents(const VECTOR_CLASS<Event>& events) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
6001     {
6002         return detail::errHandler(
6003             ::clEnqueueWaitForEvents(
6004                 object_,
6005                 (cl_uint) events.size(),
6006                 (const cl_event*) &events.front()),
6007             __ENQUEUE_WAIT_FOR_EVENTS_ERR);
6008     }
6009 #endif // #if defined(CL_VERSION_1_1)
6010
6011     cl_int enqueueAcquireGLObjects(
6012          const VECTOR_CLASS<Memory>* mem_objects = NULL,
6013          const VECTOR_CLASS<Event>* events = NULL,
6014          Event* event = NULL) const
6015      {
6016         cl_event tmp;
6017         cl_int err = detail::errHandler(
6018              ::clEnqueueAcquireGLObjects(
6019                  object_,
6020                  (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
6021                  (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
6022                  (events != NULL) ? (cl_uint) events->size() : 0,
6023                  (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
6024                  (event != NULL) ? &tmp : NULL),
6025              __ENQUEUE_ACQUIRE_GL_ERR);
6026
6027         if (event != NULL && err == CL_SUCCESS)
6028             *event = tmp;
6029
6030         return err;
6031      }
6032
6033     cl_int enqueueReleaseGLObjects(
6034          const VECTOR_CLASS<Memory>* mem_objects = NULL,
6035          const VECTOR_CLASS<Event>* events = NULL,
6036          Event* event = NULL) const
6037      {
6038         cl_event tmp;
6039         cl_int err = detail::errHandler(
6040              ::clEnqueueReleaseGLObjects(
6041                  object_,
6042                  (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
6043                  (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
6044                  (events != NULL) ? (cl_uint) events->size() : 0,
6045                  (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
6046                  (event != NULL) ? &tmp : NULL),
6047              __ENQUEUE_RELEASE_GL_ERR);
6048
6049         if (event != NULL && err == CL_SUCCESS)
6050             *event = tmp;
6051
6052         return err;
6053      }
6054
6055 #if defined (USE_DX_INTEROP)
6056 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)(
6057     cl_command_queue command_queue, cl_uint num_objects,
6058     const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
6059     const cl_event* event_wait_list, cl_event* event);
6060 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)(
6061     cl_command_queue command_queue, cl_uint num_objects,
6062     const cl_mem* mem_objects,  cl_uint num_events_in_wait_list,
6063     const cl_event* event_wait_list, cl_event* event);
6064
6065     cl_int enqueueAcquireD3D10Objects(
6066          const VECTOR_CLASS<Memory>* mem_objects = NULL,
6067          const VECTOR_CLASS<Event>* events = NULL,
6068          Event* event = NULL) const
6069     {
6070         static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL;
6071 #if defined(CL_VERSION_1_2)
6072         cl_context context = getInfo<CL_QUEUE_CONTEXT>();
6073         cl::Device device(getInfo<CL_QUEUE_DEVICE>());
6074         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
6075         __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clEnqueueAcquireD3D10ObjectsKHR);
6076 #endif
6077 #if defined(CL_VERSION_1_1)
6078         __INIT_CL_EXT_FCN_PTR(clEnqueueAcquireD3D10ObjectsKHR);
6079 #endif
6080         
6081         cl_event tmp;
6082         cl_int err = detail::errHandler(
6083              pfn_clEnqueueAcquireD3D10ObjectsKHR(
6084                  object_,
6085                  (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
6086                  (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
6087                  (events != NULL) ? (cl_uint) events->size() : 0,
6088                  (events != NULL) ? (cl_event*) &events->front() : NULL,
6089                  (event != NULL) ? &tmp : NULL),
6090              __ENQUEUE_ACQUIRE_GL_ERR);
6091
6092         if (event != NULL && err == CL_SUCCESS)
6093             *event = tmp;
6094
6095         return err;
6096      }
6097
6098     cl_int enqueueReleaseD3D10Objects(
6099          const VECTOR_CLASS<Memory>* mem_objects = NULL,
6100          const VECTOR_CLASS<Event>* events = NULL,
6101          Event* event = NULL) const
6102     {
6103         static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL;
6104 #if defined(CL_VERSION_1_2)
6105         cl_context context = getInfo<CL_QUEUE_CONTEXT>();
6106         cl::Device device(getInfo<CL_QUEUE_DEVICE>());
6107         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
6108         __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clEnqueueReleaseD3D10ObjectsKHR);
6109 #endif // #if defined(CL_VERSION_1_2)
6110 #if defined(CL_VERSION_1_1)
6111         __INIT_CL_EXT_FCN_PTR(clEnqueueReleaseD3D10ObjectsKHR);
6112 #endif // #if defined(CL_VERSION_1_1)
6113
6114         cl_event tmp;
6115         cl_int err = detail::errHandler(
6116             pfn_clEnqueueReleaseD3D10ObjectsKHR(
6117                 object_,
6118                 (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0,
6119                 (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL,
6120                 (events != NULL) ? (cl_uint) events->size() : 0,
6121                 (events != NULL) ? (cl_event*) &events->front() : NULL,
6122                 (event != NULL) ? &tmp : NULL),
6123             __ENQUEUE_RELEASE_GL_ERR);
6124
6125         if (event != NULL && err == CL_SUCCESS)
6126             *event = tmp;
6127
6128         return err;
6129     }
6130 #endif
6131
6132 /**
6133  * Deprecated APIs for 1.2
6134  */
6135 #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) 
6136     CL_EXT_PREFIX__VERSION_1_1_DEPRECATED
6137     cl_int enqueueBarrier() const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED
6138     {
6139         return detail::errHandler(
6140             ::clEnqueueBarrier(object_),
6141             __ENQUEUE_BARRIER_ERR);
6142     }
6143 #endif // #if defined(CL_VERSION_1_1)
6144
6145     cl_int flush() const
6146     {
6147         return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
6148     }
6149
6150     cl_int finish() const
6151     {
6152         return detail::errHandler(::clFinish(object_), __FINISH_ERR);
6153     }
6154 };
6155
6156 #ifdef _WIN32
6157 __declspec(selectany) volatile int CommandQueue::default_initialized_ = __DEFAULT_NOT_INITIALIZED;
6158 __declspec(selectany) CommandQueue CommandQueue::default_;
6159 __declspec(selectany) volatile cl_int CommandQueue::default_error_ = CL_SUCCESS;
6160 #else
6161 __attribute__((weak)) volatile int CommandQueue::default_initialized_ = __DEFAULT_NOT_INITIALIZED;
6162 __attribute__((weak)) CommandQueue CommandQueue::default_;
6163 __attribute__((weak)) volatile cl_int CommandQueue::default_error_ = CL_SUCCESS;
6164 #endif
6165
6166 template< typename IteratorType >
6167 Buffer::Buffer(
6168     const Context &context,
6169     IteratorType startIterator,
6170     IteratorType endIterator,
6171     bool readOnly,
6172     bool useHostPtr,
6173     cl_int* err)
6174 {
6175     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
6176     cl_int error;
6177
6178     cl_mem_flags flags = 0;
6179     if( readOnly ) {
6180         flags |= CL_MEM_READ_ONLY;
6181     }
6182     else {
6183         flags |= CL_MEM_READ_WRITE;
6184     }
6185     if( useHostPtr ) {
6186         flags |= CL_MEM_USE_HOST_PTR;
6187     }
6188     
6189     ::size_t size = sizeof(DataType)*(endIterator - startIterator);
6190
6191     if( useHostPtr ) {
6192         object_ = ::clCreateBuffer(context(), flags, size, static_cast<DataType*>(&*startIterator), &error);
6193     } else {
6194         object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
6195     }
6196
6197     detail::errHandler(error, __CREATE_BUFFER_ERR);
6198     if (err != NULL) {
6199         *err = error;
6200     }
6201
6202     if( !useHostPtr ) {
6203         CommandQueue queue(context, 0, &error);
6204         detail::errHandler(error, __CREATE_BUFFER_ERR);
6205         if (err != NULL) {
6206             *err = error;
6207         }
6208
6209         error = cl::copy(queue, startIterator, endIterator, *this);
6210         detail::errHandler(error, __CREATE_BUFFER_ERR);
6211         if (err != NULL) {
6212             *err = error;
6213         }
6214     }
6215 }
6216
6217 inline cl_int enqueueReadBuffer(
6218     const Buffer& buffer,
6219     cl_bool blocking,
6220     ::size_t offset,
6221     ::size_t size,
6222     void* ptr,
6223     const VECTOR_CLASS<Event>* events = NULL,
6224     Event* event = NULL)
6225 {
6226     cl_int error;
6227     CommandQueue queue = CommandQueue::getDefault(&error);
6228
6229     if (error != CL_SUCCESS) {
6230         return error;
6231     }
6232
6233     return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event);
6234 }
6235
6236 inline cl_int enqueueWriteBuffer(
6237         const Buffer& buffer,
6238         cl_bool blocking,
6239         ::size_t offset,
6240         ::size_t size,
6241         const void* ptr,
6242         const VECTOR_CLASS<Event>* events = NULL,
6243         Event* event = NULL)
6244 {
6245     cl_int error;
6246     CommandQueue queue = CommandQueue::getDefault(&error);
6247
6248     if (error != CL_SUCCESS) {
6249         return error;
6250     }
6251
6252     return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event);
6253 }
6254
6255 inline void* enqueueMapBuffer(
6256         const Buffer& buffer,
6257         cl_bool blocking,
6258         cl_map_flags flags,
6259         ::size_t offset,
6260         ::size_t size,
6261         const VECTOR_CLASS<Event>* events = NULL,
6262         Event* event = NULL,
6263         cl_int* err = NULL)
6264 {
6265     cl_int error;
6266     CommandQueue queue = CommandQueue::getDefault(&error);
6267     detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
6268     if (err != NULL) {
6269         *err = error;
6270     }
6271
6272     void * result = ::clEnqueueMapBuffer(
6273             queue(), buffer(), blocking, flags, offset, size,
6274             (events != NULL) ? (cl_uint) events->size() : 0,
6275             (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
6276             (cl_event*) event,
6277             &error);
6278
6279     detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
6280     if (err != NULL) {
6281         *err = error;
6282     }
6283     return result;
6284 }
6285
6286 inline cl_int enqueueUnmapMemObject(
6287     const Memory& memory,
6288     void* mapped_ptr,
6289     const VECTOR_CLASS<Event>* events = NULL,
6290     Event* event = NULL)
6291 {
6292     cl_int error;
6293     CommandQueue queue = CommandQueue::getDefault(&error);
6294     detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
6295     if (error != CL_SUCCESS) {
6296         return error;
6297     }
6298
6299     cl_event tmp;
6300     cl_int err = detail::errHandler(
6301         ::clEnqueueUnmapMemObject(
6302             queue(), memory(), mapped_ptr,
6303             (events != NULL) ? (cl_uint) events->size() : 0,
6304             (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
6305             (event != NULL) ? &tmp : NULL),
6306         __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
6307
6308     if (event != NULL && err == CL_SUCCESS)
6309         *event = tmp;
6310
6311     return err;
6312 }
6313
6314 inline cl_int enqueueCopyBuffer(
6315         const Buffer& src,
6316         const Buffer& dst,
6317         ::size_t src_offset,
6318         ::size_t dst_offset,
6319         ::size_t size,
6320         const VECTOR_CLASS<Event>* events = NULL,
6321         Event* event = NULL)
6322 {
6323     cl_int error;
6324     CommandQueue queue = CommandQueue::getDefault(&error);
6325
6326     if (error != CL_SUCCESS) {
6327         return error;
6328     }
6329
6330     return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event);
6331 }
6332
6333 /**
6334  * Blocking copy operation between iterators and a buffer.
6335  * Host to Device.
6336  * Uses default command queue.
6337  */
6338 template< typename IteratorType >
6339 inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
6340 {
6341     cl_int error;
6342     CommandQueue queue = CommandQueue::getDefault(&error);
6343     if (error != CL_SUCCESS)
6344         return error;
6345
6346     return cl::copy(queue, startIterator, endIterator, buffer);
6347 }
6348
6349 /**
6350  * Blocking copy operation between iterators and a buffer.
6351  * Device to Host.
6352  * Uses default command queue.
6353  */
6354 template< typename IteratorType >
6355 inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
6356 {
6357     cl_int error;
6358     CommandQueue queue = CommandQueue::getDefault(&error);
6359     if (error != CL_SUCCESS)
6360         return error;
6361
6362     return cl::copy(queue, buffer, startIterator, endIterator);
6363 }
6364
6365 /**
6366  * Blocking copy operation between iterators and a buffer.
6367  * Host to Device.
6368  * Uses specified queue.
6369  */
6370 template< typename IteratorType >
6371 inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
6372 {
6373     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
6374     cl_int error;
6375     
6376     ::size_t length = endIterator-startIterator;
6377     ::size_t byteLength = length*sizeof(DataType);
6378
6379     DataType *pointer = 
6380         static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error));
6381     // if exceptions enabled, enqueueMapBuffer will throw
6382     if( error != CL_SUCCESS ) {
6383         return error;
6384     }
6385 #if defined(_MSC_VER)
6386     std::copy(
6387         startIterator, 
6388         endIterator, 
6389         stdext::checked_array_iterator<DataType*>(
6390             pointer, length));
6391 #else
6392     std::copy(startIterator, endIterator, pointer);
6393 #endif
6394     Event endEvent;
6395     error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
6396     // if exceptions enabled, enqueueUnmapMemObject will throw
6397     if( error != CL_SUCCESS ) { 
6398         return error;
6399     }
6400     endEvent.wait();
6401     return CL_SUCCESS;
6402 }
6403
6404 /**
6405  * Blocking copy operation between iterators and a buffer.
6406  * Device to Host.
6407  * Uses specified queue.
6408  */
6409 template< typename IteratorType >
6410 inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
6411 {
6412     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
6413     cl_int error;
6414         
6415     ::size_t length = endIterator-startIterator;
6416     ::size_t byteLength = length*sizeof(DataType);
6417
6418     DataType *pointer = 
6419         static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error));
6420     // if exceptions enabled, enqueueMapBuffer will throw
6421     if( error != CL_SUCCESS ) {
6422         return error;
6423     }
6424     std::copy(pointer, pointer + length, startIterator);
6425     Event endEvent;
6426     error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
6427     // if exceptions enabled, enqueueUnmapMemObject will throw
6428     if( error != CL_SUCCESS ) { 
6429         return error;
6430     }
6431     endEvent.wait();
6432     return CL_SUCCESS;
6433 }
6434
6435 #if defined(CL_VERSION_1_1)
6436 inline cl_int enqueueReadBufferRect(
6437     const Buffer& buffer,
6438     cl_bool blocking,
6439     const size_t<3>& buffer_offset,
6440     const size_t<3>& host_offset,
6441     const size_t<3>& region,
6442     ::size_t buffer_row_pitch,
6443     ::size_t buffer_slice_pitch,
6444     ::size_t host_row_pitch,
6445     ::size_t host_slice_pitch,
6446     void *ptr,
6447     const VECTOR_CLASS<Event>* events = NULL,
6448     Event* event = NULL)
6449 {
6450     cl_int error;
6451     CommandQueue queue = CommandQueue::getDefault(&error);
6452
6453     if (error != CL_SUCCESS) {
6454         return error;
6455     }
6456
6457     return queue.enqueueReadBufferRect(
6458         buffer, 
6459         blocking, 
6460         buffer_offset, 
6461         host_offset,
6462         region,
6463         buffer_row_pitch,
6464         buffer_slice_pitch,
6465         host_row_pitch,
6466         host_slice_pitch,
6467         ptr, 
6468         events, 
6469         event);
6470 }
6471
6472 inline cl_int enqueueWriteBufferRect(
6473     const Buffer& buffer,
6474     cl_bool blocking,
6475     const size_t<3>& buffer_offset,
6476     const size_t<3>& host_offset,
6477     const size_t<3>& region,
6478     ::size_t buffer_row_pitch,
6479     ::size_t buffer_slice_pitch,
6480     ::size_t host_row_pitch,
6481     ::size_t host_slice_pitch,
6482     void *ptr,
6483     const VECTOR_CLASS<Event>* events = NULL,
6484     Event* event = NULL)
6485 {
6486     cl_int error;
6487     CommandQueue queue = CommandQueue::getDefault(&error);
6488
6489     if (error != CL_SUCCESS) {
6490         return error;
6491     }
6492
6493     return queue.enqueueWriteBufferRect(
6494         buffer, 
6495         blocking, 
6496         buffer_offset, 
6497         host_offset,
6498         region,
6499         buffer_row_pitch,
6500         buffer_slice_pitch,
6501         host_row_pitch,
6502         host_slice_pitch,
6503         ptr, 
6504         events, 
6505         event);
6506 }
6507
6508 inline cl_int enqueueCopyBufferRect(
6509     const Buffer& src,
6510     const Buffer& dst,
6511     const size_t<3>& src_origin,
6512     const size_t<3>& dst_origin,
6513     const size_t<3>& region,
6514     ::size_t src_row_pitch,
6515     ::size_t src_slice_pitch,
6516     ::size_t dst_row_pitch,
6517     ::size_t dst_slice_pitch,
6518     const VECTOR_CLASS<Event>* events = NULL,
6519     Event* event = NULL)
6520 {
6521     cl_int error;
6522     CommandQueue queue = CommandQueue::getDefault(&error);
6523
6524     if (error != CL_SUCCESS) {
6525         return error;
6526     }
6527
6528     return queue.enqueueCopyBufferRect(
6529         src,
6530         dst,
6531         src_origin,
6532         dst_origin,
6533         region,
6534         src_row_pitch,
6535         src_slice_pitch,
6536         dst_row_pitch,
6537         dst_slice_pitch,
6538         events, 
6539         event);
6540 }
6541 #endif
6542
6543 inline cl_int enqueueReadImage(
6544     const Image& image,
6545     cl_bool blocking,
6546     const size_t<3>& origin,
6547     const size_t<3>& region,
6548     ::size_t row_pitch,
6549     ::size_t slice_pitch,
6550     void* ptr,
6551     const VECTOR_CLASS<Event>* events = NULL,
6552     Event* event = NULL) 
6553 {
6554     cl_int error;
6555     CommandQueue queue = CommandQueue::getDefault(&error);
6556
6557     if (error != CL_SUCCESS) {
6558         return error;
6559     }
6560
6561     return queue.enqueueReadImage(
6562         image,
6563         blocking,
6564         origin,
6565         region,
6566         row_pitch,
6567         slice_pitch,
6568         ptr,
6569         events, 
6570         event);
6571 }
6572
6573 inline cl_int enqueueWriteImage(
6574     const Image& image,
6575     cl_bool blocking,
6576     const size_t<3>& origin,
6577     const size_t<3>& region,
6578     ::size_t row_pitch,
6579     ::size_t slice_pitch,
6580     void* ptr,
6581     const VECTOR_CLASS<Event>* events = NULL,
6582     Event* event = NULL)
6583 {
6584     cl_int error;
6585     CommandQueue queue = CommandQueue::getDefault(&error);
6586
6587     if (error != CL_SUCCESS) {
6588         return error;
6589     }
6590
6591     return queue.enqueueWriteImage(
6592         image,
6593         blocking,
6594         origin,
6595         region,
6596         row_pitch,
6597         slice_pitch,
6598         ptr,
6599         events, 
6600         event);
6601 }
6602
6603 inline cl_int enqueueCopyImage(
6604     const Image& src,
6605     const Image& dst,
6606     const size_t<3>& src_origin,
6607     const size_t<3>& dst_origin,
6608     const size_t<3>& region,
6609     const VECTOR_CLASS<Event>* events = NULL,
6610     Event* event = NULL)
6611 {
6612     cl_int error;
6613     CommandQueue queue = CommandQueue::getDefault(&error);
6614
6615     if (error != CL_SUCCESS) {
6616         return error;
6617     }
6618
6619     return queue.enqueueCopyImage(
6620         src,
6621         dst,
6622         src_origin,
6623         dst_origin,
6624         region,
6625         events,
6626         event);
6627 }
6628
6629 inline cl_int enqueueCopyImageToBuffer(
6630     const Image& src,
6631     const Buffer& dst,
6632     const size_t<3>& src_origin,
6633     const size_t<3>& region,
6634     ::size_t dst_offset,
6635     const VECTOR_CLASS<Event>* events = NULL,
6636     Event* event = NULL)
6637 {
6638     cl_int error;
6639     CommandQueue queue = CommandQueue::getDefault(&error);
6640
6641     if (error != CL_SUCCESS) {
6642         return error;
6643     }
6644
6645     return queue.enqueueCopyImageToBuffer(
6646         src,
6647         dst,
6648         src_origin,
6649         region,
6650         dst_offset,
6651         events,
6652         event);
6653 }
6654
6655 inline cl_int enqueueCopyBufferToImage(
6656     const Buffer& src,
6657     const Image& dst,
6658     ::size_t src_offset,
6659     const size_t<3>& dst_origin,
6660     const size_t<3>& region,
6661     const VECTOR_CLASS<Event>* events = NULL,
6662     Event* event = NULL)
6663 {
6664     cl_int error;
6665     CommandQueue queue = CommandQueue::getDefault(&error);
6666
6667     if (error != CL_SUCCESS) {
6668         return error;
6669     }
6670
6671     return queue.enqueueCopyBufferToImage(
6672         src,
6673         dst,
6674         src_offset,
6675         dst_origin,
6676         region,
6677         events,
6678         event);
6679 }
6680
6681
6682 inline cl_int flush(void)
6683 {
6684     cl_int error;
6685     CommandQueue queue = CommandQueue::getDefault(&error);
6686
6687     if (error != CL_SUCCESS) {
6688         return error;
6689     }
6690
6691     return queue.flush();
6692 }
6693
6694 inline cl_int finish(void)
6695 {
6696     cl_int error;
6697     CommandQueue queue = CommandQueue::getDefault(&error);
6698
6699     if (error != CL_SUCCESS) {
6700         return error;
6701     } 
6702
6703
6704     return queue.finish();
6705 }
6706
6707 // Kernel Functor support
6708 // New interface as of September 2011
6709 // Requires the C++11 std::tr1::function (note do not support TR1)
6710 // Visual Studio 2010 and GCC 4.2
6711
6712 struct EnqueueArgs
6713 {
6714     CommandQueue queue_;
6715     const NDRange offset_;
6716     const NDRange global_;
6717     const NDRange local_;
6718     VECTOR_CLASS<Event> events_;
6719
6720     EnqueueArgs(NDRange global) : 
6721       queue_(CommandQueue::getDefault()),
6722       offset_(NullRange), 
6723       global_(global),
6724       local_(NullRange)
6725     {
6726
6727     }
6728
6729     EnqueueArgs(NDRange global, NDRange local) : 
6730       queue_(CommandQueue::getDefault()),
6731       offset_(NullRange), 
6732       global_(global),
6733       local_(local)
6734     {
6735
6736     }
6737
6738     EnqueueArgs(NDRange offset, NDRange global, NDRange local) : 
6739       queue_(CommandQueue::getDefault()),
6740       offset_(offset), 
6741       global_(global),
6742       local_(local)
6743     {
6744
6745     }
6746
6747     EnqueueArgs(Event e, NDRange global) : 
6748       queue_(CommandQueue::getDefault()),
6749       offset_(NullRange), 
6750       global_(global),
6751       local_(NullRange)
6752     {
6753         events_.push_back(e);
6754     }
6755
6756     EnqueueArgs(Event e, NDRange global, NDRange local) : 
6757       queue_(CommandQueue::getDefault()),
6758       offset_(NullRange), 
6759       global_(global),
6760       local_(local)
6761     {
6762         events_.push_back(e);
6763     }
6764
6765     EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) : 
6766       queue_(CommandQueue::getDefault()),
6767       offset_(offset), 
6768       global_(global),
6769       local_(local)
6770     {
6771         events_.push_back(e);
6772     }
6773
6774     EnqueueArgs(const VECTOR_CLASS<Event> &events, NDRange global) : 
6775       queue_(CommandQueue::getDefault()),
6776       offset_(NullRange), 
6777       global_(global),
6778       local_(NullRange),
6779       events_(events)
6780     {
6781
6782     }
6783
6784     EnqueueArgs(const VECTOR_CLASS<Event> &events, NDRange global, NDRange local) : 
6785       queue_(CommandQueue::getDefault()),
6786       offset_(NullRange), 
6787       global_(global),
6788       local_(local),
6789       events_(events)
6790     {
6791
6792     }
6793
6794     EnqueueArgs(const VECTOR_CLASS<Event> &events, NDRange offset, NDRange global, NDRange local) : 
6795       queue_(CommandQueue::getDefault()),
6796       offset_(offset), 
6797       global_(global),
6798       local_(local),
6799       events_(events)
6800     {
6801
6802     }
6803
6804     EnqueueArgs(CommandQueue &queue, NDRange global) : 
6805       queue_(queue),
6806       offset_(NullRange), 
6807       global_(global),
6808       local_(NullRange)
6809     {
6810
6811     }
6812
6813     EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) : 
6814       queue_(queue),
6815       offset_(NullRange), 
6816       global_(global),
6817       local_(local)
6818     {
6819
6820     }
6821
6822     EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) : 
6823       queue_(queue),
6824       offset_(offset), 
6825       global_(global),
6826       local_(local)
6827     {
6828
6829     }
6830
6831     EnqueueArgs(CommandQueue &queue, Event e, NDRange global) : 
6832       queue_(queue),
6833       offset_(NullRange), 
6834       global_(global),
6835       local_(NullRange)
6836     {
6837         events_.push_back(e);
6838     }
6839
6840     EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) : 
6841       queue_(queue),
6842       offset_(NullRange), 
6843       global_(global),
6844       local_(local)
6845     {
6846         events_.push_back(e);
6847     }
6848
6849     EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) : 
6850       queue_(queue),
6851       offset_(offset), 
6852       global_(global),
6853       local_(local)
6854     {
6855         events_.push_back(e);
6856     }
6857
6858     EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS<Event> &events, NDRange global) : 
6859       queue_(queue),
6860       offset_(NullRange), 
6861       global_(global),
6862       local_(NullRange),
6863       events_(events)
6864     {
6865
6866     }
6867
6868     EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS<Event> &events, NDRange global, NDRange local) : 
6869       queue_(queue),
6870       offset_(NullRange), 
6871       global_(global),
6872       local_(local),
6873       events_(events)
6874     {
6875
6876     }
6877
6878     EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS<Event> &events, NDRange offset, NDRange global, NDRange local) : 
6879       queue_(queue),
6880       offset_(offset), 
6881       global_(global),
6882       local_(local),
6883       events_(events)
6884     {
6885
6886     }
6887 };
6888
6889 namespace detail {
6890
6891 class NullType {};
6892
6893 template<int index, typename T0>
6894 struct SetArg
6895 {
6896     static void set (Kernel kernel, T0 arg)
6897     {
6898         kernel.setArg(index, arg);
6899     }
6900 };  
6901
6902 template<int index>
6903 struct SetArg<index, NullType>
6904 {
6905     static void set (Kernel, NullType)
6906     { 
6907     }
6908 };
6909
6910 template <
6911    typename T0,   typename T1,   typename T2,   typename T3,
6912    typename T4,   typename T5,   typename T6,   typename T7,
6913    typename T8,   typename T9,   typename T10,   typename T11,
6914    typename T12,   typename T13,   typename T14,   typename T15,
6915    typename T16,   typename T17,   typename T18,   typename T19,
6916    typename T20,   typename T21,   typename T22,   typename T23,
6917    typename T24,   typename T25,   typename T26,   typename T27,
6918    typename T28,   typename T29,   typename T30,   typename T31
6919 >
6920 class KernelFunctorGlobal
6921 {
6922 private:
6923     Kernel kernel_;
6924
6925 public:
6926    KernelFunctorGlobal(
6927         Kernel kernel) :
6928             kernel_(kernel)
6929     {}
6930
6931    KernelFunctorGlobal(
6932         const Program& program,
6933         const STRING_CLASS name,
6934         cl_int * err = NULL) :
6935             kernel_(program, name.c_str(), err)
6936     {}
6937
6938     Event operator() (
6939         const EnqueueArgs& args,
6940         T0 t0,
6941         T1 t1 = NullType(),
6942         T2 t2 = NullType(),
6943         T3 t3 = NullType(),
6944         T4 t4 = NullType(),
6945         T5 t5 = NullType(),
6946         T6 t6 = NullType(),
6947         T7 t7 = NullType(),
6948         T8 t8 = NullType(),
6949         T9 t9 = NullType(),
6950         T10 t10 = NullType(),
6951         T11 t11 = NullType(),
6952         T12 t12 = NullType(),
6953         T13 t13 = NullType(),
6954         T14 t14 = NullType(),
6955         T15 t15 = NullType(),
6956         T16 t16 = NullType(),
6957         T17 t17 = NullType(),
6958         T18 t18 = NullType(),
6959         T19 t19 = NullType(),
6960         T20 t20 = NullType(),
6961         T21 t21 = NullType(),
6962         T22 t22 = NullType(),
6963         T23 t23 = NullType(),
6964         T24 t24 = NullType(),
6965         T25 t25 = NullType(),
6966         T26 t26 = NullType(),
6967         T27 t27 = NullType(),
6968         T28 t28 = NullType(),
6969         T29 t29 = NullType(),
6970         T30 t30 = NullType(),
6971         T31 t31 = NullType()
6972         )
6973     {
6974         Event event;
6975         SetArg<0, T0>::set(kernel_, t0);
6976         SetArg<1, T1>::set(kernel_, t1);
6977         SetArg<2, T2>::set(kernel_, t2);
6978         SetArg<3, T3>::set(kernel_, t3);
6979         SetArg<4, T4>::set(kernel_, t4);
6980         SetArg<5, T5>::set(kernel_, t5);
6981         SetArg<6, T6>::set(kernel_, t6);
6982         SetArg<7, T7>::set(kernel_, t7);
6983         SetArg<8, T8>::set(kernel_, t8);
6984         SetArg<9, T9>::set(kernel_, t9);
6985         SetArg<10, T10>::set(kernel_, t10);
6986         SetArg<11, T11>::set(kernel_, t11);
6987         SetArg<12, T12>::set(kernel_, t12);
6988         SetArg<13, T13>::set(kernel_, t13);
6989         SetArg<14, T14>::set(kernel_, t14);
6990         SetArg<15, T15>::set(kernel_, t15);
6991         SetArg<16, T16>::set(kernel_, t16);
6992         SetArg<17, T17>::set(kernel_, t17);
6993         SetArg<18, T18>::set(kernel_, t18);
6994         SetArg<19, T19>::set(kernel_, t19);
6995         SetArg<20, T20>::set(kernel_, t20);
6996         SetArg<21, T21>::set(kernel_, t21);
6997         SetArg<22, T22>::set(kernel_, t22);
6998         SetArg<23, T23>::set(kernel_, t23);
6999         SetArg<24, T24>::set(kernel_, t24);
7000         SetArg<25, T25>::set(kernel_, t25);
7001         SetArg<26, T26>::set(kernel_, t26);
7002         SetArg<27, T27>::set(kernel_, t27);
7003         SetArg<28, T28>::set(kernel_, t28);
7004         SetArg<29, T29>::set(kernel_, t29);
7005         SetArg<30, T30>::set(kernel_, t30);
7006         SetArg<31, T31>::set(kernel_, t31);
7007         
7008         args.queue_.enqueueNDRangeKernel(
7009             kernel_,
7010             args.offset_,
7011             args.global_,
7012             args.local_,
7013             &args.events_,
7014             &event);
7015         
7016         return event;
7017     }
7018
7019 };
7020
7021 //------------------------------------------------------------------------------------------------------
7022
7023
7024 template<
7025         typename T0,
7026         typename T1,
7027         typename T2,
7028         typename T3,
7029         typename T4,
7030         typename T5,
7031         typename T6,
7032         typename T7,
7033         typename T8,
7034         typename T9,
7035         typename T10,
7036         typename T11,
7037         typename T12,
7038         typename T13,
7039         typename T14,
7040         typename T15,
7041         typename T16,
7042         typename T17,
7043         typename T18,
7044         typename T19,
7045         typename T20,
7046         typename T21,
7047         typename T22,
7048         typename T23,
7049         typename T24,
7050         typename T25,
7051         typename T26,
7052         typename T27,
7053         typename T28,
7054         typename T29,
7055         typename T30,
7056         typename T31>
7057 struct functionImplementation_
7058 {
7059         typedef detail::KernelFunctorGlobal<
7060                 T0,
7061                 T1,
7062                 T2,
7063                 T3,
7064                 T4,
7065                 T5,
7066                 T6,
7067                 T7,
7068                 T8,
7069                 T9,
7070                 T10,
7071                 T11,
7072                 T12,
7073                 T13,
7074                 T14,
7075                 T15,
7076                 T16,
7077                 T17,
7078                 T18,
7079                 T19,
7080                 T20,
7081                 T21,
7082                 T22,
7083                 T23,
7084                 T24,
7085                 T25,
7086                 T26,
7087                 T27,
7088                 T28,
7089                 T29,
7090                 T30,
7091                 T31> FunctorType;
7092
7093     FunctorType functor_;
7094
7095     functionImplementation_(const FunctorType &functor) :
7096         functor_(functor)
7097     {
7098     
7099         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 32))
7100         // Fail variadic expansion for dev11
7101         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
7102         #endif
7103             
7104     }
7105
7106         //! \brief Return type of the functor
7107         typedef Event result_type;
7108
7109         //! \brief Function signature of kernel functor with no event dependency.
7110         typedef Event type_(
7111                 const EnqueueArgs&,
7112                 T0,
7113                 T1,
7114                 T2,
7115                 T3,
7116                 T4,
7117                 T5,
7118                 T6,
7119                 T7,
7120                 T8,
7121                 T9,
7122                 T10,
7123                 T11,
7124                 T12,
7125                 T13,
7126                 T14,
7127                 T15,
7128                 T16,
7129                 T17,
7130                 T18,
7131                 T19,
7132                 T20,
7133                 T21,
7134                 T22,
7135                 T23,
7136                 T24,
7137                 T25,
7138                 T26,
7139                 T27,
7140                 T28,
7141                 T29,
7142                 T30,
7143                 T31);
7144
7145         Event operator()(
7146                 const EnqueueArgs& enqueueArgs,
7147                 T0 arg0,
7148                 T1 arg1,
7149                 T2 arg2,
7150                 T3 arg3,
7151                 T4 arg4,
7152                 T5 arg5,
7153                 T6 arg6,
7154                 T7 arg7,
7155                 T8 arg8,
7156                 T9 arg9,
7157                 T10 arg10,
7158                 T11 arg11,
7159                 T12 arg12,
7160                 T13 arg13,
7161                 T14 arg14,
7162                 T15 arg15,
7163                 T16 arg16,
7164                 T17 arg17,
7165                 T18 arg18,
7166                 T19 arg19,
7167                 T20 arg20,
7168                 T21 arg21,
7169                 T22 arg22,
7170                 T23 arg23,
7171                 T24 arg24,
7172                 T25 arg25,
7173                 T26 arg26,
7174                 T27 arg27,
7175                 T28 arg28,
7176                 T29 arg29,
7177                 T30 arg30,
7178                 T31 arg31)
7179         {
7180                 return functor_(
7181                         enqueueArgs,
7182                         arg0,
7183                         arg1,
7184                         arg2,
7185                         arg3,
7186                         arg4,
7187                         arg5,
7188                         arg6,
7189                         arg7,
7190                         arg8,
7191                         arg9,
7192                         arg10,
7193                         arg11,
7194                         arg12,
7195                         arg13,
7196                         arg14,
7197                         arg15,
7198                         arg16,
7199                         arg17,
7200                         arg18,
7201                         arg19,
7202                         arg20,
7203                         arg21,
7204                         arg22,
7205                         arg23,
7206                         arg24,
7207                         arg25,
7208                         arg26,
7209                         arg27,
7210                         arg28,
7211                         arg29,
7212                         arg30,
7213                         arg31);
7214         }
7215
7216
7217 };
7218
7219 template<
7220         typename T0,
7221         typename T1,
7222         typename T2,
7223         typename T3,
7224         typename T4,
7225         typename T5,
7226         typename T6,
7227         typename T7,
7228         typename T8,
7229         typename T9,
7230         typename T10,
7231         typename T11,
7232         typename T12,
7233         typename T13,
7234         typename T14,
7235         typename T15,
7236         typename T16,
7237         typename T17,
7238         typename T18,
7239         typename T19,
7240         typename T20,
7241         typename T21,
7242         typename T22,
7243         typename T23,
7244         typename T24,
7245         typename T25,
7246         typename T26,
7247         typename T27,
7248         typename T28,
7249         typename T29,
7250         typename T30>
7251 struct functionImplementation_
7252 <       T0,
7253         T1,
7254         T2,
7255         T3,
7256         T4,
7257         T5,
7258         T6,
7259         T7,
7260         T8,
7261         T9,
7262         T10,
7263         T11,
7264         T12,
7265         T13,
7266         T14,
7267         T15,
7268         T16,
7269         T17,
7270         T18,
7271         T19,
7272         T20,
7273         T21,
7274         T22,
7275         T23,
7276         T24,
7277         T25,
7278         T26,
7279         T27,
7280         T28,
7281         T29,
7282         T30,
7283         NullType>
7284 {
7285         typedef detail::KernelFunctorGlobal<
7286                 T0,
7287                 T1,
7288                 T2,
7289                 T3,
7290                 T4,
7291                 T5,
7292                 T6,
7293                 T7,
7294                 T8,
7295                 T9,
7296                 T10,
7297                 T11,
7298                 T12,
7299                 T13,
7300                 T14,
7301                 T15,
7302                 T16,
7303                 T17,
7304                 T18,
7305                 T19,
7306                 T20,
7307                 T21,
7308                 T22,
7309                 T23,
7310                 T24,
7311                 T25,
7312                 T26,
7313                 T27,
7314                 T28,
7315                 T29,
7316                 T30,
7317                 NullType> FunctorType;
7318
7319     FunctorType functor_;
7320
7321     functionImplementation_(const FunctorType &functor) :
7322         functor_(functor)
7323     {
7324     
7325         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 31))
7326         // Fail variadic expansion for dev11
7327         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
7328         #endif
7329             
7330     }
7331
7332         //! \brief Return type of the functor
7333         typedef Event result_type;
7334
7335         //! \brief Function signature of kernel functor with no event dependency.
7336         typedef Event type_(
7337                 const EnqueueArgs&,
7338                 T0,
7339                 T1,
7340                 T2,
7341                 T3,
7342                 T4,
7343                 T5,
7344                 T6,
7345                 T7,
7346                 T8,
7347                 T9,
7348                 T10,
7349                 T11,
7350                 T12,
7351                 T13,
7352                 T14,
7353                 T15,
7354                 T16,
7355                 T17,
7356                 T18,
7357                 T19,
7358                 T20,
7359                 T21,
7360                 T22,
7361                 T23,
7362                 T24,
7363                 T25,
7364                 T26,
7365                 T27,
7366                 T28,
7367                 T29,
7368                 T30);
7369
7370         Event operator()(
7371                 const EnqueueArgs& enqueueArgs,
7372                 T0 arg0,
7373                 T1 arg1,
7374                 T2 arg2,
7375                 T3 arg3,
7376                 T4 arg4,
7377                 T5 arg5,
7378                 T6 arg6,
7379                 T7 arg7,
7380                 T8 arg8,
7381                 T9 arg9,
7382                 T10 arg10,
7383                 T11 arg11,
7384                 T12 arg12,
7385                 T13 arg13,
7386                 T14 arg14,
7387                 T15 arg15,
7388                 T16 arg16,
7389                 T17 arg17,
7390                 T18 arg18,
7391                 T19 arg19,
7392                 T20 arg20,
7393                 T21 arg21,
7394                 T22 arg22,
7395                 T23 arg23,
7396                 T24 arg24,
7397                 T25 arg25,
7398                 T26 arg26,
7399                 T27 arg27,
7400                 T28 arg28,
7401                 T29 arg29,
7402                 T30 arg30)
7403         {
7404                 return functor_(
7405                         enqueueArgs,
7406                         arg0,
7407                         arg1,
7408                         arg2,
7409                         arg3,
7410                         arg4,
7411                         arg5,
7412                         arg6,
7413                         arg7,
7414                         arg8,
7415                         arg9,
7416                         arg10,
7417                         arg11,
7418                         arg12,
7419                         arg13,
7420                         arg14,
7421                         arg15,
7422                         arg16,
7423                         arg17,
7424                         arg18,
7425                         arg19,
7426                         arg20,
7427                         arg21,
7428                         arg22,
7429                         arg23,
7430                         arg24,
7431                         arg25,
7432                         arg26,
7433                         arg27,
7434                         arg28,
7435                         arg29,
7436                         arg30);
7437         }
7438
7439
7440 };
7441
7442 template<
7443         typename T0,
7444         typename T1,
7445         typename T2,
7446         typename T3,
7447         typename T4,
7448         typename T5,
7449         typename T6,
7450         typename T7,
7451         typename T8,
7452         typename T9,
7453         typename T10,
7454         typename T11,
7455         typename T12,
7456         typename T13,
7457         typename T14,
7458         typename T15,
7459         typename T16,
7460         typename T17,
7461         typename T18,
7462         typename T19,
7463         typename T20,
7464         typename T21,
7465         typename T22,
7466         typename T23,
7467         typename T24,
7468         typename T25,
7469         typename T26,
7470         typename T27,
7471         typename T28,
7472         typename T29>
7473 struct functionImplementation_
7474 <       T0,
7475         T1,
7476         T2,
7477         T3,
7478         T4,
7479         T5,
7480         T6,
7481         T7,
7482         T8,
7483         T9,
7484         T10,
7485         T11,
7486         T12,
7487         T13,
7488         T14,
7489         T15,
7490         T16,
7491         T17,
7492         T18,
7493         T19,
7494         T20,
7495         T21,
7496         T22,
7497         T23,
7498         T24,
7499         T25,
7500         T26,
7501         T27,
7502         T28,
7503         T29,
7504         NullType,
7505         NullType>
7506 {
7507         typedef detail::KernelFunctorGlobal<
7508                 T0,
7509                 T1,
7510                 T2,
7511                 T3,
7512                 T4,
7513                 T5,
7514                 T6,
7515                 T7,
7516                 T8,
7517                 T9,
7518                 T10,
7519                 T11,
7520                 T12,
7521                 T13,
7522                 T14,
7523                 T15,
7524                 T16,
7525                 T17,
7526                 T18,
7527                 T19,
7528                 T20,
7529                 T21,
7530                 T22,
7531                 T23,
7532                 T24,
7533                 T25,
7534                 T26,
7535                 T27,
7536                 T28,
7537                 T29,
7538                 NullType,
7539                 NullType> FunctorType;
7540
7541     FunctorType functor_;
7542
7543     functionImplementation_(const FunctorType &functor) :
7544         functor_(functor)
7545     {
7546     
7547         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 30))
7548         // Fail variadic expansion for dev11
7549         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
7550         #endif
7551             
7552     }
7553
7554         //! \brief Return type of the functor
7555         typedef Event result_type;
7556
7557         //! \brief Function signature of kernel functor with no event dependency.
7558         typedef Event type_(
7559                 const EnqueueArgs&,
7560                 T0,
7561                 T1,
7562                 T2,
7563                 T3,
7564                 T4,
7565                 T5,
7566                 T6,
7567                 T7,
7568                 T8,
7569                 T9,
7570                 T10,
7571                 T11,
7572                 T12,
7573                 T13,
7574                 T14,
7575                 T15,
7576                 T16,
7577                 T17,
7578                 T18,
7579                 T19,
7580                 T20,
7581                 T21,
7582                 T22,
7583                 T23,
7584                 T24,
7585                 T25,
7586                 T26,
7587                 T27,
7588                 T28,
7589                 T29);
7590
7591         Event operator()(
7592                 const EnqueueArgs& enqueueArgs,
7593                 T0 arg0,
7594                 T1 arg1,
7595                 T2 arg2,
7596                 T3 arg3,
7597                 T4 arg4,
7598                 T5 arg5,
7599                 T6 arg6,
7600                 T7 arg7,
7601                 T8 arg8,
7602                 T9 arg9,
7603                 T10 arg10,
7604                 T11 arg11,
7605                 T12 arg12,
7606                 T13 arg13,
7607                 T14 arg14,
7608                 T15 arg15,
7609                 T16 arg16,
7610                 T17 arg17,
7611                 T18 arg18,
7612                 T19 arg19,
7613                 T20 arg20,
7614                 T21 arg21,
7615                 T22 arg22,
7616                 T23 arg23,
7617                 T24 arg24,
7618                 T25 arg25,
7619                 T26 arg26,
7620                 T27 arg27,
7621                 T28 arg28,
7622                 T29 arg29)
7623         {
7624                 return functor_(
7625                         enqueueArgs,
7626                         arg0,
7627                         arg1,
7628                         arg2,
7629                         arg3,
7630                         arg4,
7631                         arg5,
7632                         arg6,
7633                         arg7,
7634                         arg8,
7635                         arg9,
7636                         arg10,
7637                         arg11,
7638                         arg12,
7639                         arg13,
7640                         arg14,
7641                         arg15,
7642                         arg16,
7643                         arg17,
7644                         arg18,
7645                         arg19,
7646                         arg20,
7647                         arg21,
7648                         arg22,
7649                         arg23,
7650                         arg24,
7651                         arg25,
7652                         arg26,
7653                         arg27,
7654                         arg28,
7655                         arg29);
7656         }
7657
7658
7659 };
7660
7661 template<
7662         typename T0,
7663         typename T1,
7664         typename T2,
7665         typename T3,
7666         typename T4,
7667         typename T5,
7668         typename T6,
7669         typename T7,
7670         typename T8,
7671         typename T9,
7672         typename T10,
7673         typename T11,
7674         typename T12,
7675         typename T13,
7676         typename T14,
7677         typename T15,
7678         typename T16,
7679         typename T17,
7680         typename T18,
7681         typename T19,
7682         typename T20,
7683         typename T21,
7684         typename T22,
7685         typename T23,
7686         typename T24,
7687         typename T25,
7688         typename T26,
7689         typename T27,
7690         typename T28>
7691 struct functionImplementation_
7692 <       T0,
7693         T1,
7694         T2,
7695         T3,
7696         T4,
7697         T5,
7698         T6,
7699         T7,
7700         T8,
7701         T9,
7702         T10,
7703         T11,
7704         T12,
7705         T13,
7706         T14,
7707         T15,
7708         T16,
7709         T17,
7710         T18,
7711         T19,
7712         T20,
7713         T21,
7714         T22,
7715         T23,
7716         T24,
7717         T25,
7718         T26,
7719         T27,
7720         T28,
7721         NullType,
7722         NullType,
7723         NullType>
7724 {
7725         typedef detail::KernelFunctorGlobal<
7726                 T0,
7727                 T1,
7728                 T2,
7729                 T3,
7730                 T4,
7731                 T5,
7732                 T6,
7733                 T7,
7734                 T8,
7735                 T9,
7736                 T10,
7737                 T11,
7738                 T12,
7739                 T13,
7740                 T14,
7741                 T15,
7742                 T16,
7743                 T17,
7744                 T18,
7745                 T19,
7746                 T20,
7747                 T21,
7748                 T22,
7749                 T23,
7750                 T24,
7751                 T25,
7752                 T26,
7753                 T27,
7754                 T28,
7755                 NullType,
7756                 NullType,
7757                 NullType> FunctorType;
7758
7759     FunctorType functor_;
7760
7761     functionImplementation_(const FunctorType &functor) :
7762         functor_(functor)
7763     {
7764     
7765         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 29))
7766         // Fail variadic expansion for dev11
7767         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
7768         #endif
7769             
7770     }
7771
7772         //! \brief Return type of the functor
7773         typedef Event result_type;
7774
7775         //! \brief Function signature of kernel functor with no event dependency.
7776         typedef Event type_(
7777                 const EnqueueArgs&,
7778                 T0,
7779                 T1,
7780                 T2,
7781                 T3,
7782                 T4,
7783                 T5,
7784                 T6,
7785                 T7,
7786                 T8,
7787                 T9,
7788                 T10,
7789                 T11,
7790                 T12,
7791                 T13,
7792                 T14,
7793                 T15,
7794                 T16,
7795                 T17,
7796                 T18,
7797                 T19,
7798                 T20,
7799                 T21,
7800                 T22,
7801                 T23,
7802                 T24,
7803                 T25,
7804                 T26,
7805                 T27,
7806                 T28);
7807
7808         Event operator()(
7809                 const EnqueueArgs& enqueueArgs,
7810                 T0 arg0,
7811                 T1 arg1,
7812                 T2 arg2,
7813                 T3 arg3,
7814                 T4 arg4,
7815                 T5 arg5,
7816                 T6 arg6,
7817                 T7 arg7,
7818                 T8 arg8,
7819                 T9 arg9,
7820                 T10 arg10,
7821                 T11 arg11,
7822                 T12 arg12,
7823                 T13 arg13,
7824                 T14 arg14,
7825                 T15 arg15,
7826                 T16 arg16,
7827                 T17 arg17,
7828                 T18 arg18,
7829                 T19 arg19,
7830                 T20 arg20,
7831                 T21 arg21,
7832                 T22 arg22,
7833                 T23 arg23,
7834                 T24 arg24,
7835                 T25 arg25,
7836                 T26 arg26,
7837                 T27 arg27,
7838                 T28 arg28)
7839         {
7840                 return functor_(
7841                         enqueueArgs,
7842                         arg0,
7843                         arg1,
7844                         arg2,
7845                         arg3,
7846                         arg4,
7847                         arg5,
7848                         arg6,
7849                         arg7,
7850                         arg8,
7851                         arg9,
7852                         arg10,
7853                         arg11,
7854                         arg12,
7855                         arg13,
7856                         arg14,
7857                         arg15,
7858                         arg16,
7859                         arg17,
7860                         arg18,
7861                         arg19,
7862                         arg20,
7863                         arg21,
7864                         arg22,
7865                         arg23,
7866                         arg24,
7867                         arg25,
7868                         arg26,
7869                         arg27,
7870                         arg28);
7871         }
7872
7873
7874 };
7875
7876 template<
7877         typename T0,
7878         typename T1,
7879         typename T2,
7880         typename T3,
7881         typename T4,
7882         typename T5,
7883         typename T6,
7884         typename T7,
7885         typename T8,
7886         typename T9,
7887         typename T10,
7888         typename T11,
7889         typename T12,
7890         typename T13,
7891         typename T14,
7892         typename T15,
7893         typename T16,
7894         typename T17,
7895         typename T18,
7896         typename T19,
7897         typename T20,
7898         typename T21,
7899         typename T22,
7900         typename T23,
7901         typename T24,
7902         typename T25,
7903         typename T26,
7904         typename T27>
7905 struct functionImplementation_
7906 <       T0,
7907         T1,
7908         T2,
7909         T3,
7910         T4,
7911         T5,
7912         T6,
7913         T7,
7914         T8,
7915         T9,
7916         T10,
7917         T11,
7918         T12,
7919         T13,
7920         T14,
7921         T15,
7922         T16,
7923         T17,
7924         T18,
7925         T19,
7926         T20,
7927         T21,
7928         T22,
7929         T23,
7930         T24,
7931         T25,
7932         T26,
7933         T27,
7934         NullType,
7935         NullType,
7936         NullType,
7937         NullType>
7938 {
7939         typedef detail::KernelFunctorGlobal<
7940                 T0,
7941                 T1,
7942                 T2,
7943                 T3,
7944                 T4,
7945                 T5,
7946                 T6,
7947                 T7,
7948                 T8,
7949                 T9,
7950                 T10,
7951                 T11,
7952                 T12,
7953                 T13,
7954                 T14,
7955                 T15,
7956                 T16,
7957                 T17,
7958                 T18,
7959                 T19,
7960                 T20,
7961                 T21,
7962                 T22,
7963                 T23,
7964                 T24,
7965                 T25,
7966                 T26,
7967                 T27,
7968                 NullType,
7969                 NullType,
7970                 NullType,
7971                 NullType> FunctorType;
7972
7973     FunctorType functor_;
7974
7975     functionImplementation_(const FunctorType &functor) :
7976         functor_(functor)
7977     {
7978     
7979         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 28))
7980         // Fail variadic expansion for dev11
7981         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
7982         #endif
7983             
7984     }
7985
7986         //! \brief Return type of the functor
7987         typedef Event result_type;
7988
7989         //! \brief Function signature of kernel functor with no event dependency.
7990         typedef Event type_(
7991                 const EnqueueArgs&,
7992                 T0,
7993                 T1,
7994                 T2,
7995                 T3,
7996                 T4,
7997                 T5,
7998                 T6,
7999                 T7,
8000                 T8,
8001                 T9,
8002                 T10,
8003                 T11,
8004                 T12,
8005                 T13,
8006                 T14,
8007                 T15,
8008                 T16,
8009                 T17,
8010                 T18,
8011                 T19,
8012                 T20,
8013                 T21,
8014                 T22,
8015                 T23,
8016                 T24,
8017                 T25,
8018                 T26,
8019                 T27);
8020
8021         Event operator()(
8022                 const EnqueueArgs& enqueueArgs,
8023                 T0 arg0,
8024                 T1 arg1,
8025                 T2 arg2,
8026                 T3 arg3,
8027                 T4 arg4,
8028                 T5 arg5,
8029                 T6 arg6,
8030                 T7 arg7,
8031                 T8 arg8,
8032                 T9 arg9,
8033                 T10 arg10,
8034                 T11 arg11,
8035                 T12 arg12,
8036                 T13 arg13,
8037                 T14 arg14,
8038                 T15 arg15,
8039                 T16 arg16,
8040                 T17 arg17,
8041                 T18 arg18,
8042                 T19 arg19,
8043                 T20 arg20,
8044                 T21 arg21,
8045                 T22 arg22,
8046                 T23 arg23,
8047                 T24 arg24,
8048                 T25 arg25,
8049                 T26 arg26,
8050                 T27 arg27)
8051         {
8052                 return functor_(
8053                         enqueueArgs,
8054                         arg0,
8055                         arg1,
8056                         arg2,
8057                         arg3,
8058                         arg4,
8059                         arg5,
8060                         arg6,
8061                         arg7,
8062                         arg8,
8063                         arg9,
8064                         arg10,
8065                         arg11,
8066                         arg12,
8067                         arg13,
8068                         arg14,
8069                         arg15,
8070                         arg16,
8071                         arg17,
8072                         arg18,
8073                         arg19,
8074                         arg20,
8075                         arg21,
8076                         arg22,
8077                         arg23,
8078                         arg24,
8079                         arg25,
8080                         arg26,
8081                         arg27);
8082         }
8083
8084
8085 };
8086
8087 template<
8088         typename T0,
8089         typename T1,
8090         typename T2,
8091         typename T3,
8092         typename T4,
8093         typename T5,
8094         typename T6,
8095         typename T7,
8096         typename T8,
8097         typename T9,
8098         typename T10,
8099         typename T11,
8100         typename T12,
8101         typename T13,
8102         typename T14,
8103         typename T15,
8104         typename T16,
8105         typename T17,
8106         typename T18,
8107         typename T19,
8108         typename T20,
8109         typename T21,
8110         typename T22,
8111         typename T23,
8112         typename T24,
8113         typename T25,
8114         typename T26>
8115 struct functionImplementation_
8116 <       T0,
8117         T1,
8118         T2,
8119         T3,
8120         T4,
8121         T5,
8122         T6,
8123         T7,
8124         T8,
8125         T9,
8126         T10,
8127         T11,
8128         T12,
8129         T13,
8130         T14,
8131         T15,
8132         T16,
8133         T17,
8134         T18,
8135         T19,
8136         T20,
8137         T21,
8138         T22,
8139         T23,
8140         T24,
8141         T25,
8142         T26,
8143         NullType,
8144         NullType,
8145         NullType,
8146         NullType,
8147         NullType>
8148 {
8149         typedef detail::KernelFunctorGlobal<
8150                 T0,
8151                 T1,
8152                 T2,
8153                 T3,
8154                 T4,
8155                 T5,
8156                 T6,
8157                 T7,
8158                 T8,
8159                 T9,
8160                 T10,
8161                 T11,
8162                 T12,
8163                 T13,
8164                 T14,
8165                 T15,
8166                 T16,
8167                 T17,
8168                 T18,
8169                 T19,
8170                 T20,
8171                 T21,
8172                 T22,
8173                 T23,
8174                 T24,
8175                 T25,
8176                 T26,
8177                 NullType,
8178                 NullType,
8179                 NullType,
8180                 NullType,
8181                 NullType> FunctorType;
8182
8183     FunctorType functor_;
8184
8185     functionImplementation_(const FunctorType &functor) :
8186         functor_(functor)
8187     {
8188     
8189         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 27))
8190         // Fail variadic expansion for dev11
8191         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
8192         #endif
8193             
8194     }
8195
8196         //! \brief Return type of the functor
8197         typedef Event result_type;
8198
8199         //! \brief Function signature of kernel functor with no event dependency.
8200         typedef Event type_(
8201                 const EnqueueArgs&,
8202                 T0,
8203                 T1,
8204                 T2,
8205                 T3,
8206                 T4,
8207                 T5,
8208                 T6,
8209                 T7,
8210                 T8,
8211                 T9,
8212                 T10,
8213                 T11,
8214                 T12,
8215                 T13,
8216                 T14,
8217                 T15,
8218                 T16,
8219                 T17,
8220                 T18,
8221                 T19,
8222                 T20,
8223                 T21,
8224                 T22,
8225                 T23,
8226                 T24,
8227                 T25,
8228                 T26);
8229
8230         Event operator()(
8231                 const EnqueueArgs& enqueueArgs,
8232                 T0 arg0,
8233                 T1 arg1,
8234                 T2 arg2,
8235                 T3 arg3,
8236                 T4 arg4,
8237                 T5 arg5,
8238                 T6 arg6,
8239                 T7 arg7,
8240                 T8 arg8,
8241                 T9 arg9,
8242                 T10 arg10,
8243                 T11 arg11,
8244                 T12 arg12,
8245                 T13 arg13,
8246                 T14 arg14,
8247                 T15 arg15,
8248                 T16 arg16,
8249                 T17 arg17,
8250                 T18 arg18,
8251                 T19 arg19,
8252                 T20 arg20,
8253                 T21 arg21,
8254                 T22 arg22,
8255                 T23 arg23,
8256                 T24 arg24,
8257                 T25 arg25,
8258                 T26 arg26)
8259         {
8260                 return functor_(
8261                         enqueueArgs,
8262                         arg0,
8263                         arg1,
8264                         arg2,
8265                         arg3,
8266                         arg4,
8267                         arg5,
8268                         arg6,
8269                         arg7,
8270                         arg8,
8271                         arg9,
8272                         arg10,
8273                         arg11,
8274                         arg12,
8275                         arg13,
8276                         arg14,
8277                         arg15,
8278                         arg16,
8279                         arg17,
8280                         arg18,
8281                         arg19,
8282                         arg20,
8283                         arg21,
8284                         arg22,
8285                         arg23,
8286                         arg24,
8287                         arg25,
8288                         arg26);
8289         }
8290
8291
8292 };
8293
8294 template<
8295         typename T0,
8296         typename T1,
8297         typename T2,
8298         typename T3,
8299         typename T4,
8300         typename T5,
8301         typename T6,
8302         typename T7,
8303         typename T8,
8304         typename T9,
8305         typename T10,
8306         typename T11,
8307         typename T12,
8308         typename T13,
8309         typename T14,
8310         typename T15,
8311         typename T16,
8312         typename T17,
8313         typename T18,
8314         typename T19,
8315         typename T20,
8316         typename T21,
8317         typename T22,
8318         typename T23,
8319         typename T24,
8320         typename T25>
8321 struct functionImplementation_
8322 <       T0,
8323         T1,
8324         T2,
8325         T3,
8326         T4,
8327         T5,
8328         T6,
8329         T7,
8330         T8,
8331         T9,
8332         T10,
8333         T11,
8334         T12,
8335         T13,
8336         T14,
8337         T15,
8338         T16,
8339         T17,
8340         T18,
8341         T19,
8342         T20,
8343         T21,
8344         T22,
8345         T23,
8346         T24,
8347         T25,
8348         NullType,
8349         NullType,
8350         NullType,
8351         NullType,
8352         NullType,
8353         NullType>
8354 {
8355         typedef detail::KernelFunctorGlobal<
8356                 T0,
8357                 T1,
8358                 T2,
8359                 T3,
8360                 T4,
8361                 T5,
8362                 T6,
8363                 T7,
8364                 T8,
8365                 T9,
8366                 T10,
8367                 T11,
8368                 T12,
8369                 T13,
8370                 T14,
8371                 T15,
8372                 T16,
8373                 T17,
8374                 T18,
8375                 T19,
8376                 T20,
8377                 T21,
8378                 T22,
8379                 T23,
8380                 T24,
8381                 T25,
8382                 NullType,
8383                 NullType,
8384                 NullType,
8385                 NullType,
8386                 NullType,
8387                 NullType> FunctorType;
8388
8389     FunctorType functor_;
8390
8391     functionImplementation_(const FunctorType &functor) :
8392         functor_(functor)
8393     {
8394     
8395         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 26))
8396         // Fail variadic expansion for dev11
8397         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
8398         #endif
8399             
8400     }
8401
8402         //! \brief Return type of the functor
8403         typedef Event result_type;
8404
8405         //! \brief Function signature of kernel functor with no event dependency.
8406         typedef Event type_(
8407                 const EnqueueArgs&,
8408                 T0,
8409                 T1,
8410                 T2,
8411                 T3,
8412                 T4,
8413                 T5,
8414                 T6,
8415                 T7,
8416                 T8,
8417                 T9,
8418                 T10,
8419                 T11,
8420                 T12,
8421                 T13,
8422                 T14,
8423                 T15,
8424                 T16,
8425                 T17,
8426                 T18,
8427                 T19,
8428                 T20,
8429                 T21,
8430                 T22,
8431                 T23,
8432                 T24,
8433                 T25);
8434
8435         Event operator()(
8436                 const EnqueueArgs& enqueueArgs,
8437                 T0 arg0,
8438                 T1 arg1,
8439                 T2 arg2,
8440                 T3 arg3,
8441                 T4 arg4,
8442                 T5 arg5,
8443                 T6 arg6,
8444                 T7 arg7,
8445                 T8 arg8,
8446                 T9 arg9,
8447                 T10 arg10,
8448                 T11 arg11,
8449                 T12 arg12,
8450                 T13 arg13,
8451                 T14 arg14,
8452                 T15 arg15,
8453                 T16 arg16,
8454                 T17 arg17,
8455                 T18 arg18,
8456                 T19 arg19,
8457                 T20 arg20,
8458                 T21 arg21,
8459                 T22 arg22,
8460                 T23 arg23,
8461                 T24 arg24,
8462                 T25 arg25)
8463         {
8464                 return functor_(
8465                         enqueueArgs,
8466                         arg0,
8467                         arg1,
8468                         arg2,
8469                         arg3,
8470                         arg4,
8471                         arg5,
8472                         arg6,
8473                         arg7,
8474                         arg8,
8475                         arg9,
8476                         arg10,
8477                         arg11,
8478                         arg12,
8479                         arg13,
8480                         arg14,
8481                         arg15,
8482                         arg16,
8483                         arg17,
8484                         arg18,
8485                         arg19,
8486                         arg20,
8487                         arg21,
8488                         arg22,
8489                         arg23,
8490                         arg24,
8491                         arg25);
8492         }
8493
8494
8495 };
8496
8497 template<
8498         typename T0,
8499         typename T1,
8500         typename T2,
8501         typename T3,
8502         typename T4,
8503         typename T5,
8504         typename T6,
8505         typename T7,
8506         typename T8,
8507         typename T9,
8508         typename T10,
8509         typename T11,
8510         typename T12,
8511         typename T13,
8512         typename T14,
8513         typename T15,
8514         typename T16,
8515         typename T17,
8516         typename T18,
8517         typename T19,
8518         typename T20,
8519         typename T21,
8520         typename T22,
8521         typename T23,
8522         typename T24>
8523 struct functionImplementation_
8524 <       T0,
8525         T1,
8526         T2,
8527         T3,
8528         T4,
8529         T5,
8530         T6,
8531         T7,
8532         T8,
8533         T9,
8534         T10,
8535         T11,
8536         T12,
8537         T13,
8538         T14,
8539         T15,
8540         T16,
8541         T17,
8542         T18,
8543         T19,
8544         T20,
8545         T21,
8546         T22,
8547         T23,
8548         T24,
8549         NullType,
8550         NullType,
8551         NullType,
8552         NullType,
8553         NullType,
8554         NullType,
8555         NullType>
8556 {
8557         typedef detail::KernelFunctorGlobal<
8558                 T0,
8559                 T1,
8560                 T2,
8561                 T3,
8562                 T4,
8563                 T5,
8564                 T6,
8565                 T7,
8566                 T8,
8567                 T9,
8568                 T10,
8569                 T11,
8570                 T12,
8571                 T13,
8572                 T14,
8573                 T15,
8574                 T16,
8575                 T17,
8576                 T18,
8577                 T19,
8578                 T20,
8579                 T21,
8580                 T22,
8581                 T23,
8582                 T24,
8583                 NullType,
8584                 NullType,
8585                 NullType,
8586                 NullType,
8587                 NullType,
8588                 NullType,
8589                 NullType> FunctorType;
8590
8591     FunctorType functor_;
8592
8593     functionImplementation_(const FunctorType &functor) :
8594         functor_(functor)
8595     {
8596     
8597         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 25))
8598         // Fail variadic expansion for dev11
8599         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
8600         #endif
8601             
8602     }
8603
8604         //! \brief Return type of the functor
8605         typedef Event result_type;
8606
8607         //! \brief Function signature of kernel functor with no event dependency.
8608         typedef Event type_(
8609                 const EnqueueArgs&,
8610                 T0,
8611                 T1,
8612                 T2,
8613                 T3,
8614                 T4,
8615                 T5,
8616                 T6,
8617                 T7,
8618                 T8,
8619                 T9,
8620                 T10,
8621                 T11,
8622                 T12,
8623                 T13,
8624                 T14,
8625                 T15,
8626                 T16,
8627                 T17,
8628                 T18,
8629                 T19,
8630                 T20,
8631                 T21,
8632                 T22,
8633                 T23,
8634                 T24);
8635
8636         Event operator()(
8637                 const EnqueueArgs& enqueueArgs,
8638                 T0 arg0,
8639                 T1 arg1,
8640                 T2 arg2,
8641                 T3 arg3,
8642                 T4 arg4,
8643                 T5 arg5,
8644                 T6 arg6,
8645                 T7 arg7,
8646                 T8 arg8,
8647                 T9 arg9,
8648                 T10 arg10,
8649                 T11 arg11,
8650                 T12 arg12,
8651                 T13 arg13,
8652                 T14 arg14,
8653                 T15 arg15,
8654                 T16 arg16,
8655                 T17 arg17,
8656                 T18 arg18,
8657                 T19 arg19,
8658                 T20 arg20,
8659                 T21 arg21,
8660                 T22 arg22,
8661                 T23 arg23,
8662                 T24 arg24)
8663         {
8664                 return functor_(
8665                         enqueueArgs,
8666                         arg0,
8667                         arg1,
8668                         arg2,
8669                         arg3,
8670                         arg4,
8671                         arg5,
8672                         arg6,
8673                         arg7,
8674                         arg8,
8675                         arg9,
8676                         arg10,
8677                         arg11,
8678                         arg12,
8679                         arg13,
8680                         arg14,
8681                         arg15,
8682                         arg16,
8683                         arg17,
8684                         arg18,
8685                         arg19,
8686                         arg20,
8687                         arg21,
8688                         arg22,
8689                         arg23,
8690                         arg24);
8691         }
8692
8693
8694 };
8695
8696 template<
8697         typename T0,
8698         typename T1,
8699         typename T2,
8700         typename T3,
8701         typename T4,
8702         typename T5,
8703         typename T6,
8704         typename T7,
8705         typename T8,
8706         typename T9,
8707         typename T10,
8708         typename T11,
8709         typename T12,
8710         typename T13,
8711         typename T14,
8712         typename T15,
8713         typename T16,
8714         typename T17,
8715         typename T18,
8716         typename T19,
8717         typename T20,
8718         typename T21,
8719         typename T22,
8720         typename T23>
8721 struct functionImplementation_
8722 <       T0,
8723         T1,
8724         T2,
8725         T3,
8726         T4,
8727         T5,
8728         T6,
8729         T7,
8730         T8,
8731         T9,
8732         T10,
8733         T11,
8734         T12,
8735         T13,
8736         T14,
8737         T15,
8738         T16,
8739         T17,
8740         T18,
8741         T19,
8742         T20,
8743         T21,
8744         T22,
8745         T23,
8746         NullType,
8747         NullType,
8748         NullType,
8749         NullType,
8750         NullType,
8751         NullType,
8752         NullType,
8753         NullType>
8754 {
8755         typedef detail::KernelFunctorGlobal<
8756                 T0,
8757                 T1,
8758                 T2,
8759                 T3,
8760                 T4,
8761                 T5,
8762                 T6,
8763                 T7,
8764                 T8,
8765                 T9,
8766                 T10,
8767                 T11,
8768                 T12,
8769                 T13,
8770                 T14,
8771                 T15,
8772                 T16,
8773                 T17,
8774                 T18,
8775                 T19,
8776                 T20,
8777                 T21,
8778                 T22,
8779                 T23,
8780                 NullType,
8781                 NullType,
8782                 NullType,
8783                 NullType,
8784                 NullType,
8785                 NullType,
8786                 NullType,
8787                 NullType> FunctorType;
8788
8789     FunctorType functor_;
8790
8791     functionImplementation_(const FunctorType &functor) :
8792         functor_(functor)
8793     {
8794     
8795         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 24))
8796         // Fail variadic expansion for dev11
8797         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
8798         #endif
8799             
8800     }
8801
8802         //! \brief Return type of the functor
8803         typedef Event result_type;
8804
8805         //! \brief Function signature of kernel functor with no event dependency.
8806         typedef Event type_(
8807                 const EnqueueArgs&,
8808                 T0,
8809                 T1,
8810                 T2,
8811                 T3,
8812                 T4,
8813                 T5,
8814                 T6,
8815                 T7,
8816                 T8,
8817                 T9,
8818                 T10,
8819                 T11,
8820                 T12,
8821                 T13,
8822                 T14,
8823                 T15,
8824                 T16,
8825                 T17,
8826                 T18,
8827                 T19,
8828                 T20,
8829                 T21,
8830                 T22,
8831                 T23);
8832
8833         Event operator()(
8834                 const EnqueueArgs& enqueueArgs,
8835                 T0 arg0,
8836                 T1 arg1,
8837                 T2 arg2,
8838                 T3 arg3,
8839                 T4 arg4,
8840                 T5 arg5,
8841                 T6 arg6,
8842                 T7 arg7,
8843                 T8 arg8,
8844                 T9 arg9,
8845                 T10 arg10,
8846                 T11 arg11,
8847                 T12 arg12,
8848                 T13 arg13,
8849                 T14 arg14,
8850                 T15 arg15,
8851                 T16 arg16,
8852                 T17 arg17,
8853                 T18 arg18,
8854                 T19 arg19,
8855                 T20 arg20,
8856                 T21 arg21,
8857                 T22 arg22,
8858                 T23 arg23)
8859         {
8860                 return functor_(
8861                         enqueueArgs,
8862                         arg0,
8863                         arg1,
8864                         arg2,
8865                         arg3,
8866                         arg4,
8867                         arg5,
8868                         arg6,
8869                         arg7,
8870                         arg8,
8871                         arg9,
8872                         arg10,
8873                         arg11,
8874                         arg12,
8875                         arg13,
8876                         arg14,
8877                         arg15,
8878                         arg16,
8879                         arg17,
8880                         arg18,
8881                         arg19,
8882                         arg20,
8883                         arg21,
8884                         arg22,
8885                         arg23);
8886         }
8887
8888
8889 };
8890
8891 template<
8892         typename T0,
8893         typename T1,
8894         typename T2,
8895         typename T3,
8896         typename T4,
8897         typename T5,
8898         typename T6,
8899         typename T7,
8900         typename T8,
8901         typename T9,
8902         typename T10,
8903         typename T11,
8904         typename T12,
8905         typename T13,
8906         typename T14,
8907         typename T15,
8908         typename T16,
8909         typename T17,
8910         typename T18,
8911         typename T19,
8912         typename T20,
8913         typename T21,
8914         typename T22>
8915 struct functionImplementation_
8916 <       T0,
8917         T1,
8918         T2,
8919         T3,
8920         T4,
8921         T5,
8922         T6,
8923         T7,
8924         T8,
8925         T9,
8926         T10,
8927         T11,
8928         T12,
8929         T13,
8930         T14,
8931         T15,
8932         T16,
8933         T17,
8934         T18,
8935         T19,
8936         T20,
8937         T21,
8938         T22,
8939         NullType,
8940         NullType,
8941         NullType,
8942         NullType,
8943         NullType,
8944         NullType,
8945         NullType,
8946         NullType,
8947         NullType>
8948 {
8949         typedef detail::KernelFunctorGlobal<
8950                 T0,
8951                 T1,
8952                 T2,
8953                 T3,
8954                 T4,
8955                 T5,
8956                 T6,
8957                 T7,
8958                 T8,
8959                 T9,
8960                 T10,
8961                 T11,
8962                 T12,
8963                 T13,
8964                 T14,
8965                 T15,
8966                 T16,
8967                 T17,
8968                 T18,
8969                 T19,
8970                 T20,
8971                 T21,
8972                 T22,
8973                 NullType,
8974                 NullType,
8975                 NullType,
8976                 NullType,
8977                 NullType,
8978                 NullType,
8979                 NullType,
8980                 NullType,
8981                 NullType> FunctorType;
8982
8983     FunctorType functor_;
8984
8985     functionImplementation_(const FunctorType &functor) :
8986         functor_(functor)
8987     {
8988     
8989         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 23))
8990         // Fail variadic expansion for dev11
8991         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
8992         #endif
8993             
8994     }
8995
8996         //! \brief Return type of the functor
8997         typedef Event result_type;
8998
8999         //! \brief Function signature of kernel functor with no event dependency.
9000         typedef Event type_(
9001                 const EnqueueArgs&,
9002                 T0,
9003                 T1,
9004                 T2,
9005                 T3,
9006                 T4,
9007                 T5,
9008                 T6,
9009                 T7,
9010                 T8,
9011                 T9,
9012                 T10,
9013                 T11,
9014                 T12,
9015                 T13,
9016                 T14,
9017                 T15,
9018                 T16,
9019                 T17,
9020                 T18,
9021                 T19,
9022                 T20,
9023                 T21,
9024                 T22);
9025
9026         Event operator()(
9027                 const EnqueueArgs& enqueueArgs,
9028                 T0 arg0,
9029                 T1 arg1,
9030                 T2 arg2,
9031                 T3 arg3,
9032                 T4 arg4,
9033                 T5 arg5,
9034                 T6 arg6,
9035                 T7 arg7,
9036                 T8 arg8,
9037                 T9 arg9,
9038                 T10 arg10,
9039                 T11 arg11,
9040                 T12 arg12,
9041                 T13 arg13,
9042                 T14 arg14,
9043                 T15 arg15,
9044                 T16 arg16,
9045                 T17 arg17,
9046                 T18 arg18,
9047                 T19 arg19,
9048                 T20 arg20,
9049                 T21 arg21,
9050                 T22 arg22)
9051         {
9052                 return functor_(
9053                         enqueueArgs,
9054                         arg0,
9055                         arg1,
9056                         arg2,
9057                         arg3,
9058                         arg4,
9059                         arg5,
9060                         arg6,
9061                         arg7,
9062                         arg8,
9063                         arg9,
9064                         arg10,
9065                         arg11,
9066                         arg12,
9067                         arg13,
9068                         arg14,
9069                         arg15,
9070                         arg16,
9071                         arg17,
9072                         arg18,
9073                         arg19,
9074                         arg20,
9075                         arg21,
9076                         arg22);
9077         }
9078
9079
9080 };
9081
9082 template<
9083         typename T0,
9084         typename T1,
9085         typename T2,
9086         typename T3,
9087         typename T4,
9088         typename T5,
9089         typename T6,
9090         typename T7,
9091         typename T8,
9092         typename T9,
9093         typename T10,
9094         typename T11,
9095         typename T12,
9096         typename T13,
9097         typename T14,
9098         typename T15,
9099         typename T16,
9100         typename T17,
9101         typename T18,
9102         typename T19,
9103         typename T20,
9104         typename T21>
9105 struct functionImplementation_
9106 <       T0,
9107         T1,
9108         T2,
9109         T3,
9110         T4,
9111         T5,
9112         T6,
9113         T7,
9114         T8,
9115         T9,
9116         T10,
9117         T11,
9118         T12,
9119         T13,
9120         T14,
9121         T15,
9122         T16,
9123         T17,
9124         T18,
9125         T19,
9126         T20,
9127         T21,
9128         NullType,
9129         NullType,
9130         NullType,
9131         NullType,
9132         NullType,
9133         NullType,
9134         NullType,
9135         NullType,
9136         NullType,
9137         NullType>
9138 {
9139         typedef detail::KernelFunctorGlobal<
9140                 T0,
9141                 T1,
9142                 T2,
9143                 T3,
9144                 T4,
9145                 T5,
9146                 T6,
9147                 T7,
9148                 T8,
9149                 T9,
9150                 T10,
9151                 T11,
9152                 T12,
9153                 T13,
9154                 T14,
9155                 T15,
9156                 T16,
9157                 T17,
9158                 T18,
9159                 T19,
9160                 T20,
9161                 T21,
9162                 NullType,
9163                 NullType,
9164                 NullType,
9165                 NullType,
9166                 NullType,
9167                 NullType,
9168                 NullType,
9169                 NullType,
9170                 NullType,
9171                 NullType> FunctorType;
9172
9173     FunctorType functor_;
9174
9175     functionImplementation_(const FunctorType &functor) :
9176         functor_(functor)
9177     {
9178     
9179         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 22))
9180         // Fail variadic expansion for dev11
9181         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
9182         #endif
9183             
9184     }
9185
9186         //! \brief Return type of the functor
9187         typedef Event result_type;
9188
9189         //! \brief Function signature of kernel functor with no event dependency.
9190         typedef Event type_(
9191                 const EnqueueArgs&,
9192                 T0,
9193                 T1,
9194                 T2,
9195                 T3,
9196                 T4,
9197                 T5,
9198                 T6,
9199                 T7,
9200                 T8,
9201                 T9,
9202                 T10,
9203                 T11,
9204                 T12,
9205                 T13,
9206                 T14,
9207                 T15,
9208                 T16,
9209                 T17,
9210                 T18,
9211                 T19,
9212                 T20,
9213                 T21);
9214
9215         Event operator()(
9216                 const EnqueueArgs& enqueueArgs,
9217                 T0 arg0,
9218                 T1 arg1,
9219                 T2 arg2,
9220                 T3 arg3,
9221                 T4 arg4,
9222                 T5 arg5,
9223                 T6 arg6,
9224                 T7 arg7,
9225                 T8 arg8,
9226                 T9 arg9,
9227                 T10 arg10,
9228                 T11 arg11,
9229                 T12 arg12,
9230                 T13 arg13,
9231                 T14 arg14,
9232                 T15 arg15,
9233                 T16 arg16,
9234                 T17 arg17,
9235                 T18 arg18,
9236                 T19 arg19,
9237                 T20 arg20,
9238                 T21 arg21)
9239         {
9240                 return functor_(
9241                         enqueueArgs,
9242                         arg0,
9243                         arg1,
9244                         arg2,
9245                         arg3,
9246                         arg4,
9247                         arg5,
9248                         arg6,
9249                         arg7,
9250                         arg8,
9251                         arg9,
9252                         arg10,
9253                         arg11,
9254                         arg12,
9255                         arg13,
9256                         arg14,
9257                         arg15,
9258                         arg16,
9259                         arg17,
9260                         arg18,
9261                         arg19,
9262                         arg20,
9263                         arg21);
9264         }
9265
9266
9267 };
9268
9269 template<
9270         typename T0,
9271         typename T1,
9272         typename T2,
9273         typename T3,
9274         typename T4,
9275         typename T5,
9276         typename T6,
9277         typename T7,
9278         typename T8,
9279         typename T9,
9280         typename T10,
9281         typename T11,
9282         typename T12,
9283         typename T13,
9284         typename T14,
9285         typename T15,
9286         typename T16,
9287         typename T17,
9288         typename T18,
9289         typename T19,
9290         typename T20>
9291 struct functionImplementation_
9292 <       T0,
9293         T1,
9294         T2,
9295         T3,
9296         T4,
9297         T5,
9298         T6,
9299         T7,
9300         T8,
9301         T9,
9302         T10,
9303         T11,
9304         T12,
9305         T13,
9306         T14,
9307         T15,
9308         T16,
9309         T17,
9310         T18,
9311         T19,
9312         T20,
9313         NullType,
9314         NullType,
9315         NullType,
9316         NullType,
9317         NullType,
9318         NullType,
9319         NullType,
9320         NullType,
9321         NullType,
9322         NullType,
9323         NullType>
9324 {
9325         typedef detail::KernelFunctorGlobal<
9326                 T0,
9327                 T1,
9328                 T2,
9329                 T3,
9330                 T4,
9331                 T5,
9332                 T6,
9333                 T7,
9334                 T8,
9335                 T9,
9336                 T10,
9337                 T11,
9338                 T12,
9339                 T13,
9340                 T14,
9341                 T15,
9342                 T16,
9343                 T17,
9344                 T18,
9345                 T19,
9346                 T20,
9347                 NullType,
9348                 NullType,
9349                 NullType,
9350                 NullType,
9351                 NullType,
9352                 NullType,
9353                 NullType,
9354                 NullType,
9355                 NullType,
9356                 NullType,
9357                 NullType> FunctorType;
9358
9359     FunctorType functor_;
9360
9361     functionImplementation_(const FunctorType &functor) :
9362         functor_(functor)
9363     {
9364     
9365         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 21))
9366         // Fail variadic expansion for dev11
9367         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
9368         #endif
9369             
9370     }
9371
9372         //! \brief Return type of the functor
9373         typedef Event result_type;
9374
9375         //! \brief Function signature of kernel functor with no event dependency.
9376         typedef Event type_(
9377                 const EnqueueArgs&,
9378                 T0,
9379                 T1,
9380                 T2,
9381                 T3,
9382                 T4,
9383                 T5,
9384                 T6,
9385                 T7,
9386                 T8,
9387                 T9,
9388                 T10,
9389                 T11,
9390                 T12,
9391                 T13,
9392                 T14,
9393                 T15,
9394                 T16,
9395                 T17,
9396                 T18,
9397                 T19,
9398                 T20);
9399
9400         Event operator()(
9401                 const EnqueueArgs& enqueueArgs,
9402                 T0 arg0,
9403                 T1 arg1,
9404                 T2 arg2,
9405                 T3 arg3,
9406                 T4 arg4,
9407                 T5 arg5,
9408                 T6 arg6,
9409                 T7 arg7,
9410                 T8 arg8,
9411                 T9 arg9,
9412                 T10 arg10,
9413                 T11 arg11,
9414                 T12 arg12,
9415                 T13 arg13,
9416                 T14 arg14,
9417                 T15 arg15,
9418                 T16 arg16,
9419                 T17 arg17,
9420                 T18 arg18,
9421                 T19 arg19,
9422                 T20 arg20)
9423         {
9424                 return functor_(
9425                         enqueueArgs,
9426                         arg0,
9427                         arg1,
9428                         arg2,
9429                         arg3,
9430                         arg4,
9431                         arg5,
9432                         arg6,
9433                         arg7,
9434                         arg8,
9435                         arg9,
9436                         arg10,
9437                         arg11,
9438                         arg12,
9439                         arg13,
9440                         arg14,
9441                         arg15,
9442                         arg16,
9443                         arg17,
9444                         arg18,
9445                         arg19,
9446                         arg20);
9447         }
9448
9449
9450 };
9451
9452 template<
9453         typename T0,
9454         typename T1,
9455         typename T2,
9456         typename T3,
9457         typename T4,
9458         typename T5,
9459         typename T6,
9460         typename T7,
9461         typename T8,
9462         typename T9,
9463         typename T10,
9464         typename T11,
9465         typename T12,
9466         typename T13,
9467         typename T14,
9468         typename T15,
9469         typename T16,
9470         typename T17,
9471         typename T18,
9472         typename T19>
9473 struct functionImplementation_
9474 <       T0,
9475         T1,
9476         T2,
9477         T3,
9478         T4,
9479         T5,
9480         T6,
9481         T7,
9482         T8,
9483         T9,
9484         T10,
9485         T11,
9486         T12,
9487         T13,
9488         T14,
9489         T15,
9490         T16,
9491         T17,
9492         T18,
9493         T19,
9494         NullType,
9495         NullType,
9496         NullType,
9497         NullType,
9498         NullType,
9499         NullType,
9500         NullType,
9501         NullType,
9502         NullType,
9503         NullType,
9504         NullType,
9505         NullType>
9506 {
9507         typedef detail::KernelFunctorGlobal<
9508                 T0,
9509                 T1,
9510                 T2,
9511                 T3,
9512                 T4,
9513                 T5,
9514                 T6,
9515                 T7,
9516                 T8,
9517                 T9,
9518                 T10,
9519                 T11,
9520                 T12,
9521                 T13,
9522                 T14,
9523                 T15,
9524                 T16,
9525                 T17,
9526                 T18,
9527                 T19,
9528                 NullType,
9529                 NullType,
9530                 NullType,
9531                 NullType,
9532                 NullType,
9533                 NullType,
9534                 NullType,
9535                 NullType,
9536                 NullType,
9537                 NullType,
9538                 NullType,
9539                 NullType> FunctorType;
9540
9541     FunctorType functor_;
9542
9543     functionImplementation_(const FunctorType &functor) :
9544         functor_(functor)
9545     {
9546     
9547         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 20))
9548         // Fail variadic expansion for dev11
9549         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
9550         #endif
9551             
9552     }
9553
9554         //! \brief Return type of the functor
9555         typedef Event result_type;
9556
9557         //! \brief Function signature of kernel functor with no event dependency.
9558         typedef Event type_(
9559                 const EnqueueArgs&,
9560                 T0,
9561                 T1,
9562                 T2,
9563                 T3,
9564                 T4,
9565                 T5,
9566                 T6,
9567                 T7,
9568                 T8,
9569                 T9,
9570                 T10,
9571                 T11,
9572                 T12,
9573                 T13,
9574                 T14,
9575                 T15,
9576                 T16,
9577                 T17,
9578                 T18,
9579                 T19);
9580
9581         Event operator()(
9582                 const EnqueueArgs& enqueueArgs,
9583                 T0 arg0,
9584                 T1 arg1,
9585                 T2 arg2,
9586                 T3 arg3,
9587                 T4 arg4,
9588                 T5 arg5,
9589                 T6 arg6,
9590                 T7 arg7,
9591                 T8 arg8,
9592                 T9 arg9,
9593                 T10 arg10,
9594                 T11 arg11,
9595                 T12 arg12,
9596                 T13 arg13,
9597                 T14 arg14,
9598                 T15 arg15,
9599                 T16 arg16,
9600                 T17 arg17,
9601                 T18 arg18,
9602                 T19 arg19)
9603         {
9604                 return functor_(
9605                         enqueueArgs,
9606                         arg0,
9607                         arg1,
9608                         arg2,
9609                         arg3,
9610                         arg4,
9611                         arg5,
9612                         arg6,
9613                         arg7,
9614                         arg8,
9615                         arg9,
9616                         arg10,
9617                         arg11,
9618                         arg12,
9619                         arg13,
9620                         arg14,
9621                         arg15,
9622                         arg16,
9623                         arg17,
9624                         arg18,
9625                         arg19);
9626         }
9627
9628
9629 };
9630
9631 template<
9632         typename T0,
9633         typename T1,
9634         typename T2,
9635         typename T3,
9636         typename T4,
9637         typename T5,
9638         typename T6,
9639         typename T7,
9640         typename T8,
9641         typename T9,
9642         typename T10,
9643         typename T11,
9644         typename T12,
9645         typename T13,
9646         typename T14,
9647         typename T15,
9648         typename T16,
9649         typename T17,
9650         typename T18>
9651 struct functionImplementation_
9652 <       T0,
9653         T1,
9654         T2,
9655         T3,
9656         T4,
9657         T5,
9658         T6,
9659         T7,
9660         T8,
9661         T9,
9662         T10,
9663         T11,
9664         T12,
9665         T13,
9666         T14,
9667         T15,
9668         T16,
9669         T17,
9670         T18,
9671         NullType,
9672         NullType,
9673         NullType,
9674         NullType,
9675         NullType,
9676         NullType,
9677         NullType,
9678         NullType,
9679         NullType,
9680         NullType,
9681         NullType,
9682         NullType,
9683         NullType>
9684 {
9685         typedef detail::KernelFunctorGlobal<
9686                 T0,
9687                 T1,
9688                 T2,
9689                 T3,
9690                 T4,
9691                 T5,
9692                 T6,
9693                 T7,
9694                 T8,
9695                 T9,
9696                 T10,
9697                 T11,
9698                 T12,
9699                 T13,
9700                 T14,
9701                 T15,
9702                 T16,
9703                 T17,
9704                 T18,
9705                 NullType,
9706                 NullType,
9707                 NullType,
9708                 NullType,
9709                 NullType,
9710                 NullType,
9711                 NullType,
9712                 NullType,
9713                 NullType,
9714                 NullType,
9715                 NullType,
9716                 NullType,
9717                 NullType> FunctorType;
9718
9719     FunctorType functor_;
9720
9721     functionImplementation_(const FunctorType &functor) :
9722         functor_(functor)
9723     {
9724     
9725         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 19))
9726         // Fail variadic expansion for dev11
9727         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
9728         #endif
9729             
9730     }
9731
9732         //! \brief Return type of the functor
9733         typedef Event result_type;
9734
9735         //! \brief Function signature of kernel functor with no event dependency.
9736         typedef Event type_(
9737                 const EnqueueArgs&,
9738                 T0,
9739                 T1,
9740                 T2,
9741                 T3,
9742                 T4,
9743                 T5,
9744                 T6,
9745                 T7,
9746                 T8,
9747                 T9,
9748                 T10,
9749                 T11,
9750                 T12,
9751                 T13,
9752                 T14,
9753                 T15,
9754                 T16,
9755                 T17,
9756                 T18);
9757
9758         Event operator()(
9759                 const EnqueueArgs& enqueueArgs,
9760                 T0 arg0,
9761                 T1 arg1,
9762                 T2 arg2,
9763                 T3 arg3,
9764                 T4 arg4,
9765                 T5 arg5,
9766                 T6 arg6,
9767                 T7 arg7,
9768                 T8 arg8,
9769                 T9 arg9,
9770                 T10 arg10,
9771                 T11 arg11,
9772                 T12 arg12,
9773                 T13 arg13,
9774                 T14 arg14,
9775                 T15 arg15,
9776                 T16 arg16,
9777                 T17 arg17,
9778                 T18 arg18)
9779         {
9780                 return functor_(
9781                         enqueueArgs,
9782                         arg0,
9783                         arg1,
9784                         arg2,
9785                         arg3,
9786                         arg4,
9787                         arg5,
9788                         arg6,
9789                         arg7,
9790                         arg8,
9791                         arg9,
9792                         arg10,
9793                         arg11,
9794                         arg12,
9795                         arg13,
9796                         arg14,
9797                         arg15,
9798                         arg16,
9799                         arg17,
9800                         arg18);
9801         }
9802
9803
9804 };
9805
9806 template<
9807         typename T0,
9808         typename T1,
9809         typename T2,
9810         typename T3,
9811         typename T4,
9812         typename T5,
9813         typename T6,
9814         typename T7,
9815         typename T8,
9816         typename T9,
9817         typename T10,
9818         typename T11,
9819         typename T12,
9820         typename T13,
9821         typename T14,
9822         typename T15,
9823         typename T16,
9824         typename T17>
9825 struct functionImplementation_
9826 <       T0,
9827         T1,
9828         T2,
9829         T3,
9830         T4,
9831         T5,
9832         T6,
9833         T7,
9834         T8,
9835         T9,
9836         T10,
9837         T11,
9838         T12,
9839         T13,
9840         T14,
9841         T15,
9842         T16,
9843         T17,
9844         NullType,
9845         NullType,
9846         NullType,
9847         NullType,
9848         NullType,
9849         NullType,
9850         NullType,
9851         NullType,
9852         NullType,
9853         NullType,
9854         NullType,
9855         NullType,
9856         NullType,
9857         NullType>
9858 {
9859         typedef detail::KernelFunctorGlobal<
9860                 T0,
9861                 T1,
9862                 T2,
9863                 T3,
9864                 T4,
9865                 T5,
9866                 T6,
9867                 T7,
9868                 T8,
9869                 T9,
9870                 T10,
9871                 T11,
9872                 T12,
9873                 T13,
9874                 T14,
9875                 T15,
9876                 T16,
9877                 T17,
9878                 NullType,
9879                 NullType,
9880                 NullType,
9881                 NullType,
9882                 NullType,
9883                 NullType,
9884                 NullType,
9885                 NullType,
9886                 NullType,
9887                 NullType,
9888                 NullType,
9889                 NullType,
9890                 NullType,
9891                 NullType> FunctorType;
9892
9893     FunctorType functor_;
9894
9895     functionImplementation_(const FunctorType &functor) :
9896         functor_(functor)
9897     {
9898     
9899         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 18))
9900         // Fail variadic expansion for dev11
9901         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
9902         #endif
9903             
9904     }
9905
9906         //! \brief Return type of the functor
9907         typedef Event result_type;
9908
9909         //! \brief Function signature of kernel functor with no event dependency.
9910         typedef Event type_(
9911                 const EnqueueArgs&,
9912                 T0,
9913                 T1,
9914                 T2,
9915                 T3,
9916                 T4,
9917                 T5,
9918                 T6,
9919                 T7,
9920                 T8,
9921                 T9,
9922                 T10,
9923                 T11,
9924                 T12,
9925                 T13,
9926                 T14,
9927                 T15,
9928                 T16,
9929                 T17);
9930
9931         Event operator()(
9932                 const EnqueueArgs& enqueueArgs,
9933                 T0 arg0,
9934                 T1 arg1,
9935                 T2 arg2,
9936                 T3 arg3,
9937                 T4 arg4,
9938                 T5 arg5,
9939                 T6 arg6,
9940                 T7 arg7,
9941                 T8 arg8,
9942                 T9 arg9,
9943                 T10 arg10,
9944                 T11 arg11,
9945                 T12 arg12,
9946                 T13 arg13,
9947                 T14 arg14,
9948                 T15 arg15,
9949                 T16 arg16,
9950                 T17 arg17)
9951         {
9952                 return functor_(
9953                         enqueueArgs,
9954                         arg0,
9955                         arg1,
9956                         arg2,
9957                         arg3,
9958                         arg4,
9959                         arg5,
9960                         arg6,
9961                         arg7,
9962                         arg8,
9963                         arg9,
9964                         arg10,
9965                         arg11,
9966                         arg12,
9967                         arg13,
9968                         arg14,
9969                         arg15,
9970                         arg16,
9971                         arg17);
9972         }
9973
9974
9975 };
9976
9977 template<
9978         typename T0,
9979         typename T1,
9980         typename T2,
9981         typename T3,
9982         typename T4,
9983         typename T5,
9984         typename T6,
9985         typename T7,
9986         typename T8,
9987         typename T9,
9988         typename T10,
9989         typename T11,
9990         typename T12,
9991         typename T13,
9992         typename T14,
9993         typename T15,
9994         typename T16>
9995 struct functionImplementation_
9996 <       T0,
9997         T1,
9998         T2,
9999         T3,
10000         T4,
10001         T5,
10002         T6,
10003         T7,
10004         T8,
10005         T9,
10006         T10,
10007         T11,
10008         T12,
10009         T13,
10010         T14,
10011         T15,
10012         T16,
10013         NullType,
10014         NullType,
10015         NullType,
10016         NullType,
10017         NullType,
10018         NullType,
10019         NullType,
10020         NullType,
10021         NullType,
10022         NullType,
10023         NullType,
10024         NullType,
10025         NullType,
10026         NullType,
10027         NullType>
10028 {
10029         typedef detail::KernelFunctorGlobal<
10030                 T0,
10031                 T1,
10032                 T2,
10033                 T3,
10034                 T4,
10035                 T5,
10036                 T6,
10037                 T7,
10038                 T8,
10039                 T9,
10040                 T10,
10041                 T11,
10042                 T12,
10043                 T13,
10044                 T14,
10045                 T15,
10046                 T16,
10047                 NullType,
10048                 NullType,
10049                 NullType,
10050                 NullType,
10051                 NullType,
10052                 NullType,
10053                 NullType,
10054                 NullType,
10055                 NullType,
10056                 NullType,
10057                 NullType,
10058                 NullType,
10059                 NullType,
10060                 NullType,
10061                 NullType> FunctorType;
10062
10063     FunctorType functor_;
10064
10065     functionImplementation_(const FunctorType &functor) :
10066         functor_(functor)
10067     {
10068     
10069         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 17))
10070         // Fail variadic expansion for dev11
10071         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
10072         #endif
10073             
10074     }
10075
10076         //! \brief Return type of the functor
10077         typedef Event result_type;
10078
10079         //! \brief Function signature of kernel functor with no event dependency.
10080         typedef Event type_(
10081                 const EnqueueArgs&,
10082                 T0,
10083                 T1,
10084                 T2,
10085                 T3,
10086                 T4,
10087                 T5,
10088                 T6,
10089                 T7,
10090                 T8,
10091                 T9,
10092                 T10,
10093                 T11,
10094                 T12,
10095                 T13,
10096                 T14,
10097                 T15,
10098                 T16);
10099
10100         Event operator()(
10101                 const EnqueueArgs& enqueueArgs,
10102                 T0 arg0,
10103                 T1 arg1,
10104                 T2 arg2,
10105                 T3 arg3,
10106                 T4 arg4,
10107                 T5 arg5,
10108                 T6 arg6,
10109                 T7 arg7,
10110                 T8 arg8,
10111                 T9 arg9,
10112                 T10 arg10,
10113                 T11 arg11,
10114                 T12 arg12,
10115                 T13 arg13,
10116                 T14 arg14,
10117                 T15 arg15,
10118                 T16 arg16)
10119         {
10120                 return functor_(
10121                         enqueueArgs,
10122                         arg0,
10123                         arg1,
10124                         arg2,
10125                         arg3,
10126                         arg4,
10127                         arg5,
10128                         arg6,
10129                         arg7,
10130                         arg8,
10131                         arg9,
10132                         arg10,
10133                         arg11,
10134                         arg12,
10135                         arg13,
10136                         arg14,
10137                         arg15,
10138                         arg16);
10139         }
10140
10141
10142 };
10143
10144 template<
10145         typename T0,
10146         typename T1,
10147         typename T2,
10148         typename T3,
10149         typename T4,
10150         typename T5,
10151         typename T6,
10152         typename T7,
10153         typename T8,
10154         typename T9,
10155         typename T10,
10156         typename T11,
10157         typename T12,
10158         typename T13,
10159         typename T14,
10160         typename T15>
10161 struct functionImplementation_
10162 <       T0,
10163         T1,
10164         T2,
10165         T3,
10166         T4,
10167         T5,
10168         T6,
10169         T7,
10170         T8,
10171         T9,
10172         T10,
10173         T11,
10174         T12,
10175         T13,
10176         T14,
10177         T15,
10178         NullType,
10179         NullType,
10180         NullType,
10181         NullType,
10182         NullType,
10183         NullType,
10184         NullType,
10185         NullType,
10186         NullType,
10187         NullType,
10188         NullType,
10189         NullType,
10190         NullType,
10191         NullType,
10192         NullType,
10193         NullType>
10194 {
10195         typedef detail::KernelFunctorGlobal<
10196                 T0,
10197                 T1,
10198                 T2,
10199                 T3,
10200                 T4,
10201                 T5,
10202                 T6,
10203                 T7,
10204                 T8,
10205                 T9,
10206                 T10,
10207                 T11,
10208                 T12,
10209                 T13,
10210                 T14,
10211                 T15,
10212                 NullType,
10213                 NullType,
10214                 NullType,
10215                 NullType,
10216                 NullType,
10217                 NullType,
10218                 NullType,
10219                 NullType,
10220                 NullType,
10221                 NullType,
10222                 NullType,
10223                 NullType,
10224                 NullType,
10225                 NullType,
10226                 NullType,
10227                 NullType> FunctorType;
10228
10229     FunctorType functor_;
10230
10231     functionImplementation_(const FunctorType &functor) :
10232         functor_(functor)
10233     {
10234     
10235         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 16))
10236         // Fail variadic expansion for dev11
10237         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
10238         #endif
10239             
10240     }
10241
10242         //! \brief Return type of the functor
10243         typedef Event result_type;
10244
10245         //! \brief Function signature of kernel functor with no event dependency.
10246         typedef Event type_(
10247                 const EnqueueArgs&,
10248                 T0,
10249                 T1,
10250                 T2,
10251                 T3,
10252                 T4,
10253                 T5,
10254                 T6,
10255                 T7,
10256                 T8,
10257                 T9,
10258                 T10,
10259                 T11,
10260                 T12,
10261                 T13,
10262                 T14,
10263                 T15);
10264
10265         Event operator()(
10266                 const EnqueueArgs& enqueueArgs,
10267                 T0 arg0,
10268                 T1 arg1,
10269                 T2 arg2,
10270                 T3 arg3,
10271                 T4 arg4,
10272                 T5 arg5,
10273                 T6 arg6,
10274                 T7 arg7,
10275                 T8 arg8,
10276                 T9 arg9,
10277                 T10 arg10,
10278                 T11 arg11,
10279                 T12 arg12,
10280                 T13 arg13,
10281                 T14 arg14,
10282                 T15 arg15)
10283         {
10284                 return functor_(
10285                         enqueueArgs,
10286                         arg0,
10287                         arg1,
10288                         arg2,
10289                         arg3,
10290                         arg4,
10291                         arg5,
10292                         arg6,
10293                         arg7,
10294                         arg8,
10295                         arg9,
10296                         arg10,
10297                         arg11,
10298                         arg12,
10299                         arg13,
10300                         arg14,
10301                         arg15);
10302         }
10303
10304
10305 };
10306
10307 template<
10308         typename T0,
10309         typename T1,
10310         typename T2,
10311         typename T3,
10312         typename T4,
10313         typename T5,
10314         typename T6,
10315         typename T7,
10316         typename T8,
10317         typename T9,
10318         typename T10,
10319         typename T11,
10320         typename T12,
10321         typename T13,
10322         typename T14>
10323 struct functionImplementation_
10324 <       T0,
10325         T1,
10326         T2,
10327         T3,
10328         T4,
10329         T5,
10330         T6,
10331         T7,
10332         T8,
10333         T9,
10334         T10,
10335         T11,
10336         T12,
10337         T13,
10338         T14,
10339         NullType,
10340         NullType,
10341         NullType,
10342         NullType,
10343         NullType,
10344         NullType,
10345         NullType,
10346         NullType,
10347         NullType,
10348         NullType,
10349         NullType,
10350         NullType,
10351         NullType,
10352         NullType,
10353         NullType,
10354         NullType,
10355         NullType>
10356 {
10357         typedef detail::KernelFunctorGlobal<
10358                 T0,
10359                 T1,
10360                 T2,
10361                 T3,
10362                 T4,
10363                 T5,
10364                 T6,
10365                 T7,
10366                 T8,
10367                 T9,
10368                 T10,
10369                 T11,
10370                 T12,
10371                 T13,
10372                 T14,
10373                 NullType,
10374                 NullType,
10375                 NullType,
10376                 NullType,
10377                 NullType,
10378                 NullType,
10379                 NullType,
10380                 NullType,
10381                 NullType,
10382                 NullType,
10383                 NullType,
10384                 NullType,
10385                 NullType,
10386                 NullType,
10387                 NullType,
10388                 NullType,
10389                 NullType> FunctorType;
10390
10391     FunctorType functor_;
10392
10393     functionImplementation_(const FunctorType &functor) :
10394         functor_(functor)
10395     {
10396     
10397         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 15))
10398         // Fail variadic expansion for dev11
10399         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
10400         #endif
10401             
10402     }
10403
10404         //! \brief Return type of the functor
10405         typedef Event result_type;
10406
10407         //! \brief Function signature of kernel functor with no event dependency.
10408         typedef Event type_(
10409                 const EnqueueArgs&,
10410                 T0,
10411                 T1,
10412                 T2,
10413                 T3,
10414                 T4,
10415                 T5,
10416                 T6,
10417                 T7,
10418                 T8,
10419                 T9,
10420                 T10,
10421                 T11,
10422                 T12,
10423                 T13,
10424                 T14);
10425
10426         Event operator()(
10427                 const EnqueueArgs& enqueueArgs,
10428                 T0 arg0,
10429                 T1 arg1,
10430                 T2 arg2,
10431                 T3 arg3,
10432                 T4 arg4,
10433                 T5 arg5,
10434                 T6 arg6,
10435                 T7 arg7,
10436                 T8 arg8,
10437                 T9 arg9,
10438                 T10 arg10,
10439                 T11 arg11,
10440                 T12 arg12,
10441                 T13 arg13,
10442                 T14 arg14)
10443         {
10444                 return functor_(
10445                         enqueueArgs,
10446                         arg0,
10447                         arg1,
10448                         arg2,
10449                         arg3,
10450                         arg4,
10451                         arg5,
10452                         arg6,
10453                         arg7,
10454                         arg8,
10455                         arg9,
10456                         arg10,
10457                         arg11,
10458                         arg12,
10459                         arg13,
10460                         arg14);
10461         }
10462
10463
10464 };
10465
10466 template<
10467         typename T0,
10468         typename T1,
10469         typename T2,
10470         typename T3,
10471         typename T4,
10472         typename T5,
10473         typename T6,
10474         typename T7,
10475         typename T8,
10476         typename T9,
10477         typename T10,
10478         typename T11,
10479         typename T12,
10480         typename T13>
10481 struct functionImplementation_
10482 <       T0,
10483         T1,
10484         T2,
10485         T3,
10486         T4,
10487         T5,
10488         T6,
10489         T7,
10490         T8,
10491         T9,
10492         T10,
10493         T11,
10494         T12,
10495         T13,
10496         NullType,
10497         NullType,
10498         NullType,
10499         NullType,
10500         NullType,
10501         NullType,
10502         NullType,
10503         NullType,
10504         NullType,
10505         NullType,
10506         NullType,
10507         NullType,
10508         NullType,
10509         NullType,
10510         NullType,
10511         NullType,
10512         NullType,
10513         NullType>
10514 {
10515         typedef detail::KernelFunctorGlobal<
10516                 T0,
10517                 T1,
10518                 T2,
10519                 T3,
10520                 T4,
10521                 T5,
10522                 T6,
10523                 T7,
10524                 T8,
10525                 T9,
10526                 T10,
10527                 T11,
10528                 T12,
10529                 T13,
10530                 NullType,
10531                 NullType,
10532                 NullType,
10533                 NullType,
10534                 NullType,
10535                 NullType,
10536                 NullType,
10537                 NullType,
10538                 NullType,
10539                 NullType,
10540                 NullType,
10541                 NullType,
10542                 NullType,
10543                 NullType,
10544                 NullType,
10545                 NullType,
10546                 NullType,
10547                 NullType> FunctorType;
10548
10549     FunctorType functor_;
10550
10551     functionImplementation_(const FunctorType &functor) :
10552         functor_(functor)
10553     {
10554     
10555         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 14))
10556         // Fail variadic expansion for dev11
10557         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
10558         #endif
10559             
10560     }
10561
10562         //! \brief Return type of the functor
10563         typedef Event result_type;
10564
10565         //! \brief Function signature of kernel functor with no event dependency.
10566         typedef Event type_(
10567                 const EnqueueArgs&,
10568                 T0,
10569                 T1,
10570                 T2,
10571                 T3,
10572                 T4,
10573                 T5,
10574                 T6,
10575                 T7,
10576                 T8,
10577                 T9,
10578                 T10,
10579                 T11,
10580                 T12,
10581                 T13);
10582
10583         Event operator()(
10584                 const EnqueueArgs& enqueueArgs,
10585                 T0 arg0,
10586                 T1 arg1,
10587                 T2 arg2,
10588                 T3 arg3,
10589                 T4 arg4,
10590                 T5 arg5,
10591                 T6 arg6,
10592                 T7 arg7,
10593                 T8 arg8,
10594                 T9 arg9,
10595                 T10 arg10,
10596                 T11 arg11,
10597                 T12 arg12,
10598                 T13 arg13)
10599         {
10600                 return functor_(
10601                         enqueueArgs,
10602                         arg0,
10603                         arg1,
10604                         arg2,
10605                         arg3,
10606                         arg4,
10607                         arg5,
10608                         arg6,
10609                         arg7,
10610                         arg8,
10611                         arg9,
10612                         arg10,
10613                         arg11,
10614                         arg12,
10615                         arg13);
10616         }
10617
10618
10619 };
10620
10621 template<
10622         typename T0,
10623         typename T1,
10624         typename T2,
10625         typename T3,
10626         typename T4,
10627         typename T5,
10628         typename T6,
10629         typename T7,
10630         typename T8,
10631         typename T9,
10632         typename T10,
10633         typename T11,
10634         typename T12>
10635 struct functionImplementation_
10636 <       T0,
10637         T1,
10638         T2,
10639         T3,
10640         T4,
10641         T5,
10642         T6,
10643         T7,
10644         T8,
10645         T9,
10646         T10,
10647         T11,
10648         T12,
10649         NullType,
10650         NullType,
10651         NullType,
10652         NullType,
10653         NullType,
10654         NullType,
10655         NullType,
10656         NullType,
10657         NullType,
10658         NullType,
10659         NullType,
10660         NullType,
10661         NullType,
10662         NullType,
10663         NullType,
10664         NullType,
10665         NullType,
10666         NullType,
10667         NullType>
10668 {
10669         typedef detail::KernelFunctorGlobal<
10670                 T0,
10671                 T1,
10672                 T2,
10673                 T3,
10674                 T4,
10675                 T5,
10676                 T6,
10677                 T7,
10678                 T8,
10679                 T9,
10680                 T10,
10681                 T11,
10682                 T12,
10683                 NullType,
10684                 NullType,
10685                 NullType,
10686                 NullType,
10687                 NullType,
10688                 NullType,
10689                 NullType,
10690                 NullType,
10691                 NullType,
10692                 NullType,
10693                 NullType,
10694                 NullType,
10695                 NullType,
10696                 NullType,
10697                 NullType,
10698                 NullType,
10699                 NullType,
10700                 NullType,
10701                 NullType> FunctorType;
10702
10703     FunctorType functor_;
10704
10705     functionImplementation_(const FunctorType &functor) :
10706         functor_(functor)
10707     {
10708     
10709         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 13))
10710         // Fail variadic expansion for dev11
10711         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
10712         #endif
10713             
10714     }
10715
10716         //! \brief Return type of the functor
10717         typedef Event result_type;
10718
10719         //! \brief Function signature of kernel functor with no event dependency.
10720         typedef Event type_(
10721                 const EnqueueArgs&,
10722                 T0,
10723                 T1,
10724                 T2,
10725                 T3,
10726                 T4,
10727                 T5,
10728                 T6,
10729                 T7,
10730                 T8,
10731                 T9,
10732                 T10,
10733                 T11,
10734                 T12);
10735
10736         Event operator()(
10737                 const EnqueueArgs& enqueueArgs,
10738                 T0 arg0,
10739                 T1 arg1,
10740                 T2 arg2,
10741                 T3 arg3,
10742                 T4 arg4,
10743                 T5 arg5,
10744                 T6 arg6,
10745                 T7 arg7,
10746                 T8 arg8,
10747                 T9 arg9,
10748                 T10 arg10,
10749                 T11 arg11,
10750                 T12 arg12)
10751         {
10752                 return functor_(
10753                         enqueueArgs,
10754                         arg0,
10755                         arg1,
10756                         arg2,
10757                         arg3,
10758                         arg4,
10759                         arg5,
10760                         arg6,
10761                         arg7,
10762                         arg8,
10763                         arg9,
10764                         arg10,
10765                         arg11,
10766                         arg12);
10767         }
10768
10769
10770 };
10771
10772 template<
10773         typename T0,
10774         typename T1,
10775         typename T2,
10776         typename T3,
10777         typename T4,
10778         typename T5,
10779         typename T6,
10780         typename T7,
10781         typename T8,
10782         typename T9,
10783         typename T10,
10784         typename T11>
10785 struct functionImplementation_
10786 <       T0,
10787         T1,
10788         T2,
10789         T3,
10790         T4,
10791         T5,
10792         T6,
10793         T7,
10794         T8,
10795         T9,
10796         T10,
10797         T11,
10798         NullType,
10799         NullType,
10800         NullType,
10801         NullType,
10802         NullType,
10803         NullType,
10804         NullType,
10805         NullType,
10806         NullType,
10807         NullType,
10808         NullType,
10809         NullType,
10810         NullType,
10811         NullType,
10812         NullType,
10813         NullType,
10814         NullType,
10815         NullType,
10816         NullType,
10817         NullType>
10818 {
10819         typedef detail::KernelFunctorGlobal<
10820                 T0,
10821                 T1,
10822                 T2,
10823                 T3,
10824                 T4,
10825                 T5,
10826                 T6,
10827                 T7,
10828                 T8,
10829                 T9,
10830                 T10,
10831                 T11,
10832                 NullType,
10833                 NullType,
10834                 NullType,
10835                 NullType,
10836                 NullType,
10837                 NullType,
10838                 NullType,
10839                 NullType,
10840                 NullType,
10841                 NullType,
10842                 NullType,
10843                 NullType,
10844                 NullType,
10845                 NullType,
10846                 NullType,
10847                 NullType,
10848                 NullType,
10849                 NullType,
10850                 NullType,
10851                 NullType> FunctorType;
10852
10853     FunctorType functor_;
10854
10855     functionImplementation_(const FunctorType &functor) :
10856         functor_(functor)
10857     {
10858     
10859         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 12))
10860         // Fail variadic expansion for dev11
10861         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
10862         #endif
10863             
10864     }
10865
10866         //! \brief Return type of the functor
10867         typedef Event result_type;
10868
10869         //! \brief Function signature of kernel functor with no event dependency.
10870         typedef Event type_(
10871                 const EnqueueArgs&,
10872                 T0,
10873                 T1,
10874                 T2,
10875                 T3,
10876                 T4,
10877                 T5,
10878                 T6,
10879                 T7,
10880                 T8,
10881                 T9,
10882                 T10,
10883                 T11);
10884
10885         Event operator()(
10886                 const EnqueueArgs& enqueueArgs,
10887                 T0 arg0,
10888                 T1 arg1,
10889                 T2 arg2,
10890                 T3 arg3,
10891                 T4 arg4,
10892                 T5 arg5,
10893                 T6 arg6,
10894                 T7 arg7,
10895                 T8 arg8,
10896                 T9 arg9,
10897                 T10 arg10,
10898                 T11 arg11)
10899         {
10900                 return functor_(
10901                         enqueueArgs,
10902                         arg0,
10903                         arg1,
10904                         arg2,
10905                         arg3,
10906                         arg4,
10907                         arg5,
10908                         arg6,
10909                         arg7,
10910                         arg8,
10911                         arg9,
10912                         arg10,
10913                         arg11);
10914         }
10915
10916
10917 };
10918
10919 template<
10920         typename T0,
10921         typename T1,
10922         typename T2,
10923         typename T3,
10924         typename T4,
10925         typename T5,
10926         typename T6,
10927         typename T7,
10928         typename T8,
10929         typename T9,
10930         typename T10>
10931 struct functionImplementation_
10932 <       T0,
10933         T1,
10934         T2,
10935         T3,
10936         T4,
10937         T5,
10938         T6,
10939         T7,
10940         T8,
10941         T9,
10942         T10,
10943         NullType,
10944         NullType,
10945         NullType,
10946         NullType,
10947         NullType,
10948         NullType,
10949         NullType,
10950         NullType,
10951         NullType,
10952         NullType,
10953         NullType,
10954         NullType,
10955         NullType,
10956         NullType,
10957         NullType,
10958         NullType,
10959         NullType,
10960         NullType,
10961         NullType,
10962         NullType,
10963         NullType>
10964 {
10965         typedef detail::KernelFunctorGlobal<
10966                 T0,
10967                 T1,
10968                 T2,
10969                 T3,
10970                 T4,
10971                 T5,
10972                 T6,
10973                 T7,
10974                 T8,
10975                 T9,
10976                 T10,
10977                 NullType,
10978                 NullType,
10979                 NullType,
10980                 NullType,
10981                 NullType,
10982                 NullType,
10983                 NullType,
10984                 NullType,
10985                 NullType,
10986                 NullType,
10987                 NullType,
10988                 NullType,
10989                 NullType,
10990                 NullType,
10991                 NullType,
10992                 NullType,
10993                 NullType,
10994                 NullType,
10995                 NullType,
10996                 NullType,
10997                 NullType> FunctorType;
10998
10999     FunctorType functor_;
11000
11001     functionImplementation_(const FunctorType &functor) :
11002         functor_(functor)
11003     {
11004     
11005         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 11))
11006         // Fail variadic expansion for dev11
11007         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11008         #endif
11009             
11010     }
11011
11012         //! \brief Return type of the functor
11013         typedef Event result_type;
11014
11015         //! \brief Function signature of kernel functor with no event dependency.
11016         typedef Event type_(
11017                 const EnqueueArgs&,
11018                 T0,
11019                 T1,
11020                 T2,
11021                 T3,
11022                 T4,
11023                 T5,
11024                 T6,
11025                 T7,
11026                 T8,
11027                 T9,
11028                 T10);
11029
11030         Event operator()(
11031                 const EnqueueArgs& enqueueArgs,
11032                 T0 arg0,
11033                 T1 arg1,
11034                 T2 arg2,
11035                 T3 arg3,
11036                 T4 arg4,
11037                 T5 arg5,
11038                 T6 arg6,
11039                 T7 arg7,
11040                 T8 arg8,
11041                 T9 arg9,
11042                 T10 arg10)
11043         {
11044                 return functor_(
11045                         enqueueArgs,
11046                         arg0,
11047                         arg1,
11048                         arg2,
11049                         arg3,
11050                         arg4,
11051                         arg5,
11052                         arg6,
11053                         arg7,
11054                         arg8,
11055                         arg9,
11056                         arg10);
11057         }
11058
11059
11060 };
11061
11062 template<
11063         typename T0,
11064         typename T1,
11065         typename T2,
11066         typename T3,
11067         typename T4,
11068         typename T5,
11069         typename T6,
11070         typename T7,
11071         typename T8,
11072         typename T9>
11073 struct functionImplementation_
11074 <       T0,
11075         T1,
11076         T2,
11077         T3,
11078         T4,
11079         T5,
11080         T6,
11081         T7,
11082         T8,
11083         T9,
11084         NullType,
11085         NullType,
11086         NullType,
11087         NullType,
11088         NullType,
11089         NullType,
11090         NullType,
11091         NullType,
11092         NullType,
11093         NullType,
11094         NullType,
11095         NullType,
11096         NullType,
11097         NullType,
11098         NullType,
11099         NullType,
11100         NullType,
11101         NullType,
11102         NullType,
11103         NullType,
11104         NullType,
11105         NullType>
11106 {
11107         typedef detail::KernelFunctorGlobal<
11108                 T0,
11109                 T1,
11110                 T2,
11111                 T3,
11112                 T4,
11113                 T5,
11114                 T6,
11115                 T7,
11116                 T8,
11117                 T9,
11118                 NullType,
11119                 NullType,
11120                 NullType,
11121                 NullType,
11122                 NullType,
11123                 NullType,
11124                 NullType,
11125                 NullType,
11126                 NullType,
11127                 NullType,
11128                 NullType,
11129                 NullType,
11130                 NullType,
11131                 NullType,
11132                 NullType,
11133                 NullType,
11134                 NullType,
11135                 NullType,
11136                 NullType,
11137                 NullType,
11138                 NullType,
11139                 NullType> FunctorType;
11140
11141     FunctorType functor_;
11142
11143     functionImplementation_(const FunctorType &functor) :
11144         functor_(functor)
11145     {
11146     
11147         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 10))
11148         // Fail variadic expansion for dev11
11149         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11150         #endif
11151             
11152     }
11153
11154         //! \brief Return type of the functor
11155         typedef Event result_type;
11156
11157         //! \brief Function signature of kernel functor with no event dependency.
11158         typedef Event type_(
11159                 const EnqueueArgs&,
11160                 T0,
11161                 T1,
11162                 T2,
11163                 T3,
11164                 T4,
11165                 T5,
11166                 T6,
11167                 T7,
11168                 T8,
11169                 T9);
11170
11171         Event operator()(
11172                 const EnqueueArgs& enqueueArgs,
11173                 T0 arg0,
11174                 T1 arg1,
11175                 T2 arg2,
11176                 T3 arg3,
11177                 T4 arg4,
11178                 T5 arg5,
11179                 T6 arg6,
11180                 T7 arg7,
11181                 T8 arg8,
11182                 T9 arg9)
11183         {
11184                 return functor_(
11185                         enqueueArgs,
11186                         arg0,
11187                         arg1,
11188                         arg2,
11189                         arg3,
11190                         arg4,
11191                         arg5,
11192                         arg6,
11193                         arg7,
11194                         arg8,
11195                         arg9);
11196         }
11197
11198
11199 };
11200
11201 template<
11202         typename T0,
11203         typename T1,
11204         typename T2,
11205         typename T3,
11206         typename T4,
11207         typename T5,
11208         typename T6,
11209         typename T7,
11210         typename T8>
11211 struct functionImplementation_
11212 <       T0,
11213         T1,
11214         T2,
11215         T3,
11216         T4,
11217         T5,
11218         T6,
11219         T7,
11220         T8,
11221         NullType,
11222         NullType,
11223         NullType,
11224         NullType,
11225         NullType,
11226         NullType,
11227         NullType,
11228         NullType,
11229         NullType,
11230         NullType,
11231         NullType,
11232         NullType,
11233         NullType,
11234         NullType,
11235         NullType,
11236         NullType,
11237         NullType,
11238         NullType,
11239         NullType,
11240         NullType,
11241         NullType,
11242         NullType,
11243         NullType>
11244 {
11245         typedef detail::KernelFunctorGlobal<
11246                 T0,
11247                 T1,
11248                 T2,
11249                 T3,
11250                 T4,
11251                 T5,
11252                 T6,
11253                 T7,
11254                 T8,
11255                 NullType,
11256                 NullType,
11257                 NullType,
11258                 NullType,
11259                 NullType,
11260                 NullType,
11261                 NullType,
11262                 NullType,
11263                 NullType,
11264                 NullType,
11265                 NullType,
11266                 NullType,
11267                 NullType,
11268                 NullType,
11269                 NullType,
11270                 NullType,
11271                 NullType,
11272                 NullType,
11273                 NullType,
11274                 NullType,
11275                 NullType,
11276                 NullType,
11277                 NullType> FunctorType;
11278
11279     FunctorType functor_;
11280
11281     functionImplementation_(const FunctorType &functor) :
11282         functor_(functor)
11283     {
11284     
11285         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 9))
11286         // Fail variadic expansion for dev11
11287         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11288         #endif
11289             
11290     }
11291
11292         //! \brief Return type of the functor
11293         typedef Event result_type;
11294
11295         //! \brief Function signature of kernel functor with no event dependency.
11296         typedef Event type_(
11297                 const EnqueueArgs&,
11298                 T0,
11299                 T1,
11300                 T2,
11301                 T3,
11302                 T4,
11303                 T5,
11304                 T6,
11305                 T7,
11306                 T8);
11307
11308         Event operator()(
11309                 const EnqueueArgs& enqueueArgs,
11310                 T0 arg0,
11311                 T1 arg1,
11312                 T2 arg2,
11313                 T3 arg3,
11314                 T4 arg4,
11315                 T5 arg5,
11316                 T6 arg6,
11317                 T7 arg7,
11318                 T8 arg8)
11319         {
11320                 return functor_(
11321                         enqueueArgs,
11322                         arg0,
11323                         arg1,
11324                         arg2,
11325                         arg3,
11326                         arg4,
11327                         arg5,
11328                         arg6,
11329                         arg7,
11330                         arg8);
11331         }
11332
11333
11334 };
11335
11336 template<
11337         typename T0,
11338         typename T1,
11339         typename T2,
11340         typename T3,
11341         typename T4,
11342         typename T5,
11343         typename T6,
11344         typename T7>
11345 struct functionImplementation_
11346 <       T0,
11347         T1,
11348         T2,
11349         T3,
11350         T4,
11351         T5,
11352         T6,
11353         T7,
11354         NullType,
11355         NullType,
11356         NullType,
11357         NullType,
11358         NullType,
11359         NullType,
11360         NullType,
11361         NullType,
11362         NullType,
11363         NullType,
11364         NullType,
11365         NullType,
11366         NullType,
11367         NullType,
11368         NullType,
11369         NullType,
11370         NullType,
11371         NullType,
11372         NullType,
11373         NullType,
11374         NullType,
11375         NullType,
11376         NullType,
11377         NullType>
11378 {
11379         typedef detail::KernelFunctorGlobal<
11380                 T0,
11381                 T1,
11382                 T2,
11383                 T3,
11384                 T4,
11385                 T5,
11386                 T6,
11387                 T7,
11388                 NullType,
11389                 NullType,
11390                 NullType,
11391                 NullType,
11392                 NullType,
11393                 NullType,
11394                 NullType,
11395                 NullType,
11396                 NullType,
11397                 NullType,
11398                 NullType,
11399                 NullType,
11400                 NullType,
11401                 NullType,
11402                 NullType,
11403                 NullType,
11404                 NullType,
11405                 NullType,
11406                 NullType,
11407                 NullType,
11408                 NullType,
11409                 NullType,
11410                 NullType,
11411                 NullType> FunctorType;
11412
11413     FunctorType functor_;
11414
11415     functionImplementation_(const FunctorType &functor) :
11416         functor_(functor)
11417     {
11418     
11419         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 8))
11420         // Fail variadic expansion for dev11
11421         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11422         #endif
11423             
11424     }
11425
11426         //! \brief Return type of the functor
11427         typedef Event result_type;
11428
11429         //! \brief Function signature of kernel functor with no event dependency.
11430         typedef Event type_(
11431                 const EnqueueArgs&,
11432                 T0,
11433                 T1,
11434                 T2,
11435                 T3,
11436                 T4,
11437                 T5,
11438                 T6,
11439                 T7);
11440
11441         Event operator()(
11442                 const EnqueueArgs& enqueueArgs,
11443                 T0 arg0,
11444                 T1 arg1,
11445                 T2 arg2,
11446                 T3 arg3,
11447                 T4 arg4,
11448                 T5 arg5,
11449                 T6 arg6,
11450                 T7 arg7)
11451         {
11452                 return functor_(
11453                         enqueueArgs,
11454                         arg0,
11455                         arg1,
11456                         arg2,
11457                         arg3,
11458                         arg4,
11459                         arg5,
11460                         arg6,
11461                         arg7);
11462         }
11463
11464
11465 };
11466
11467 template<
11468         typename T0,
11469         typename T1,
11470         typename T2,
11471         typename T3,
11472         typename T4,
11473         typename T5,
11474         typename T6>
11475 struct functionImplementation_
11476 <       T0,
11477         T1,
11478         T2,
11479         T3,
11480         T4,
11481         T5,
11482         T6,
11483         NullType,
11484         NullType,
11485         NullType,
11486         NullType,
11487         NullType,
11488         NullType,
11489         NullType,
11490         NullType,
11491         NullType,
11492         NullType,
11493         NullType,
11494         NullType,
11495         NullType,
11496         NullType,
11497         NullType,
11498         NullType,
11499         NullType,
11500         NullType,
11501         NullType,
11502         NullType,
11503         NullType,
11504         NullType,
11505         NullType,
11506         NullType,
11507         NullType>
11508 {
11509         typedef detail::KernelFunctorGlobal<
11510                 T0,
11511                 T1,
11512                 T2,
11513                 T3,
11514                 T4,
11515                 T5,
11516                 T6,
11517                 NullType,
11518                 NullType,
11519                 NullType,
11520                 NullType,
11521                 NullType,
11522                 NullType,
11523                 NullType,
11524                 NullType,
11525                 NullType,
11526                 NullType,
11527                 NullType,
11528                 NullType,
11529                 NullType,
11530                 NullType,
11531                 NullType,
11532                 NullType,
11533                 NullType,
11534                 NullType,
11535                 NullType,
11536                 NullType,
11537                 NullType,
11538                 NullType,
11539                 NullType,
11540                 NullType,
11541                 NullType> FunctorType;
11542
11543     FunctorType functor_;
11544
11545     functionImplementation_(const FunctorType &functor) :
11546         functor_(functor)
11547     {
11548     
11549         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 7))
11550         // Fail variadic expansion for dev11
11551         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11552         #endif
11553             
11554     }
11555
11556         //! \brief Return type of the functor
11557         typedef Event result_type;
11558
11559         //! \brief Function signature of kernel functor with no event dependency.
11560         typedef Event type_(
11561                 const EnqueueArgs&,
11562                 T0,
11563                 T1,
11564                 T2,
11565                 T3,
11566                 T4,
11567                 T5,
11568                 T6);
11569
11570         Event operator()(
11571                 const EnqueueArgs& enqueueArgs,
11572                 T0 arg0,
11573                 T1 arg1,
11574                 T2 arg2,
11575                 T3 arg3,
11576                 T4 arg4,
11577                 T5 arg5,
11578                 T6 arg6)
11579         {
11580                 return functor_(
11581                         enqueueArgs,
11582                         arg0,
11583                         arg1,
11584                         arg2,
11585                         arg3,
11586                         arg4,
11587                         arg5,
11588                         arg6);
11589         }
11590
11591
11592 };
11593
11594 template<
11595         typename T0,
11596         typename T1,
11597         typename T2,
11598         typename T3,
11599         typename T4,
11600         typename T5>
11601 struct functionImplementation_
11602 <       T0,
11603         T1,
11604         T2,
11605         T3,
11606         T4,
11607         T5,
11608         NullType,
11609         NullType,
11610         NullType,
11611         NullType,
11612         NullType,
11613         NullType,
11614         NullType,
11615         NullType,
11616         NullType,
11617         NullType,
11618         NullType,
11619         NullType,
11620         NullType,
11621         NullType,
11622         NullType,
11623         NullType,
11624         NullType,
11625         NullType,
11626         NullType,
11627         NullType,
11628         NullType,
11629         NullType,
11630         NullType,
11631         NullType,
11632         NullType,
11633         NullType>
11634 {
11635         typedef detail::KernelFunctorGlobal<
11636                 T0,
11637                 T1,
11638                 T2,
11639                 T3,
11640                 T4,
11641                 T5,
11642                 NullType,
11643                 NullType,
11644                 NullType,
11645                 NullType,
11646                 NullType,
11647                 NullType,
11648                 NullType,
11649                 NullType,
11650                 NullType,
11651                 NullType,
11652                 NullType,
11653                 NullType,
11654                 NullType,
11655                 NullType,
11656                 NullType,
11657                 NullType,
11658                 NullType,
11659                 NullType,
11660                 NullType,
11661                 NullType,
11662                 NullType,
11663                 NullType,
11664                 NullType,
11665                 NullType,
11666                 NullType,
11667                 NullType> FunctorType;
11668
11669     FunctorType functor_;
11670
11671     functionImplementation_(const FunctorType &functor) :
11672         functor_(functor)
11673     {
11674     
11675         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 6))
11676         // Fail variadic expansion for dev11
11677         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11678         #endif
11679             
11680     }
11681
11682         //! \brief Return type of the functor
11683         typedef Event result_type;
11684
11685         //! \brief Function signature of kernel functor with no event dependency.
11686         typedef Event type_(
11687                 const EnqueueArgs&,
11688                 T0,
11689                 T1,
11690                 T2,
11691                 T3,
11692                 T4,
11693                 T5);
11694
11695         Event operator()(
11696                 const EnqueueArgs& enqueueArgs,
11697                 T0 arg0,
11698                 T1 arg1,
11699                 T2 arg2,
11700                 T3 arg3,
11701                 T4 arg4,
11702                 T5 arg5)
11703         {
11704                 return functor_(
11705                         enqueueArgs,
11706                         arg0,
11707                         arg1,
11708                         arg2,
11709                         arg3,
11710                         arg4,
11711                         arg5);
11712         }
11713
11714
11715 };
11716
11717 template<
11718         typename T0,
11719         typename T1,
11720         typename T2,
11721         typename T3,
11722         typename T4>
11723 struct functionImplementation_
11724 <       T0,
11725         T1,
11726         T2,
11727         T3,
11728         T4,
11729         NullType,
11730         NullType,
11731         NullType,
11732         NullType,
11733         NullType,
11734         NullType,
11735         NullType,
11736         NullType,
11737         NullType,
11738         NullType,
11739         NullType,
11740         NullType,
11741         NullType,
11742         NullType,
11743         NullType,
11744         NullType,
11745         NullType,
11746         NullType,
11747         NullType,
11748         NullType,
11749         NullType,
11750         NullType,
11751         NullType,
11752         NullType,
11753         NullType,
11754         NullType,
11755         NullType>
11756 {
11757         typedef detail::KernelFunctorGlobal<
11758                 T0,
11759                 T1,
11760                 T2,
11761                 T3,
11762                 T4,
11763                 NullType,
11764                 NullType,
11765                 NullType,
11766                 NullType,
11767                 NullType,
11768                 NullType,
11769                 NullType,
11770                 NullType,
11771                 NullType,
11772                 NullType,
11773                 NullType,
11774                 NullType,
11775                 NullType,
11776                 NullType,
11777                 NullType,
11778                 NullType,
11779                 NullType,
11780                 NullType,
11781                 NullType,
11782                 NullType,
11783                 NullType,
11784                 NullType,
11785                 NullType,
11786                 NullType,
11787                 NullType,
11788                 NullType,
11789                 NullType> FunctorType;
11790
11791     FunctorType functor_;
11792
11793     functionImplementation_(const FunctorType &functor) :
11794         functor_(functor)
11795     {
11796     
11797         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 5))
11798         // Fail variadic expansion for dev11
11799         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11800         #endif
11801             
11802     }
11803
11804         //! \brief Return type of the functor
11805         typedef Event result_type;
11806
11807         //! \brief Function signature of kernel functor with no event dependency.
11808         typedef Event type_(
11809                 const EnqueueArgs&,
11810                 T0,
11811                 T1,
11812                 T2,
11813                 T3,
11814                 T4);
11815
11816         Event operator()(
11817                 const EnqueueArgs& enqueueArgs,
11818                 T0 arg0,
11819                 T1 arg1,
11820                 T2 arg2,
11821                 T3 arg3,
11822                 T4 arg4)
11823         {
11824                 return functor_(
11825                         enqueueArgs,
11826                         arg0,
11827                         arg1,
11828                         arg2,
11829                         arg3,
11830                         arg4);
11831         }
11832
11833
11834 };
11835
11836 template<
11837         typename T0,
11838         typename T1,
11839         typename T2,
11840         typename T3>
11841 struct functionImplementation_
11842 <       T0,
11843         T1,
11844         T2,
11845         T3,
11846         NullType,
11847         NullType,
11848         NullType,
11849         NullType,
11850         NullType,
11851         NullType,
11852         NullType,
11853         NullType,
11854         NullType,
11855         NullType,
11856         NullType,
11857         NullType,
11858         NullType,
11859         NullType,
11860         NullType,
11861         NullType,
11862         NullType,
11863         NullType,
11864         NullType,
11865         NullType,
11866         NullType,
11867         NullType,
11868         NullType,
11869         NullType,
11870         NullType,
11871         NullType,
11872         NullType,
11873         NullType>
11874 {
11875         typedef detail::KernelFunctorGlobal<
11876                 T0,
11877                 T1,
11878                 T2,
11879                 T3,
11880                 NullType,
11881                 NullType,
11882                 NullType,
11883                 NullType,
11884                 NullType,
11885                 NullType,
11886                 NullType,
11887                 NullType,
11888                 NullType,
11889                 NullType,
11890                 NullType,
11891                 NullType,
11892                 NullType,
11893                 NullType,
11894                 NullType,
11895                 NullType,
11896                 NullType,
11897                 NullType,
11898                 NullType,
11899                 NullType,
11900                 NullType,
11901                 NullType,
11902                 NullType,
11903                 NullType,
11904                 NullType,
11905                 NullType,
11906                 NullType,
11907                 NullType> FunctorType;
11908
11909     FunctorType functor_;
11910
11911     functionImplementation_(const FunctorType &functor) :
11912         functor_(functor)
11913     {
11914     
11915         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 4))
11916         // Fail variadic expansion for dev11
11917         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
11918         #endif
11919             
11920     }
11921
11922         //! \brief Return type of the functor
11923         typedef Event result_type;
11924
11925         //! \brief Function signature of kernel functor with no event dependency.
11926         typedef Event type_(
11927                 const EnqueueArgs&,
11928                 T0,
11929                 T1,
11930                 T2,
11931                 T3);
11932
11933         Event operator()(
11934                 const EnqueueArgs& enqueueArgs,
11935                 T0 arg0,
11936                 T1 arg1,
11937                 T2 arg2,
11938                 T3 arg3)
11939         {
11940                 return functor_(
11941                         enqueueArgs,
11942                         arg0,
11943                         arg1,
11944                         arg2,
11945                         arg3);
11946         }
11947
11948
11949 };
11950
11951 template<
11952         typename T0,
11953         typename T1,
11954         typename T2>
11955 struct functionImplementation_
11956 <       T0,
11957         T1,
11958         T2,
11959         NullType,
11960         NullType,
11961         NullType,
11962         NullType,
11963         NullType,
11964         NullType,
11965         NullType,
11966         NullType,
11967         NullType,
11968         NullType,
11969         NullType,
11970         NullType,
11971         NullType,
11972         NullType,
11973         NullType,
11974         NullType,
11975         NullType,
11976         NullType,
11977         NullType,
11978         NullType,
11979         NullType,
11980         NullType,
11981         NullType,
11982         NullType,
11983         NullType,
11984         NullType,
11985         NullType,
11986         NullType,
11987         NullType>
11988 {
11989         typedef detail::KernelFunctorGlobal<
11990                 T0,
11991                 T1,
11992                 T2,
11993                 NullType,
11994                 NullType,
11995                 NullType,
11996                 NullType,
11997                 NullType,
11998                 NullType,
11999                 NullType,
12000                 NullType,
12001                 NullType,
12002                 NullType,
12003                 NullType,
12004                 NullType,
12005                 NullType,
12006                 NullType,
12007                 NullType,
12008                 NullType,
12009                 NullType,
12010                 NullType,
12011                 NullType,
12012                 NullType,
12013                 NullType,
12014                 NullType,
12015                 NullType,
12016                 NullType,
12017                 NullType,
12018                 NullType,
12019                 NullType,
12020                 NullType,
12021                 NullType> FunctorType;
12022
12023     FunctorType functor_;
12024
12025     functionImplementation_(const FunctorType &functor) :
12026         functor_(functor)
12027     {
12028     
12029         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 3))
12030         // Fail variadic expansion for dev11
12031         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
12032         #endif
12033             
12034     }
12035
12036         //! \brief Return type of the functor
12037         typedef Event result_type;
12038
12039         //! \brief Function signature of kernel functor with no event dependency.
12040         typedef Event type_(
12041                 const EnqueueArgs&,
12042                 T0,
12043                 T1,
12044                 T2);
12045
12046         Event operator()(
12047                 const EnqueueArgs& enqueueArgs,
12048                 T0 arg0,
12049                 T1 arg1,
12050                 T2 arg2)
12051         {
12052                 return functor_(
12053                         enqueueArgs,
12054                         arg0,
12055                         arg1,
12056                         arg2);
12057         }
12058
12059
12060 };
12061
12062 template<
12063         typename T0,
12064         typename T1>
12065 struct functionImplementation_
12066 <       T0,
12067         T1,
12068         NullType,
12069         NullType,
12070         NullType,
12071         NullType,
12072         NullType,
12073         NullType,
12074         NullType,
12075         NullType,
12076         NullType,
12077         NullType,
12078         NullType,
12079         NullType,
12080         NullType,
12081         NullType,
12082         NullType,
12083         NullType,
12084         NullType,
12085         NullType,
12086         NullType,
12087         NullType,
12088         NullType,
12089         NullType,
12090         NullType,
12091         NullType,
12092         NullType,
12093         NullType,
12094         NullType,
12095         NullType,
12096         NullType,
12097         NullType>
12098 {
12099         typedef detail::KernelFunctorGlobal<
12100                 T0,
12101                 T1,
12102                 NullType,
12103                 NullType,
12104                 NullType,
12105                 NullType,
12106                 NullType,
12107                 NullType,
12108                 NullType,
12109                 NullType,
12110                 NullType,
12111                 NullType,
12112                 NullType,
12113                 NullType,
12114                 NullType,
12115                 NullType,
12116                 NullType,
12117                 NullType,
12118                 NullType,
12119                 NullType,
12120                 NullType,
12121                 NullType,
12122                 NullType,
12123                 NullType,
12124                 NullType,
12125                 NullType,
12126                 NullType,
12127                 NullType,
12128                 NullType,
12129                 NullType,
12130                 NullType,
12131                 NullType> FunctorType;
12132
12133     FunctorType functor_;
12134
12135     functionImplementation_(const FunctorType &functor) :
12136         functor_(functor)
12137     {
12138     
12139         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 2))
12140         // Fail variadic expansion for dev11
12141         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
12142         #endif
12143             
12144     }
12145
12146         //! \brief Return type of the functor
12147         typedef Event result_type;
12148
12149         //! \brief Function signature of kernel functor with no event dependency.
12150         typedef Event type_(
12151                 const EnqueueArgs&,
12152                 T0,
12153                 T1);
12154
12155         Event operator()(
12156                 const EnqueueArgs& enqueueArgs,
12157                 T0 arg0,
12158                 T1 arg1)
12159         {
12160                 return functor_(
12161                         enqueueArgs,
12162                         arg0,
12163                         arg1);
12164         }
12165
12166
12167 };
12168
12169 template<
12170         typename T0>
12171 struct functionImplementation_
12172 <       T0,
12173         NullType,
12174         NullType,
12175         NullType,
12176         NullType,
12177         NullType,
12178         NullType,
12179         NullType,
12180         NullType,
12181         NullType,
12182         NullType,
12183         NullType,
12184         NullType,
12185         NullType,
12186         NullType,
12187         NullType,
12188         NullType,
12189         NullType,
12190         NullType,
12191         NullType,
12192         NullType,
12193         NullType,
12194         NullType,
12195         NullType,
12196         NullType,
12197         NullType,
12198         NullType,
12199         NullType,
12200         NullType,
12201         NullType,
12202         NullType,
12203         NullType>
12204 {
12205         typedef detail::KernelFunctorGlobal<
12206                 T0,
12207                 NullType,
12208                 NullType,
12209                 NullType,
12210                 NullType,
12211                 NullType,
12212                 NullType,
12213                 NullType,
12214                 NullType,
12215                 NullType,
12216                 NullType,
12217                 NullType,
12218                 NullType,
12219                 NullType,
12220                 NullType,
12221                 NullType,
12222                 NullType,
12223                 NullType,
12224                 NullType,
12225                 NullType,
12226                 NullType,
12227                 NullType,
12228                 NullType,
12229                 NullType,
12230                 NullType,
12231                 NullType,
12232                 NullType,
12233                 NullType,
12234                 NullType,
12235                 NullType,
12236                 NullType,
12237                 NullType> FunctorType;
12238
12239     FunctorType functor_;
12240
12241     functionImplementation_(const FunctorType &functor) :
12242         functor_(functor)
12243     {
12244     
12245         #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 1))
12246         // Fail variadic expansion for dev11
12247         static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it.");
12248         #endif
12249             
12250     }
12251
12252         //! \brief Return type of the functor
12253         typedef Event result_type;
12254
12255         //! \brief Function signature of kernel functor with no event dependency.
12256         typedef Event type_(
12257                 const EnqueueArgs&,
12258                 T0);
12259
12260         Event operator()(
12261                 const EnqueueArgs& enqueueArgs,
12262                 T0 arg0)
12263         {
12264                 return functor_(
12265                         enqueueArgs,
12266                         arg0);
12267         }
12268
12269
12270 };
12271
12272
12273
12274
12275
12276 } // namespace detail
12277
12278 //----------------------------------------------------------------------------------------------
12279
12280 template <
12281    typename T0,   typename T1 = detail::NullType,   typename T2 = detail::NullType,
12282    typename T3 = detail::NullType,   typename T4 = detail::NullType,
12283    typename T5 = detail::NullType,   typename T6 = detail::NullType,
12284    typename T7 = detail::NullType,   typename T8 = detail::NullType,
12285    typename T9 = detail::NullType,   typename T10 = detail::NullType,
12286    typename T11 = detail::NullType,   typename T12 = detail::NullType,
12287    typename T13 = detail::NullType,   typename T14 = detail::NullType,
12288    typename T15 = detail::NullType,   typename T16 = detail::NullType,
12289    typename T17 = detail::NullType,   typename T18 = detail::NullType,
12290    typename T19 = detail::NullType,   typename T20 = detail::NullType,
12291    typename T21 = detail::NullType,   typename T22 = detail::NullType,
12292    typename T23 = detail::NullType,   typename T24 = detail::NullType,
12293    typename T25 = detail::NullType,   typename T26 = detail::NullType,
12294    typename T27 = detail::NullType,   typename T28 = detail::NullType,
12295    typename T29 = detail::NullType,   typename T30 = detail::NullType,
12296    typename T31 = detail::NullType
12297 >
12298 struct make_kernel :
12299     public detail::functionImplementation_<
12300                T0,   T1,   T2,   T3,
12301                T4,   T5,   T6,   T7,
12302                T8,   T9,   T10,   T11,
12303                T12,   T13,   T14,   T15,
12304                T16,   T17,   T18,   T19,
12305                T20,   T21,   T22,   T23,
12306                T24,   T25,   T26,   T27,
12307                T28,   T29,   T30,   T31
12308     >
12309 {
12310 public:
12311         typedef detail::KernelFunctorGlobal<             
12312                        T0,   T1,   T2,   T3,
12313                T4,   T5,   T6,   T7,
12314                T8,   T9,   T10,   T11,
12315                T12,   T13,   T14,   T15,
12316                T16,   T17,   T18,   T19,
12317                T20,   T21,   T22,   T23,
12318                T24,   T25,   T26,   T27,
12319                T28,   T29,   T30,   T31
12320     > FunctorType;
12321
12322     make_kernel(
12323         const Program& program,
12324         const STRING_CLASS name,
12325         cl_int * err = NULL) :
12326            detail::functionImplementation_<
12327                     T0,   T1,   T2,   T3,
12328                        T4,   T5,   T6,   T7,
12329                        T8,   T9,   T10,   T11,
12330                        T12,   T13,   T14,   T15,
12331                        T16,   T17,   T18,   T19,
12332                        T20,   T21,   T22,   T23,
12333                        T24,   T25,   T26,   T27,
12334                        T28,   T29,   T30,   T31
12335            >(
12336             FunctorType(program, name, err)) 
12337     {}
12338
12339     make_kernel(
12340         const Kernel kernel) :
12341            detail::functionImplementation_<
12342                     T0,   T1,   T2,   T3,
12343                        T4,   T5,   T6,   T7,
12344                        T8,   T9,   T10,   T11,
12345                        T12,   T13,   T14,   T15,
12346                        T16,   T17,   T18,   T19,
12347                        T20,   T21,   T22,   T23,
12348                        T24,   T25,   T26,   T27,
12349                        T28,   T29,   T30,   T31
12350            >(
12351             FunctorType(kernel)) 
12352     {}    
12353 };
12354
12355
12356 //----------------------------------------------------------------------------------------------------------------------
12357
12358 #undef __ERR_STR
12359 #if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
12360 #undef __GET_DEVICE_INFO_ERR
12361 #undef __GET_PLATFORM_INFO_ERR
12362 #undef __GET_DEVICE_IDS_ERR
12363 #undef __GET_CONTEXT_INFO_ERR
12364 #undef __GET_EVENT_INFO_ERR
12365 #undef __GET_EVENT_PROFILE_INFO_ERR
12366 #undef __GET_MEM_OBJECT_INFO_ERR
12367 #undef __GET_IMAGE_INFO_ERR
12368 #undef __GET_SAMPLER_INFO_ERR
12369 #undef __GET_KERNEL_INFO_ERR
12370 #undef __GET_KERNEL_ARG_INFO_ERR
12371 #undef __GET_KERNEL_WORK_GROUP_INFO_ERR
12372 #undef __GET_PROGRAM_INFO_ERR
12373 #undef __GET_PROGRAM_BUILD_INFO_ERR
12374 #undef __GET_COMMAND_QUEUE_INFO_ERR
12375
12376 #undef __CREATE_CONTEXT_ERR
12377 #undef __CREATE_CONTEXT_FROM_TYPE_ERR
12378 #undef __GET_SUPPORTED_IMAGE_FORMATS_ERR
12379
12380 #undef __CREATE_BUFFER_ERR
12381 #undef __CREATE_SUBBUFFER_ERR
12382 #undef __CREATE_IMAGE2D_ERR
12383 #undef __CREATE_IMAGE3D_ERR
12384 #undef __CREATE_SAMPLER_ERR
12385 #undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR
12386
12387 #undef __CREATE_USER_EVENT_ERR
12388 #undef __SET_USER_EVENT_STATUS_ERR
12389 #undef __SET_EVENT_CALLBACK_ERR
12390 #undef __SET_PRINTF_CALLBACK_ERR
12391
12392 #undef __WAIT_FOR_EVENTS_ERR
12393
12394 #undef __CREATE_KERNEL_ERR
12395 #undef __SET_KERNEL_ARGS_ERR
12396 #undef __CREATE_PROGRAM_WITH_SOURCE_ERR
12397 #undef __CREATE_PROGRAM_WITH_BINARY_ERR
12398 #undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR
12399 #undef __BUILD_PROGRAM_ERR
12400 #undef __CREATE_KERNELS_IN_PROGRAM_ERR
12401
12402 #undef __CREATE_COMMAND_QUEUE_ERR
12403 #undef __SET_COMMAND_QUEUE_PROPERTY_ERR
12404 #undef __ENQUEUE_READ_BUFFER_ERR
12405 #undef __ENQUEUE_WRITE_BUFFER_ERR
12406 #undef __ENQUEUE_READ_BUFFER_RECT_ERR
12407 #undef __ENQUEUE_WRITE_BUFFER_RECT_ERR
12408 #undef __ENQEUE_COPY_BUFFER_ERR
12409 #undef __ENQEUE_COPY_BUFFER_RECT_ERR
12410 #undef __ENQUEUE_READ_IMAGE_ERR
12411 #undef __ENQUEUE_WRITE_IMAGE_ERR
12412 #undef __ENQUEUE_COPY_IMAGE_ERR
12413 #undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR
12414 #undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR
12415 #undef __ENQUEUE_MAP_BUFFER_ERR
12416 #undef __ENQUEUE_MAP_IMAGE_ERR
12417 #undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR
12418 #undef __ENQUEUE_NDRANGE_KERNEL_ERR
12419 #undef __ENQUEUE_TASK_ERR
12420 #undef __ENQUEUE_NATIVE_KERNEL
12421
12422 #undef __CL_EXPLICIT_CONSTRUCTORS
12423
12424 #undef __UNLOAD_COMPILER_ERR
12425 #endif //__CL_USER_OVERRIDE_ERROR_STRINGS
12426
12427 #undef __CL_FUNCTION_TYPE
12428
12429 // Extensions
12430 /**
12431  * Deprecated APIs for 1.2
12432  */
12433 #if defined(CL_VERSION_1_1)
12434 #undef __INIT_CL_EXT_FCN_PTR
12435 #endif // #if defined(CL_VERSION_1_1)
12436 #undef __CREATE_SUB_DEVICES
12437
12438 #if defined(USE_CL_DEVICE_FISSION)
12439 #undef __PARAM_NAME_DEVICE_FISSION
12440 #endif // USE_CL_DEVICE_FISSION
12441
12442 #undef __DEFAULT_NOT_INITIALIZED 
12443 #undef __DEFAULT_BEING_INITIALIZED 
12444 #undef __DEFAULT_INITIALIZED
12445
12446 } // namespace cl
12447
12448 #ifdef _WIN32
12449 #pragma pop_macro("max")
12450 #endif // _WIN32
12451
12452 #endif // CL_HPP_