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