"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/include/CL/cl.hpp" (16 Sep 2020, 300070 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cl.hpp" see the Fossies "Dox" file reference documentation.

    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  */
  264 namespace cl {
  265 
  266 class 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 
  291 class Program;
  292 class Device;
  293 class Context;
  294 class CommandQueue;
  295 class Memory;
  296 class 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  */
  303 class Error : public std::exception
  304 {
  305 private:
  306     cl_int err_;
  307     const char * errStr_;
  308 public:
  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 
  350 namespace detail
  351 {
  352 #if defined(__CL_ENABLE_EXCEPTIONS)
  353 static 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
  363 static 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)
  501 typedef 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  */
  512 class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED string
  513 {
  514 private:
  515     ::size_t size_;
  516     char * str_;
  517 public:
  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;
  679 typedef 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  */
  713 template <typename T, unsigned int N = __MAX_DEFAULT_VECTOR_SIZE>
  714 class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED vector
  715 {
  716 private:
  717     T data_[N];
  718     unsigned int size_;
  719 
  720 public:
  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 
 1073 namespace 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  */
 1120 template <int N>
 1121 class size_t
 1122 { 
 1123 private:
 1124     ::size_t data_[N];
 1125 
 1126 public:
 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 
 1152 namespace 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.
 1158 template<typename Functor, typename T>
 1159 inline 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
 1165 template <typename Func, typename T>
 1166 inline 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  */
 1190 template <typename Func, typename T>
 1191 inline 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>
 1221 template <typename Func>
 1222 inline 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
 1234 template <typename Func>
 1235 inline 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
 1279 template <typename Func, ::size_t N>
 1280 inline 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 
 1301 template<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  */
 1309 template<typename Func, typename T>
 1310 inline 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 
 1518 template <typename enum_type, cl_int Name>
 1519 struct param_traits {};
 1520 
 1521 #define __CL_DECLARE_PARAM_TRAITS(token, param_name, T) \
 1522 struct token;                                        \
 1523 template<>                                           \
 1524 struct 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 
 1605 template <typename Func, typename T>
 1606 inline cl_int
 1607 getInfo(Func f, cl_uint name, T* param)
 1608 {
 1609     return getInfoHelper(f, name, param, 0);
 1610 }
 1611 
 1612 template <typename Func, typename Arg0>
 1613 struct 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 
 1621 template <typename Func, typename Arg0, typename Arg1>
 1622 struct 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 
 1630 template <typename Func, typename Arg0, typename T>
 1631 inline cl_int
 1632 getInfo(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 
 1638 template <typename Func, typename Arg0, typename Arg1, typename T>
 1639 inline cl_int
 1640 getInfo(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 
 1646 template<typename T>
 1647 struct ReferenceHandler
 1648 { };
 1649 
 1650 #if defined(CL_VERSION_1_2)
 1651 /**
 1652  * OpenCL 1.2 devices do have retain/release.
 1653  */
 1654 template <>
 1655 struct 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  */
 1684 template <>
 1685 struct 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 
 1696 template <>
 1697 struct 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 
 1707 template <>
 1708 struct 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 
 1716 template <>
 1717 struct 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 
 1725 template <>
 1726 struct 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 
 1734 template <>
 1735 struct 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 
 1743 template <>
 1744 struct 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 
 1752 template <>
 1753 struct 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 
 1761 template <>
 1762 struct 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
 1772 static 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 
 1791 static 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 
 1800 static 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)
 1808 static 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 
 1822 template <typename T>
 1823 class Wrapper
 1824 {
 1825 public:
 1826     typedef T cl_type;
 1827 
 1828 protected:
 1829     cl_type object_;
 1830 
 1831 public:
 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 
 1888 protected:
 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 
 1903 template <>
 1904 class Wrapper<cl_device_id>
 1905 {
 1906 public:
 1907     typedef cl_device_id cl_type;
 1908 
 1909 protected:
 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 
 1925 public:
 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 
 1994 protected:
 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  */
 2030 struct 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  */
 2060 class Device : public detail::Wrapper<cl_device_id>
 2061 {
 2062 public:
 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  */
 2213 class Platform : public detail::Wrapper<cl_platform_id>
 2214 {
 2215 public:
 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  */
 2478 inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int
 2479 UnloadCompiler() CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
 2480 inline cl_int
 2481 UnloadCompiler()
 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  */
 2495 class Context 
 2496     : public detail::Wrapper<cl_context>
 2497 {
 2498 private:
 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_;
 2507 public:
 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 
 2828 inline 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
 2852 CL_WEAK_ATTRIB_PREFIX std::atomic<int> CL_WEAK_ATTRIB_SUFFIX Context::default_initialized_;
 2853 #else // !CL_HPP_CPP11_ATOMICS_SUPPORTED
 2854 CL_WEAK_ATTRIB_PREFIX volatile int CL_WEAK_ATTRIB_SUFFIX Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED;
 2855 #endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED
 2856 
 2857 CL_WEAK_ATTRIB_PREFIX Context CL_WEAK_ATTRIB_SUFFIX Context::default_;
 2858 CL_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  */
 2868 class Event : public detail::Wrapper<cl_event>
 2869 {
 2870 public:
 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  */
 2988 class UserEvent : public Event
 2989 {
 2990 public:
 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  */
 3030 inline static cl_int
 3031 WaitForEvents(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  */
 3047 class Memory : public detail::Wrapper<cl_mem>
 3048 {
 3049 public:
 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
 3154 class Buffer;
 3155 template< typename IteratorType >
 3156 cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
 3157 template< typename IteratorType >
 3158 cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
 3159 template< typename IteratorType >
 3160 cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
 3161 template< typename IteratorType >
 3162 cl_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  */
 3171 class Buffer : public Memory
 3172 {
 3173 public:
 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  */
 3381 class BufferD3D10 : public Buffer
 3382 {
 3383 public:
 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  */
 3487 class BufferGL : public Buffer
 3488 {
 3489 public:
 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  */
 3580 class Image : public Memory
 3581 {
 3582 protected:
 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 
 3632 public:
 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  */
 3664 class Image1D : public Image
 3665 {
 3666 public:
 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  */
 3753 class Image1DBuffer : public Image
 3754 {
 3755 public:
 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  */
 3830 class Image1DArray : public Image
 3831 {
 3832 public:
 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  */
 3916 class Image2D : public Image
 3917 {
 3918 public:
 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  */
 4049 class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED Image2DGL CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED : public Image2D
 4050 {
 4051 public:
 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  */
 4136 class Image2DArray : public Image
 4137 {
 4138 public:
 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  */
 4225 class Image3D : public Image
 4226 {
 4227 public:
 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  */
 4361 class Image3DGL : public Image3D
 4362 {
 4363 public:
 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  */
 4450 class ImageGL : public Image
 4451 {
 4452 public:
 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 */
 4526 class 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 {
 4533 public:
 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  */
 4658 class Sampler : public detail::Wrapper<cl_sampler>
 4659 {
 4660 public:
 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 
 4761 class Program;
 4762 class CommandQueue;
 4763 class Kernel;
 4764 
 4765 //! \brief Class interface for specifying NDRange values.
 4766 class NDRange
 4767 {
 4768 private:
 4769     size_t<3> sizes_;
 4770     cl_uint dimensions_;
 4771 
 4772 public:
 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.
 4815 static const NDRange NullRange;
 4816 
 4817 //! \brief Local address wrapper for use with Kernel::setArg
 4818 struct LocalSpaceArg
 4819 {
 4820     ::size_t size_;
 4821 };
 4822 
 4823 namespace detail {
 4824 
 4825 template <typename T>
 4826 struct KernelArgumentHandler
 4827 {
 4828     static ::size_t size(const T&) { return sizeof(T); }
 4829     static const T* ptr(const T& value) { return &value; }
 4830 };
 4831 
 4832 template <>
 4833 struct 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  */
 4846 inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED LocalSpaceArg
 4847 __local(::size_t size) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
 4848 inline 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  */
 4858 inline LocalSpaceArg
 4859 Local(::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  */
 4875 class Kernel : public detail::Wrapper<cl_kernel>
 4876 {
 4877 public:
 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  */
 5021 class Program : public detail::Wrapper<cl_program>
 5022 {
 5023 public:
 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)
 5392 inline 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 
 5428 inline 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 
 5472 template<>
 5473 inline 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 
 5492 inline 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  */
 5508 class CommandQueue : public detail::Wrapper<cl_command_queue>
 5509 {
 5510 private:
 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_;
 5518 public:
 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_,