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