<commit_before>#include <UtH\Platform\Graphics.hpp>
#include <UtH\Platform\Configuration.hpp>
#include <UtH\Platform\OpenGL.hpp>
#include <UtH\Platform\OGLCheck.hpp>
#include <iostream>

#ifdef _DEBUG
#pragma comment(lib, "freeglut_staticd.lib")
#pragma comment(lib, "glew32sd.lib")
#else // Release
// FIXME: Static 'Release' version of the GLEW lib breaks the build
// consider using dynamic linking for release
#pragma comment(lib, "freeglut_static.lib")
#pragma comment(lib, "glew32sd.lib")
#endif

namespace uth
{
    static int shaderTypes[SHADERTYPE_LAST] =           {GL_VERTEX_SHADER,
                                                         GL_FRAGMENT_SHADER};
    static int dataTypes[DATATYPE_LAST] =               {GL_BYTE,
                                                         GL_UNSIGNED_BYTE,
                                                         GL_SHORT,
                                                         GL_UNSIGNED_SHORT,
                                                         GL_INT,
                                                         GL_UNSIGNED_INT,
                                                         GL_FLOAT,
                                                         GL_DOUBLE};
    static int bufferTypes[BUFFERTYPE_LAST] =           {GL_ARRAY_BUFFER,
                                                         GL_READ_BUFFER,
                                                         GL_COPY_WRITE_BUFFER,
                                                         GL_ELEMENT_ARRAY_BUFFER,
                                                         GL_PIXEL_PACK_BUFFER,
                                                         GL_PIXEL_UNPACK_BUFFER,
                                                         GL_TEXTURE_BUFFER,
                                                         GL_TRANSFORM_FEEDBACK_BUFFER,
                                                         GL_UNIFORM_BUFFER};
    static int usageTypes[USAGETYPE_LAST] =             {GL_STREAM_DRAW,
                                                         GL_STREAM_READ,
                                                         GL_STREAM_COPY,
                                                         GL_STATIC_DRAW,
                                                         GL_STATIC_READ,
                                                         GL_STATIC_COPY,
                                                         GL_DYNAMIC_DRAW,
                                                         GL_DYNAMIC_READ,
                                                         GL_DYNAMIC_COPY};
    static int pixelStoreParams[PIXELSTOREPARAM_LAST] = {GL_PACK_SWAP_BYTES,
                                                         GL_PACK_LSB_FIRST,
                                                         GL_PACK_ROW_LENGTH,
                                                         GL_PACK_IMAGE_HEIGHT,
                                                         GL_PACK_SKIP_PIXELS,
                                                         GL_PACK_SKIP_ROWS,
                                                         GL_PACK_SKIP_IMAGES,
                                                         GL_PACK_ALIGNMENT,
                                                         GL_UNPACK_SWAP_BYTES,
                                                         GL_UNPACK_LSB_FIRST,
                                                         GL_UNPACK_ROW_LENGTH,
                                                         GL_UNPACK_IMAGE_HEIGHT,
                                                         GL_UNPACK_SKIP_PIXELS,
                                                         GL_UNPACK_SKIP_ROWS,
                                                         GL_UNPACK_SKIP_IMAGES,
                                                         GL_UNPACK_ALIGNMENT};
    static int textureTypes[TEXTURETYPE_LAST] =         {TEXTURE_1D,
                                                         TEXTURE_2D,
                                                         TEXTURE_3D,
                                                         TEXTURE_1D_ARRAY,
                                                         TEXTURE_2D_ARRAY,
                                                         TEXTURE_RECTANGLE,
                                                         TEXTURE_CUBE_MAP,
                                                         TEXTURE_2D_MULTISAMPLE,
                                                         TEXTURE_2D_MULTISAMPLE_ARRAY};
    static int imageFormats[IMAGEFORMAT_LAST] =         {GL_RGB,
                                                         GL_RGBA};
    static int textureParams[TEXTUREPARAM_LAST] =       {GL_TEXTURE_BASE_LEVEL,
                                                         GL_TEXTURE_COMPARE_FUNC,
                                                         GL_TEXTURE_COMPARE_MODE,
                                                         GL_TEXTURE_LOD_BIAS,
                                                         GL_TEXTURE_MIN_FILTER,
                                                         GL_TEXTURE_MAG_FILTER,
                                                         GL_TEXTURE_MIN_LOD,
                                                         GL_TEXTURE_MAX_LOD,
                                                         GL_TEXTURE_MAX_LEVEL,
                                                         GL_TEXTURE_SWIZZLE_R,
                                                         GL_TEXTURE_SWIZZLE_G,
                                                         GL_TEXTURE_SWIZZLE_B,
                                                         GL_TEXTURE_SWIZZLE_A,
                                                         GL_TEXTURE_WRAP_S,
                                                         GL_TEXTURE_WRAP_T,
                                                         GL_TEXTURE_WRAP_R};
    static int primitiveTypes[PRIMITIVETYPE_LAST] =     {GL_POINTS,
                                                         GL_LINE_STRIP,
                                                         GL_LINE_LOOP,
                                                         GL_LINES,
                                                         GL_LINE_STRIP_ADJACENCY,
                                                         GL_LINES_ADJACENCY,
                                                         GL_TRIANGLE_STRIP,
                                                         GL_TRIANGLE_FAN,
                                                         GL_TRIANGLES,
                                                         GL_TRIANGLE_STRIP_ADJACENCY,
                                                         GL_TRIANGLES_ADJACENCY};
    static int depthFunctions[DEPTHFUNCTION_LAST] =     {GL_NEVER,
                                                         GL_LESS,
                                                         GL_EQUAL,
                                                         GL_LEQUAL,
                                                         GL_GREATER,
                                                         GL_NOTEQUAL,
                                                         GL_GEQUAL,
                                                         GL_ALWAYS};
    static int blendFunctions[BLENDFUNCTION_LAST] =     {GL_ZERO,
                                                         GL_ONE,
                                                         GL_SRC_COLOR,
                                                         GL_ONE_MINUS_SRC_COLOR,
                                                         GL_DST_COLOR,
                                                         GL_ONE_MINUS_DST_COLOR,
                                                         GL_SRC_ALPHA,
                                                         GL_ONE_MINUS_SRC_ALPHA,
                                                         GL_DST_ALPHA,
                                                         GL_ONE_MINUS_DST_ALPHA,
                                                         GL_CONSTANT_COLOR,
                                                         GL_ONE_MINUS_CONSTANT_COLOR,
                                                         GL_CONSTANT_ALPHA,
                                                         GL_ONE_MINUS_CONSTANT_ALPHA};
    static int faceCullings[FACECULLING_LAST] =         {GL_FRONT,
                                                         GL_BACK,
                                                         GL_FRONT_AND_BACK};

    // Window functions
    bool Graphics::createWindow(const WindowSettings& settings)
    {
        if (m_windowHandle) destroyWindow();

        m_windowSettings = settings;

        // Context settings
        glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
        glutInitContextProfile(GLUT_CORE_PROFILE);

        // Extra settings
        glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);

        // Position & size
        glutInitWindowPosition(settings.position.x, settings.position.y);
        glutInitWindowSize(settings.size.x, settings.size.y);

        // Display settings
        glutInitDisplayMode(settings.useBlending ? GLUT_RGBA : GLUT_RGB |
                            settings.useDepthBuffer ? GLUT_DEPTH : 0x0 |
                            settings.useStencilBuffer ? GLUT_STENCIL : 0x0 |
                            settings.useDoubleBuffering ? GLUT_DOUBLE : GLUT_SINGLE);

        int majorVer = settings.contextVersionMajor,
            minorVer = settings.contextVersionMinor;

        glutInitContextVersion(settings.contextVersionMajor, settings.contextVersionMinor);
        m_windowHandle = glutCreateWindow("Generic Window Title");

		std::cout << "glew init might produces GL_INVALID_ENUM error. Just ignore it" << std::endl;
		glewExperimental = GL_TRUE;
        oglCheck(glewInit());

        return true;
    }

    void Graphics::destroyWindow()
    {
        oglCheck(glutDestroyWindow(m_windowHandle));
    }

    void Graphics::clear(const float r, const float g, const float b, const float a)
    {
        oglCheck(glClear(GL_COLOR_BUFFER_BIT |
                         GL_DEPTH_BUFFER_BIT |
                         GL_STENCIL_BUFFER_BIT));
		oglCheck(glClearColor(r, g, b, a));

        if (!m_windowSettings.useDepthBuffer) return;

		#ifdef UTH_SYSTEM_OPENGLES
			oglCheck(glClearDepthf(1));
		#else
			oglCheck(glClearDepth(1));
		#endif

        if (!m_windowSettings.useStencilBuffer) return;

        oglCheck(glClearStencil(1));
    }

    void Graphics::swapBuffers()
    {
        oglCheck(glutSwapBuffers());
    }

    void setViewport(const int x, const int y, const size_t width, const size_t height)
    {
        oglCheck(glViewport(x, y, width, height));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Shaders

    int Graphics::createShaderProgram()
    {
        return glCreateProgram();
    }

    bool Graphics::createShader(const ShaderType type, const int shaderProgram, const char* shaderCode)
    {
        if (!shaderCode) return false;

        unsigned int shader = glCreateShader(shaderTypes[type]);
        oglCheck(glShaderSource(shader, 1, &shaderCode, NULL));
        oglCheck(glCompileShader(shader));

		int infoLenght;
		oglCheck(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLenght));
		if(infoLenght > 1)
		{
			char* buf = new char[infoLenght];
			oglCheck(glGetShaderInfoLog(shader, infoLenght, NULL, buf));
			std::cout << buf << std::endl;
			delete buf;
		}

        int success;
		oglCheck(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));

		if (!success)
		{
            glDeleteShader(shader);

            return false;
        }

        oglCheck(glAttachShader(shaderProgram, shader));
        oglCheck(glDeleteShader(shader));

        return true;
    }

    bool Graphics::linkShaderProgram(const int shaderProgram)
    {
        oglCheck(glLinkProgram(shaderProgram));

        int success;
		oglCheck(glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success));

		if (!success)
		{
            destroyShaderProgram(shaderProgram);

			return false;
		}

		return true;
    }

    void Graphics::bindProgram(const int shaderProgram)
    {
        if (shaderProgram)
            oglCheck(glUseProgram(shaderProgram));
    }

    void unbindProgram()
    {
        oglCheck(glUseProgram(0));
    }

    void Graphics::destroyShaderProgram(const int shaderProgram)
    {
        oglCheck(glDeleteProgram(shaderProgram));
    }

    int Graphics::getUniformLocation(const int shaderProgram, const char* name)
    {
		return glGetUniformLocation(shaderProgram, name);
    }

    int Graphics::getAttributeLocation(const int shaderProgram, const char* name)
    {
        return glGetAttribLocation(shaderProgram, name);
    }

    void Graphics::setUniform(const int location, const float x)
    {
        oglCheck(glUniform1f(location, x));
    }

    void Graphics::setUniform(const int location, const float x, const float y)
    {
        oglCheck(glUniform2f(location, x, y));
    }

    void Graphics::setUniform(const int location, const float x, const float y, const float z)
    {
        oglCheck(glUniform3f(location, x, y, z));
    }

    void Graphics::setUniform(const int location, const float x, const float y, const float z, const float w)
    {
        oglCheck(glUniform4f(location, x, y, z, w));
    }

    void Graphics::setUniform(const int location, const umath::vector2& vector)
    {
        oglCheck(glUniform2fv(location, 1, &vector.x));
    }

    void Graphics::setUniform(const int location, const umath::vector3& vector)
    {
        oglCheck(glUniform3fv(location, 1, &vector.x));
    }

    void Graphics::setUniform(const int location, const umath::vector4& vector)
    {
        oglCheck(glUniform4fv(location, 1, &vector.x));
    }

    void Graphics::setUniform(const int location, const umath::matrix3& matrix)
    {
        oglCheck(glUniformMatrix3fv(location, 1, GL_FALSE, &matrix[0][0]));
    }

    void Graphics::setUniform(const int location, const umath::matrix4& matrix)
    {
        oglCheck(glUniformMatrix4fv(location, 1, GL_FALSE, &matrix[0][0]));
    }

    void Graphics::enableVertexAttribArray(const int location)
    {
        oglCheck(glEnableVertexAttribArray(location));
    }

    void Graphics::disableVertexAttribArray(const int location)
    {
        oglCheck(glDisableVertexAttribArray(location));
    }

    void Graphics::setVertexAttribPointer(const int location, const int size, DataType type, const int stride, const void* pointer)
    {
        oglCheck(glVertexAttribPointer(location, size, dataTypes[type], GL_FALSE, stride, pointer));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Buffers

    void generateBuffers(const unsigned int amount, unsigned int* buffers)
    {
        oglCheck(glGenBuffers(amount, buffers));
    }

    void deleteBuffers(const unsigned int amount, unsigned int* buffers)
    {
        oglCheck(glDeleteBuffers(amount, buffers));
    }

    void bindBuffer(BufferType type, const unsigned int buffer)
    {
        oglCheck(glBindBuffer(bufferTypes[type], buffer));
    }

    void setBufferData(BufferType type, const unsigned int size, const void* data, UsageType usageType)
    {
        oglCheck(glBufferData(bufferTypes[type], size, data, usageTypes[usageType]));
    }

    void setBufferSubData(BufferType type, const unsigned int offset, const unsigned int size, const void* data)
    {
        oglCheck(glBufferSubData(bufferTypes[type], offset, size, data));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Texture functions

    void setPixelStore(PixelStoreParam param, const int value)
    {
        oglCheck(glPixelStorei(pixelStoreParams[param], value));
    }

    void generateTextures(const unsigned int amount, unsigned int* data)
    {
        oglCheck(glGenTextures(amount, data));
    }

    void setActiveTexUnit(TexUnit unit)
    {
        oglCheck(glActiveTexture(unit));
    }

    void bindTexture(TextureType type, const int texture)
    {
        oglCheck(glBindTexture(textureTypes[type], texture));
    }

    void setTextureImage1D(const int level, ImageFormat imageFormat, const size_t width, ImageFormat pixelFormat, DataType dataType, const void* pixels)
    {
        oglCheck(glTexImage1D(textureTypes[TEXTURE_1D], level, imageFormats[imageFormat], width, 0, imageFormats[pixelFormat], dataTypes[dataType], pixels));
    }

    void setTextureImage2D(TextureType type, const int level, ImageFormat imageFormat, const size_t width, const size_t height, ImageFormat pixelFormat, DataType dataType, const void* pixels)
    {
        oglCheck(glTexImage2D(textureTypes[TEXTURE_2D], level, imageFormats[imageFormat], width, height, 0, imageFormats[pixelFormat], dataTypes[dataType], pixels));
    }

    void setTextureParameter(TextureType type, TextureParam param, const int value)
    {
        oglCheck(glTexParameteri(textureTypes[type], textureParams[param], value));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Drawing functions
    void drawArrays(PrimitiveType type, const int first, const size_t count)
    {
        oglCheck(glDrawArrays(primitiveTypes[type], first, count));
    }

    void drawElements(PrimitiveType type, const size_t count, DataType dataType, const void* indices)
    {
        oglCheck(glDrawElements(primitiveTypes[type], count, dataTypes[dataType], indices));
    }

    void setPointSize(const float size)
    {
        oglCheck(glPointSize(size));
    }

    void setLineWidth(const float width)
    {
        oglCheck(glLineWidth(width));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Other
    void flush()
    {
        oglCheck(glFlush());
    }

    void setDepthFunction(const bool enable, DepthFunction func)
    {
        static bool enabled = false;

        if (enable != enabled)
        {
            if (enable)
                oglCheck(glEnable(GL_DEPTH_TEST));
            else
                oglCheck(glDisable(GL_DEPTH_TEST));

            enabled = !enabled;
        }

        oglCheck(glDepthFunc(depthFunctions[func]));
    }

    void setBlendFunction(const bool enable, BlendFunction sfunc, BlendFunction dfunc)
    {
        static bool enabled = false;

        if (enable != enabled)
        {
            if (enable)
                oglCheck(glEnable(GL_BLEND));
            else
                oglCheck(glDisable(GL_BLEND));

            enabled = !enabled;
        }

        oglCheck(glBlendFunc(blendFunctions[sfunc], blendFunctions[dfunc]));
    }

    void setFaceCulling(const bool enable, FaceCulling mode)
    {
        static bool enabled = false;

        if (enable != enabled)
        {
            if (enable)
                oglCheck(glEnable(GL_CULL_FACE));
            else
                oglCheck(glDisable(GL_CULL_FACE));

            enabled = !enabled;
        }

        oglCheck(glCullFace(faceCullings[mode]));
    }

    // Private

    Graphics::Graphics()
        : m_windowHandle(0),
          m_windowSettings()
    {
        char* myargv[1];
        int myargc = 1;
        myargv[0] = strdup("UtH Engine");
        glutInit(&myargc, myargv);
    }

    Graphics::~Graphics()
    {
        destroyWindow();
    }
}<commit_msg>Made graphics.cpp functions actually be part of the graphics class.<commit_after>#include <UtH\Platform\Graphics.hpp>
#include <UtH\Platform\Configuration.hpp>
#include <UtH\Platform\OpenGL.hpp>
#include <UtH\Platform\OGLCheck.hpp>
#include <iostream>

#ifdef _DEBUG
#pragma comment(lib, "freeglut_staticd.lib")
#pragma comment(lib, "glew32sd.lib")
#else // Release
// FIXME: Static 'Release' version of the GLEW lib breaks the build
// consider using dynamic linking for release
#pragma comment(lib, "freeglut_static.lib")
#pragma comment(lib, "glew32sd.lib")
#endif

namespace uth
{
    static int shaderTypes[SHADERTYPE_LAST] =           {GL_VERTEX_SHADER,
                                                         GL_FRAGMENT_SHADER};
    static int dataTypes[DATATYPE_LAST] =               {GL_BYTE,
                                                         GL_UNSIGNED_BYTE,
                                                         GL_SHORT,
                                                         GL_UNSIGNED_SHORT,
                                                         GL_INT,
                                                         GL_UNSIGNED_INT,
                                                         GL_FLOAT,
                                                         GL_DOUBLE};
    static int bufferTypes[BUFFERTYPE_LAST] =           {GL_ARRAY_BUFFER,
                                                         GL_READ_BUFFER,
                                                         GL_COPY_WRITE_BUFFER,
                                                         GL_ELEMENT_ARRAY_BUFFER,
                                                         GL_PIXEL_PACK_BUFFER,
                                                         GL_PIXEL_UNPACK_BUFFER,
                                                         GL_TEXTURE_BUFFER,
                                                         GL_TRANSFORM_FEEDBACK_BUFFER,
                                                         GL_UNIFORM_BUFFER};
    static int usageTypes[USAGETYPE_LAST] =             {GL_STREAM_DRAW,
                                                         GL_STREAM_READ,
                                                         GL_STREAM_COPY,
                                                         GL_STATIC_DRAW,
                                                         GL_STATIC_READ,
                                                         GL_STATIC_COPY,
                                                         GL_DYNAMIC_DRAW,
                                                         GL_DYNAMIC_READ,
                                                         GL_DYNAMIC_COPY};
    static int pixelStoreParams[PIXELSTOREPARAM_LAST] = {GL_PACK_SWAP_BYTES,
                                                         GL_PACK_LSB_FIRST,
                                                         GL_PACK_ROW_LENGTH,
                                                         GL_PACK_IMAGE_HEIGHT,
                                                         GL_PACK_SKIP_PIXELS,
                                                         GL_PACK_SKIP_ROWS,
                                                         GL_PACK_SKIP_IMAGES,
                                                         GL_PACK_ALIGNMENT,
                                                         GL_UNPACK_SWAP_BYTES,
                                                         GL_UNPACK_LSB_FIRST,
                                                         GL_UNPACK_ROW_LENGTH,
                                                         GL_UNPACK_IMAGE_HEIGHT,
                                                         GL_UNPACK_SKIP_PIXELS,
                                                         GL_UNPACK_SKIP_ROWS,
                                                         GL_UNPACK_SKIP_IMAGES,
                                                         GL_UNPACK_ALIGNMENT};
    static int textureTypes[TEXTURETYPE_LAST] =         {TEXTURE_1D,
                                                         TEXTURE_2D,
                                                         TEXTURE_3D,
                                                         TEXTURE_1D_ARRAY,
                                                         TEXTURE_2D_ARRAY,
                                                         TEXTURE_RECTANGLE,
                                                         TEXTURE_CUBE_MAP,
                                                         TEXTURE_2D_MULTISAMPLE,
                                                         TEXTURE_2D_MULTISAMPLE_ARRAY};
    static int imageFormats[IMAGEFORMAT_LAST] =         {GL_RGB,
                                                         GL_RGBA};
    static int textureParams[TEXTUREPARAM_LAST] =       {GL_TEXTURE_BASE_LEVEL,
                                                         GL_TEXTURE_COMPARE_FUNC,
                                                         GL_TEXTURE_COMPARE_MODE,
                                                         GL_TEXTURE_LOD_BIAS,
                                                         GL_TEXTURE_MIN_FILTER,
                                                         GL_TEXTURE_MAG_FILTER,
                                                         GL_TEXTURE_MIN_LOD,
                                                         GL_TEXTURE_MAX_LOD,
                                                         GL_TEXTURE_MAX_LEVEL,
                                                         GL_TEXTURE_SWIZZLE_R,
                                                         GL_TEXTURE_SWIZZLE_G,
                                                         GL_TEXTURE_SWIZZLE_B,
                                                         GL_TEXTURE_SWIZZLE_A,
                                                         GL_TEXTURE_WRAP_S,
                                                         GL_TEXTURE_WRAP_T,
                                                         GL_TEXTURE_WRAP_R};
    static int primitiveTypes[PRIMITIVETYPE_LAST] =     {GL_POINTS,
                                                         GL_LINE_STRIP,
                                                         GL_LINE_LOOP,
                                                         GL_LINES,
                                                         GL_LINE_STRIP_ADJACENCY,
                                                         GL_LINES_ADJACENCY,
                                                         GL_TRIANGLE_STRIP,
                                                         GL_TRIANGLE_FAN,
                                                         GL_TRIANGLES,
                                                         GL_TRIANGLE_STRIP_ADJACENCY,
                                                         GL_TRIANGLES_ADJACENCY};
    static int depthFunctions[DEPTHFUNCTION_LAST] =     {GL_NEVER,
                                                         GL_LESS,
                                                         GL_EQUAL,
                                                         GL_LEQUAL,
                                                         GL_GREATER,
                                                         GL_NOTEQUAL,
                                                         GL_GEQUAL,
                                                         GL_ALWAYS};
    static int blendFunctions[BLENDFUNCTION_LAST] =     {GL_ZERO,
                                                         GL_ONE,
                                                         GL_SRC_COLOR,
                                                         GL_ONE_MINUS_SRC_COLOR,
                                                         GL_DST_COLOR,
                                                         GL_ONE_MINUS_DST_COLOR,
                                                         GL_SRC_ALPHA,
                                                         GL_ONE_MINUS_SRC_ALPHA,
                                                         GL_DST_ALPHA,
                                                         GL_ONE_MINUS_DST_ALPHA,
                                                         GL_CONSTANT_COLOR,
                                                         GL_ONE_MINUS_CONSTANT_COLOR,
                                                         GL_CONSTANT_ALPHA,
                                                         GL_ONE_MINUS_CONSTANT_ALPHA};
    static int faceCullings[FACECULLING_LAST] =         {GL_FRONT,
                                                         GL_BACK,
                                                         GL_FRONT_AND_BACK};

    // Window functions
    bool Graphics::createWindow(const WindowSettings& settings)
    {
        if (m_windowHandle) destroyWindow();

        m_windowSettings = settings;

        // Context settings
        glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
        glutInitContextProfile(GLUT_CORE_PROFILE);

        // Extra settings
        glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);

        // Position & size
        glutInitWindowPosition(settings.position.x, settings.position.y);
        glutInitWindowSize(settings.size.x, settings.size.y);

        // Display settings
        glutInitDisplayMode(settings.useBlending ? GLUT_RGBA : GLUT_RGB |
                            settings.useDepthBuffer ? GLUT_DEPTH : 0x0 |
                            settings.useStencilBuffer ? GLUT_STENCIL : 0x0 |
                            settings.useDoubleBuffering ? GLUT_DOUBLE : GLUT_SINGLE);

        int majorVer = settings.contextVersionMajor,
            minorVer = settings.contextVersionMinor;

        glutInitContextVersion(settings.contextVersionMajor, settings.contextVersionMinor);
        m_windowHandle = glutCreateWindow("Generic Window Title");

		std::cout << "glew init might produces GL_INVALID_ENUM error. Just ignore it" << std::endl;
		glewExperimental = GL_TRUE;
        oglCheck(glewInit());

        return true;
    }

    void Graphics::destroyWindow()
    {
        oglCheck(glutDestroyWindow(m_windowHandle));
    }

    void Graphics::clear(const float r, const float g, const float b, const float a)
    {
        oglCheck(glClear(GL_COLOR_BUFFER_BIT |
                         GL_DEPTH_BUFFER_BIT |
                         GL_STENCIL_BUFFER_BIT));
		oglCheck(glClearColor(r, g, b, a));

        if (!m_windowSettings.useDepthBuffer) return;

		#ifdef UTH_SYSTEM_OPENGLES
			oglCheck(glClearDepthf(1));
		#else
			oglCheck(glClearDepth(1));
		#endif

        if (!m_windowSettings.useStencilBuffer) return;

        oglCheck(glClearStencil(1));
    }

    void Graphics::swapBuffers()
    {
        oglCheck(glutSwapBuffers());
    }

    void setViewport(const int x, const int y, const size_t width, const size_t height)
    {
        oglCheck(glViewport(x, y, width, height));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Shaders

    int Graphics::createShaderProgram()
    {
        return glCreateProgram();
    }

    bool Graphics::createShader(const ShaderType type, const int shaderProgram, const char* shaderCode)
    {
        if (!shaderCode) return false;

        unsigned int shader = glCreateShader(shaderTypes[type]);
        oglCheck(glShaderSource(shader, 1, &shaderCode, NULL));
        oglCheck(glCompileShader(shader));

		int infoLenght;
		oglCheck(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLenght));
		if(infoLenght > 1)
		{
			char* buf = new char[infoLenght];
			oglCheck(glGetShaderInfoLog(shader, infoLenght, NULL, buf));
			std::cout << buf << std::endl;
			delete buf;
		}

        int success;
		oglCheck(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));

		if (!success)
		{
            glDeleteShader(shader);

            return false;
        }

        oglCheck(glAttachShader(shaderProgram, shader));
        oglCheck(glDeleteShader(shader));

        return true;
    }

    bool Graphics::linkShaderProgram(const int shaderProgram)
    {
        oglCheck(glLinkProgram(shaderProgram));

        int success;
		oglCheck(glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success));

		if (!success)
		{
            destroyShaderProgram(shaderProgram);

			return false;
		}

		return true;
    }

    void Graphics::bindProgram(const int shaderProgram)
    {
        if (shaderProgram)
            oglCheck(glUseProgram(shaderProgram));
    }

    void unbindProgram()
    {
        oglCheck(glUseProgram(0));
    }

    void Graphics::destroyShaderProgram(const int shaderProgram)
    {
        oglCheck(glDeleteProgram(shaderProgram));
    }

    int Graphics::getUniformLocation(const int shaderProgram, const char* name)
    {
		return glGetUniformLocation(shaderProgram, name);
    }

    int Graphics::getAttributeLocation(const int shaderProgram, const char* name)
    {
        return glGetAttribLocation(shaderProgram, name);
    }

    void Graphics::setUniform(const int location, const float x)
    {
        oglCheck(glUniform1f(location, x));
    }

    void Graphics::setUniform(const int location, const float x, const float y)
    {
        oglCheck(glUniform2f(location, x, y));
    }

    void Graphics::setUniform(const int location, const float x, const float y, const float z)
    {
        oglCheck(glUniform3f(location, x, y, z));
    }

    void Graphics::setUniform(const int location, const float x, const float y, const float z, const float w)
    {
        oglCheck(glUniform4f(location, x, y, z, w));
    }

    void Graphics::setUniform(const int location, const umath::vector2& vector)
    {
        oglCheck(glUniform2fv(location, 1, &vector.x));
    }

    void Graphics::setUniform(const int location, const umath::vector3& vector)
    {
        oglCheck(glUniform3fv(location, 1, &vector.x));
    }

    void Graphics::setUniform(const int location, const umath::vector4& vector)
    {
        oglCheck(glUniform4fv(location, 1, &vector.x));
    }

    void Graphics::setUniform(const int location, const umath::matrix3& matrix)
    {
        oglCheck(glUniformMatrix3fv(location, 1, GL_FALSE, &matrix[0][0]));
    }

    void Graphics::setUniform(const int location, const umath::matrix4& matrix)
    {
        oglCheck(glUniformMatrix4fv(location, 1, GL_FALSE, &matrix[0][0]));
    }

    void Graphics::enableVertexAttribArray(const int location)
    {
        oglCheck(glEnableVertexAttribArray(location));
    }

    void Graphics::disableVertexAttribArray(const int location)
    {
        oglCheck(glDisableVertexAttribArray(location));
    }

    void Graphics::setVertexAttribPointer(const int location, const int size, DataType type, const int stride, const void* pointer)
    {
        oglCheck(glVertexAttribPointer(location, size, dataTypes[type], GL_FALSE, stride, pointer));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Buffers

    void Graphics::generateBuffers(const unsigned int amount, unsigned int* buffers)
    {
        oglCheck(glGenBuffers(amount, buffers));
    }

    void Graphics::deleteBuffers(const unsigned int amount, unsigned int* buffers)
    {
        oglCheck(glDeleteBuffers(amount, buffers));
    }

    void Graphics::bindBuffer(BufferType type, const unsigned int buffer)
    {
        oglCheck(glBindBuffer(bufferTypes[type], buffer));
    }

    void Graphics::setBufferData(BufferType type, const unsigned int size, const void* data, UsageType usageType)
    {
        oglCheck(glBufferData(bufferTypes[type], size, data, usageTypes[usageType]));
    }

    void Graphics::setBufferSubData(BufferType type, const unsigned int offset, const unsigned int size, const void* data)
    {
        oglCheck(glBufferSubData(bufferTypes[type], offset, size, data));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Texture functions

    void Graphics::setPixelStore(PixelStoreParam param, const int value)
    {
        oglCheck(glPixelStorei(pixelStoreParams[param], value));
    }

    void Graphics::generateTextures(const unsigned int amount, unsigned int* data)
    {
        oglCheck(glGenTextures(amount, data));
    }

    void Graphics::setActiveTexUnit(TexUnit unit)
    {
        oglCheck(glActiveTexture(unit));
    }

    void Graphics::bindTexture(TextureType type, const int texture)
    {
        oglCheck(glBindTexture(textureTypes[type], texture));
    }

    void Graphics::setTextureImage1D(const int level, ImageFormat imageFormat, const size_t width, ImageFormat pixelFormat, DataType dataType, const void* pixels)
    {
        oglCheck(glTexImage1D(textureTypes[TEXTURE_1D], level, imageFormats[imageFormat], width, 0, imageFormats[pixelFormat], dataTypes[dataType], pixels));
    }

    void Graphics::setTextureImage2D(TextureType type, const int level, ImageFormat imageFormat, const size_t width, const size_t height, ImageFormat pixelFormat, DataType dataType, const void* pixels)
    {
        oglCheck(glTexImage2D(textureTypes[TEXTURE_2D], level, imageFormats[imageFormat], width, height, 0, imageFormats[pixelFormat], dataTypes[dataType], pixels));
    }

    void Graphics::setTextureParameter(TextureType type, TextureParam param, const int value)
    {
        oglCheck(glTexParameteri(textureTypes[type], textureParams[param], value));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Drawing functions
    void Graphics::drawArrays(PrimitiveType type, const int first, const size_t count)
    {
        oglCheck(glDrawArrays(primitiveTypes[type], first, count));
    }

    void Graphics::drawElements(PrimitiveType type, const size_t count, DataType dataType, const void* indices)
    {
        oglCheck(glDrawElements(primitiveTypes[type], count, dataTypes[dataType], indices));
    }

    void Graphics::setPointSize(const float size)
    {
        oglCheck(glPointSize(size));
    }

    void Graphics::setLineWidth(const float width)
    {
        oglCheck(glLineWidth(width));
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Other
    void Graphics::flush()
    {
        oglCheck(glFlush());
    }

    void Graphics::setDepthFunction(const bool enable, DepthFunction func)
    {
        static bool enabled = false;

        if (enable != enabled)
        {
            if (enable)
                oglCheck(glEnable(GL_DEPTH_TEST));
            else
                oglCheck(glDisable(GL_DEPTH_TEST));

            enabled = !enabled;
        }

        oglCheck(glDepthFunc(depthFunctions[func]));
    }

    void Graphics::setBlendFunction(const bool enable, BlendFunction sfunc, BlendFunction dfunc)
    {
        static bool enabled = false;

        if (enable != enabled)
        {
            if (enable)
                oglCheck(glEnable(GL_BLEND));
            else
                oglCheck(glDisable(GL_BLEND));

            enabled = !enabled;
        }

        oglCheck(glBlendFunc(blendFunctions[sfunc], blendFunctions[dfunc]));
    }

    void Graphics::setFaceCulling(const bool enable, FaceCulling mode)
    {
        static bool enabled = false;

        if (enable != enabled)
        {
            if (enable)
                oglCheck(glEnable(GL_CULL_FACE));
            else
                oglCheck(glDisable(GL_CULL_FACE));

            enabled = !enabled;
        }

        oglCheck(glCullFace(faceCullings[mode]));
    }

    // Private

    Graphics::Graphics()
        : m_windowHandle(0),
          m_windowSettings()
    {
        char* myargv[1];
        int myargc = 1;
        myargv[0] = strdup("UtH Engine");
        glutInit(&myargc, myargv);
    }

    Graphics::~Graphics()
    {
        destroyWindow();
    }
}<|endoftext|>


<commit_before>/* string_functions.cc
   Jeremy Barnes, 7 February 2005
   Copyright (c) 2005 Jeremy Barnes.  All rights reserved.

   This file is part of "Jeremy's Machine Learning Library", copyright (c)
   1999-2005 Jeremy Barnes.

   This program is available under the GNU General Public License, the terms
   of which are given by the file "license.txt" in the top level directory of
   the source code distribution.  If this file is missing, you have no right
   to use the program; please contact the author.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   for more details.

   ---

   String manipulation functions.
*/

#include "string_functions.h"
#include <stdarg.h>
#include <stdio.h>
#include "jml/arch/exception.h"
#include <sys/errno.h>
#include <stdlib.h>

using namespace std;

namespace ML {

struct va_ender {
    va_ender(va_list & ap)
        : ap(ap)
    {
    }

    ~va_ender()
    {
        va_end(ap);
    }

    va_list & ap;
};

std::string format(const char * fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    try {
        string result = vformat(fmt, ap);
        va_end(ap);
        return result;
    }
    catch (...) {
        va_end(ap);
        throw;
    }
}

std::string vformat(const char * fmt, va_list ap)
{
    char * mem;
    string result;
    int res = vasprintf(&mem, fmt, ap);
    if (res < 0)
        throw Exception(errno, "vasprintf", "format()");

    try {
        result = mem;
        free(mem);
        return result;
    }
    catch (...) {
        free(mem);
        throw;
    }
}

std::vector<std::string> split(const std::string & str, char c)
{
    vector<string> result;
    size_t start = 0;
    size_t pos = 0;
    while (pos < str.size()) {
        if (str[pos] == c) {
            result.push_back(string(str, start, pos - start));
            start = pos + 1;
        }
        ++pos;
    }

    if (start < str.size())
        result.push_back(string(str, start, pos - start));

    return result;
}

std::string lowercase(const std::string & str)
{
    string result = str;
    for (unsigned i = 0;  i < str.size();  ++i)
        result[i] = tolower(result[i]);
    return result;
}

std::string remove_trailing_whitespace(const std::string & str)
{
    int startOfSpace = -1;
    for (unsigned i = 0;  i < str.length();  ++i) {
        if (isspace(str[i])) {
            if (startOfSpace == -1) startOfSpace = i;
        }
        else startOfSpace = -1;
    }

    if (startOfSpace == -1) return str;
    return string(str, 0, startOfSpace);
}

bool removeIfEndsWith(std::string & str, const std::string & ending)
{
    if (str.rfind(ending) == str.size() - ending.length()) {
        str = string(str, 0, str.size() - ending.length());
        return true;
    }

    return false;
}

bool endsWith(const std::string & haystack, const std::string & needle)
{
    string::size_type result = haystack.rfind(needle);
    return result != string::npos
        && result == haystack.size() - needle.size();
}

std::string hexify_string(const std::string & str)
{
    size_t i, len(str.size());
    std::string newString;
    newString.reserve(len * 3);

    for (i = 0; i < len; i++) {
        if (str[i] < 32 || str[i] > 127) {
            newString += format("\\x%.2x", int(str[i] & 0xff));
        }
        else {
            newString += str[i];
        }
    }

    return newString;
}

int
antoi(const char * start, const char * end, int base)
{
    int result(0);
    bool neg = false;
    if (*start == '-') {
        if (base == 10) {
            neg = true;
        }
        else {
            throw ML::Exception("Cannot negate non base 10");
        }
    }

    for (const char * ptr = start + neg; ptr < end; ptr++) {
        int digit;
        if (*ptr >= '0' and *ptr <= '9') {
            digit = *ptr - '0';
        }
        else if (*ptr >= 'A' and *ptr <= 'F') {
            digit = *ptr - 'A' + 10;
        }
        else if (*ptr >= 'a' and *ptr <= 'f') {
            digit = *ptr - 'a' + 10;
        }
        else {
            throw ML::Exception("expected digit");
        }
        if (digit > base) {
            intptr_t offset = ptr - start;
            throw ML::Exception("digit '%c' (%d) exceeds base '%d'"
                                " at offset '%d'",
                                *ptr, digit, base, offset);
        }
        result = result * base + digit;
    }

    if (neg) {
        return result * -1;
    }
    return result;
}

} // namespace ML
<commit_msg>antoi: accept numbers starting with "+"<commit_after>/* string_functions.cc
   Jeremy Barnes, 7 February 2005
   Copyright (c) 2005 Jeremy Barnes.  All rights reserved.

   This file is part of "Jeremy's Machine Learning Library", copyright (c)
   1999-2005 Jeremy Barnes.

   This program is available under the GNU General Public License, the terms
   of which are given by the file "license.txt" in the top level directory of
   the source code distribution.  If this file is missing, you have no right
   to use the program; please contact the author.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   for more details.

   ---

   String manipulation functions.
*/

#include "string_functions.h"
#include <stdarg.h>
#include <stdio.h>
#include "jml/arch/exception.h"
#include <sys/errno.h>
#include <stdlib.h>

using namespace std;

namespace ML {

struct va_ender {
    va_ender(va_list & ap)
        : ap(ap)
    {
    }

    ~va_ender()
    {
        va_end(ap);
    }

    va_list & ap;
};

std::string format(const char * fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    try {
        string result = vformat(fmt, ap);
        va_end(ap);
        return result;
    }
    catch (...) {
        va_end(ap);
        throw;
    }
}

std::string vformat(const char * fmt, va_list ap)
{
    char * mem;
    string result;
    int res = vasprintf(&mem, fmt, ap);
    if (res < 0)
        throw Exception(errno, "vasprintf", "format()");

    try {
        result = mem;
        free(mem);
        return result;
    }
    catch (...) {
        free(mem);
        throw;
    }
}

std::vector<std::string> split(const std::string & str, char c)
{
    vector<string> result;
    size_t start = 0;
    size_t pos = 0;
    while (pos < str.size()) {
        if (str[pos] == c) {
            result.push_back(string(str, start, pos - start));
            start = pos + 1;
        }
        ++pos;
    }

    if (start < str.size())
        result.push_back(string(str, start, pos - start));

    return result;
}

std::string lowercase(const std::string & str)
{
    string result = str;
    for (unsigned i = 0;  i < str.size();  ++i)
        result[i] = tolower(result[i]);
    return result;
}

std::string remove_trailing_whitespace(const std::string & str)
{
    int startOfSpace = -1;
    for (unsigned i = 0;  i < str.length();  ++i) {
        if (isspace(str[i])) {
            if (startOfSpace == -1) startOfSpace = i;
        }
        else startOfSpace = -1;
    }

    if (startOfSpace == -1) return str;
    return string(str, 0, startOfSpace);
}

bool removeIfEndsWith(std::string & str, const std::string & ending)
{
    if (str.rfind(ending) == str.size() - ending.length()) {
        str = string(str, 0, str.size() - ending.length());
        return true;
    }

    return false;
}

bool endsWith(const std::string & haystack, const std::string & needle)
{
    string::size_type result = haystack.rfind(needle);
    return result != string::npos
        && result == haystack.size() - needle.size();
}

std::string hexify_string(const std::string & str)
{
    size_t i, len(str.size());
    std::string newString;
    newString.reserve(len * 3);

    for (i = 0; i < len; i++) {
        if (str[i] < 32 || str[i] > 127) {
            newString += format("\\x%.2x", int(str[i] & 0xff));
        }
        else {
            newString += str[i];
        }
    }

    return newString;
}

int
antoi(const char * start, const char * end, int base)
{
    int result(0);
    bool neg = false;
    if (*start == '-') {
        if (base == 10) {
            neg = true;
        }
        else {
            throw ML::Exception("Cannot negate non base 10");
        }
        start++;
    }
    else if (*start == '+') {
        start++;
    }

    for (const char * ptr = start; ptr < end; ptr++) {
        int digit;
        if (*ptr >= '0' and *ptr <= '9') {
            digit = *ptr - '0';
        }
        else if (*ptr >= 'A' and *ptr <= 'F') {
            digit = *ptr - 'A' + 10;
        }
        else if (*ptr >= 'a' and *ptr <= 'f') {
            digit = *ptr - 'a' + 10;
        }
        else {
            throw ML::Exception("expected digit");
        }
        if (digit > base) {
            intptr_t offset = ptr - start;
            throw ML::Exception("digit '%c' (%d) exceeds base '%d'"
                                " at offset '%d'",
                                *ptr, digit, base, offset);
        }
        result = result * base + digit;
    }

    if (neg) {
        return result * -1;
    }

    return result;
}

} // namespace ML
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <iostream>

#include "itkImageRegionIteratorWithIndex.h"
#include "itkNumericTraits.h"

template <typename TPixelType>
class itkImageIteratorWithIndexTestIteratorTester
{

  public:
    typedef TPixelType                  PixelType;

    typedef itk::Image< PixelType, 3 > ImageType;

    typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;

    typedef itk::ImageRegionConstIteratorWithIndex< ImageType > ConstIteratorType;

    itkImageIteratorWithIndexTestIteratorTester( const PixelType & value )
    {
      m_Image = ImageType::New();

      typename ImageType::SizeType size;
      size.Fill(100);

      typename ImageType::IndexType start;
      start.Fill(0);

      typename ImageType::RegionType region;
      region.SetSize( size );
      region.SetIndex( start );

      m_Image->SetRegions( region );
      m_Image->Allocate();

      m_Image->FillBuffer( value );
    }

    bool TestIterator()
    {
     IteratorType it( m_Image, m_Image->GetBufferedRegion() );
     it.GoToBegin();
     while( !it.IsAtEnd() )
       {
       PixelType value = it.Get();
       PixelType testValue = value * static_cast<typename itk::NumericTraits<PixelType>::ValueType>( 2 );
       it.Set( testValue);
       if( it.Get() != testValue )
        {
        std::cerr << "TestIterator failed!" << std::endl;
        return false;
        }
       ++it;
       }
     return true;
    }

    bool TestConstIterator()
    {
     ConstIteratorType it( m_Image, m_Image->GetBufferedRegion() );
     it.GoToBegin();
     while( !it.IsAtEnd() )
       {
       PixelType value = it.Get();
       if( value != it.Get() ) // check repeatibility
         {
         std::cerr << "TestConstIterator failed!" << std::endl;
         return false;
         }
       ++it;
       }
     return true;
    }

  private:

    typename ImageType::Pointer m_Image;

};

int itkImageIteratorWithIndexTest(int, char* [] )
{

  bool testPassed = true; // let's be optimistic

  // Instantiate image of various types and
  // test the iterators on them

  std::cout << "Testing with Image< char, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< char > TesterC( 10 );
  if( TesterC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterC.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< unsigned char, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< unsigned char > TesterUC( 10 );
  if( TesterUC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUC.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< short, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< short > TesterS( 10 );
  if( TesterS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterS.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< unsigned short, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< unsigned short > TesterUS( 10 );
  if( TesterUS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUS.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< int, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< int > TesterI( 10 );
  if( TesterI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterI.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< unsigned int, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< unsigned int > TesterUI( 10 );
  if( TesterUI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUI.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< float, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< float > TesterF( 10.0 );
  if( TesterF.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterF.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< double, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< double > TesterD( 10.0 );
  if( TesterD.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterD.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<char,4>, 3 > " << std::endl;
  typedef itk::Vector<char,4> VC;
  VC vc;
  vc.Fill( 127 );
  itkImageIteratorWithIndexTestIteratorTester< VC > TesterVC( vc );
  if( TesterVC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVC.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<unsigned char,4>, 3 > " << std::endl;
  typedef itk::Vector<unsigned char,4> VUC;
  VUC vuc;
  vuc.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VUC > TesterVUC( vuc );
  if( TesterVUC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUC.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<short,4>, 3 > " << std::endl;
  typedef itk::Vector<short,4> VS;
  VS vs;
  vs.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VS > TesterVS( vs );
  if( TesterVS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVS.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<unsigned short,4>, 3 > " << std::endl;
  typedef itk::Vector<unsigned short,4> VUS;
  VUS vus;
  vus.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VUS > TesterVUS( vus );
  if( TesterVUS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUS.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<int,4>, 3 > " << std::endl;
  typedef itk::Vector<int,4> VI;
  VI vi;
  vi.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VI > TesterVI( vi );
  if( TesterVI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVI.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<unsigned int,4>, 3 > " << std::endl;
  typedef itk::Vector<unsigned int,4> VUI;
  VUI vui;
  vui.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VUI > TesterVUI( vui );
  if( TesterVUI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUI.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<float,4>, 3 > " << std::endl;
  typedef itk::Vector<float,4> VF;
  VF vf;
  vf.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VF > TesterVF( vf );
  if( TesterVF.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVF.TestConstIterator() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<double,4>, 3 > " << std::endl;
  typedef itk::Vector<double,4> VD;
  VD vd;
  vd.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VD > TesterVD( vd );
  if( TesterVD.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVD.TestConstIterator() == false )
    {
    testPassed = false;
    }

  if ( !testPassed )
    {
    std::cout << "Failed" << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Success" << std::endl;
  return EXIT_SUCCESS;

}
<commit_msg>ENH: adding reverse iteration test<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <iostream>

#include "itkImageRegionIteratorWithIndex.h"
#include "itkNumericTraits.h"

template <typename TPixelType>
class itkImageIteratorWithIndexTestIteratorTester
{

  public:
    typedef TPixelType                  PixelType;

    typedef itk::Image< PixelType, 3 > ImageType;

    typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;

    typedef itk::ImageRegionConstIteratorWithIndex< ImageType > ConstIteratorType;

    itkImageIteratorWithIndexTestIteratorTester( const PixelType & value )
    {
      m_Image = ImageType::New();

      typename ImageType::SizeType size;
      size.Fill(100);

      typename ImageType::IndexType start;
      start.Fill(0);

      typename ImageType::RegionType region;
      region.SetSize( size );
      region.SetIndex( start );

      m_Image->SetRegions( region );
      m_Image->Allocate();

      m_Image->FillBuffer( value );
    }

    bool TestIterator()
    {
     IteratorType it( m_Image, m_Image->GetBufferedRegion() );
     itk::SizeValueType i = 0;
     it.GoToBegin();
     while( !it.IsAtEnd() )
       {
       PixelType value = it.Get();
       PixelType testValue = value * static_cast<typename itk::NumericTraits<PixelType>::ValueType>( 2 );
       it.Set( testValue);
       if( it.Get() != testValue )
        {
        std::cerr << "TestIterator failed!" << std::endl;
        return false;
        }
       ++it;
       i++;
       }
     if (i != m_Image->GetBufferedRegion().GetNumberOfPixels())
       {
       std::cerr << "TestConstIterator failed (NumberOfPixels)!" << std::endl;
       return false;
       }
     return true;
    }

    bool TestConstIterator()
    {
     ConstIteratorType it( m_Image, m_Image->GetBufferedRegion() );
     itk::SizeValueType i = 0;
     it.GoToBegin();
     while( !it.IsAtEnd() )
       {
       PixelType value = it.Get();
       if( value != it.Get() ) // check repeatibility
         {
         std::cerr << "TestConstIterator failed!" << std::endl;
         return false;
         }
       ++it;
       i++;
       }
     if (i != m_Image->GetBufferedRegion().GetNumberOfPixels())
       {
       std::cerr << "TestConstIterator failed (NumberOfPixels)!" << std::endl;
       return false;
       }
     return true;
    }

    bool TestReverseIteration()
    {
     ConstIteratorType it( m_Image, m_Image->GetBufferedRegion() );
     itk::SizeValueType i = 0;
     it.GoToReverseBegin();
     while( !it.IsAtReverseEnd() )
       {
       PixelType value = it.Get();
       if( value != it.Get() ) // check repeatibility
         {
         std::cerr << "TestReverseIteration failed!" << std::endl;
         return false;
         }
       --it;
       i++;
       }
     if (i != m_Image->GetBufferedRegion().GetNumberOfPixels())
       {
       std::cerr << "TestConstIterator failed (NumberOfPixels)!" << std::endl;
       return false;
       }
     return true;
    }

  private:

    typename ImageType::Pointer m_Image;

};

int itkImageIteratorWithIndexTest(int, char* [] )
{

  bool testPassed = true; // let's be optimistic

  // Instantiate image of various types and
  // test the iterators on them

  std::cout << "Testing with Image< char, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< char > TesterC( 10 );
  if( TesterC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterC.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterC.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< unsigned char, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< unsigned char > TesterUC( 10 );
  if( TesterUC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUC.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUC.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< short, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< short > TesterS( 10 );
  if( TesterS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterS.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterS.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< unsigned short, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< unsigned short > TesterUS( 10 );
  if( TesterUS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUS.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUS.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< int, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< int > TesterI( 10 );
  if( TesterI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterI.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterI.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< unsigned int, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< unsigned int > TesterUI( 10 );
  if( TesterUI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUI.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterUI.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< float, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< float > TesterF( 10.0 );
  if( TesterF.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterF.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterF.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< double, 3 > " << std::endl;
  itkImageIteratorWithIndexTestIteratorTester< double > TesterD( 10.0 );
  if( TesterD.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterD.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterD.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<char,4>, 3 > " << std::endl;
  typedef itk::Vector<char,4> VC;
  VC vc;
  vc.Fill( 127 );
  itkImageIteratorWithIndexTestIteratorTester< VC > TesterVC( vc );
  if( TesterVC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVC.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVC.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<unsigned char,4>, 3 > " << std::endl;
  typedef itk::Vector<unsigned char,4> VUC;
  VUC vuc;
  vuc.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VUC > TesterVUC( vuc );
  if( TesterVUC.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUC.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUC.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<short,4>, 3 > " << std::endl;
  typedef itk::Vector<short,4> VS;
  VS vs;
  vs.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VS > TesterVS( vs );
  if( TesterVS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVS.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVS.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<unsigned short,4>, 3 > " << std::endl;
  typedef itk::Vector<unsigned short,4> VUS;
  VUS vus;
  vus.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VUS > TesterVUS( vus );
  if( TesterVUS.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUS.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUS.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<int,4>, 3 > " << std::endl;
  typedef itk::Vector<int,4> VI;
  VI vi;
  vi.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VI > TesterVI( vi );
  if( TesterVI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVI.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVI.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<unsigned int,4>, 3 > " << std::endl;
  typedef itk::Vector<unsigned int,4> VUI;
  VUI vui;
  vui.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VUI > TesterVUI( vui );
  if( TesterVUI.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUI.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVUI.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<float,4>, 3 > " << std::endl;
  typedef itk::Vector<float,4> VF;
  VF vf;
  vf.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VF > TesterVF( vf );
  if( TesterVF.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVF.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVF.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  std::cout << "Testing with Image< itk::Vector<double,4>, 3 > " << std::endl;
  typedef itk::Vector<double,4> VD;
  VD vd;
  vd.Fill( 10 );
  itkImageIteratorWithIndexTestIteratorTester< VD > TesterVD( vd );
  if( TesterVD.TestIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVD.TestConstIterator() == false )
    {
    testPassed = false;
    }
  if( TesterVD.TestReverseIteration() == false )
    {
    testPassed = false;
    }

  if ( !testPassed )
    {
    std::cout << "Failed" << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Success" << std::endl;
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>

#include <mitkPAMonteCarloThreadHandler.h>

// us
#include <usModule.h>
#include <usModuleResource.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
#include <usModuleResourceStream.h>

#include <random>
#include <chrono>

class mitkMCThreadHandlerTestSuite : public mitk::TestFixture
{
  CPPUNIT_TEST_SUITE(mitkMCThreadHandlerTestSuite);
  MITK_TEST(testConstructorBehavior);
  MITK_TEST(testCorrectNumberOfPhotons);
  MITK_TEST(testCorrectNumberOfPhotonsWithUnevenPackageSize);
  MITK_TEST(testCorrectNumberOfPhotonsWithTooLargePackageSize);
  MITK_TEST(testCorrectTimeMeasure);
  CPPUNIT_TEST_SUITE_END();

private:

  mitk::pa::MonteCarloThreadHandler::Pointer m_MonteCarloThreadHandler;
  long m_NumberOrTime = 500;

public:

  void setUp() override
  {
  }

  void testConstructorBehavior()
  {
    auto threadHandler1 = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true, true);
    auto threadHandler2 = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true);

    CPPUNIT_ASSERT(mitk::pa::Equal(threadHandler1, threadHandler2, 1e-6, true));
  }

  void testCorrectTimeMeasure()
  {
    for (int i = 0; i < 10; i++)
    {
      m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true, false);
      auto timeBefore = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
      long nextWorkPackage = 0;
      while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
      {//Do nothing
      }
      auto timeAfter = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();

      //Assert that the time error is less than 10% in a 500ms sample size
      //This test might not be stable when on different machines.
      CPPUNIT_ASSERT(std::abs((timeAfter - timeBefore) - m_NumberOrTime) <= 50);
    }
  }

  void testCorrectNumberOfPhotons()
  {
    m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false);
    m_MonteCarloThreadHandler->SetPackageSize(100);
    long numberOfPhotonsSimulated = 0;
    long nextWorkPackage = 0;
    while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
    {
      numberOfPhotonsSimulated += nextWorkPackage;
    }
    CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime);
  }

  void testCorrectNumberOfPhotonsWithUnevenPackageSize()
  {
    m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false);
    m_MonteCarloThreadHandler->SetPackageSize(77);
    long numberOfPhotonsSimulated = 0;
    long nextWorkPackage = 0;
    while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
    {
      numberOfPhotonsSimulated += nextWorkPackage;
    }
    CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime);
  }

  void testCorrectNumberOfPhotonsWithTooLargePackageSize()
  {
    m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false);
    m_MonteCarloThreadHandler->SetPackageSize(10000);
    long numberOfPhotonsSimulated = 0;
    long nextWorkPackage = 0;
    while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
    {
      numberOfPhotonsSimulated += nextWorkPackage;
    }
    CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime);
  }

  void tearDown() override
  {
    m_MonteCarloThreadHandler = nullptr;
  }
};

MITK_TEST_SUITE_REGISTRATION(mitkMCThreadHandler)
<commit_msg>Fixed some warnings<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>

#include <mitkPAMonteCarloThreadHandler.h>

// us
#include <usModule.h>
#include <usModuleResource.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
#include <usModuleResourceStream.h>

#include <random>
#include <chrono>

class mitkMCThreadHandlerTestSuite : public mitk::TestFixture
{
  CPPUNIT_TEST_SUITE(mitkMCThreadHandlerTestSuite);
  MITK_TEST(testConstructorBehavior);
  MITK_TEST(testCorrectNumberOfPhotons);
  MITK_TEST(testCorrectNumberOfPhotonsWithUnevenPackageSize);
  MITK_TEST(testCorrectNumberOfPhotonsWithTooLargePackageSize);
  MITK_TEST(testCorrectTimeMeasure);
  CPPUNIT_TEST_SUITE_END();

private:

  mitk::pa::MonteCarloThreadHandler::Pointer m_MonteCarloThreadHandler;
  long m_NumberOrTime = 500;

public:

  void setUp() override
  {
  }

  void testConstructorBehavior()
  {
    auto threadHandler1 = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true, true);
    auto threadHandler2 = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true);

    CPPUNIT_ASSERT(mitk::pa::Equal(threadHandler1, threadHandler2, 1e-6, true));
  }

  void testCorrectTimeMeasure()
  {
    for (int i = 0; i < 10; i++)
    {
      m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true, false);
      auto timeBefore = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
      long nextWorkPackage = 0;
      while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
      {//Do nothing
      }
      auto timeAfter = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();

      //Assert that the time error is less than 10% in a 500ms sample size
      //This test might not be stable when on different machines.
      CPPUNIT_ASSERT(std::labs((timeAfter - timeBefore) - m_NumberOrTime) <= 50);
    }
  }

  void testCorrectNumberOfPhotons()
  {
    m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false);
    m_MonteCarloThreadHandler->SetPackageSize(100);
    long numberOfPhotonsSimulated = 0;
    long nextWorkPackage = 0;
    while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
    {
      numberOfPhotonsSimulated += nextWorkPackage;
    }
    CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime);
  }

  void testCorrectNumberOfPhotonsWithUnevenPackageSize()
  {
    m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false);
    m_MonteCarloThreadHandler->SetPackageSize(77);
    long numberOfPhotonsSimulated = 0;
    long nextWorkPackage = 0;
    while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
    {
      numberOfPhotonsSimulated += nextWorkPackage;
    }
    CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime);
  }

  void testCorrectNumberOfPhotonsWithTooLargePackageSize()
  {
    m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false);
    m_MonteCarloThreadHandler->SetPackageSize(10000);
    long numberOfPhotonsSimulated = 0;
    long nextWorkPackage = 0;
    while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0)
    {
      numberOfPhotonsSimulated += nextWorkPackage;
    }
    CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime);
  }

  void tearDown() override
  {
    m_MonteCarloThreadHandler = nullptr;
  }
};

MITK_TEST_SUITE_REGISTRATION(mitkMCThreadHandler)
<|endoftext|>


<commit_before><commit_msg>cppcheck: variableScope<commit_after><|endoftext|>


<commit_before>//_____________________________________________________________________
AliAnalysisTask *AddTaskJFFlucMapMaster(TString taskName="JFFlucMaster", UInt_t period = 0, double ptmin = 0.5){
	// Load Custom Configuration and parameters
	enum { lhc15o=0, lhc18q=1, lhc18r=2 };
	cout << "AddTaskJFFlucMapMaster:: period=" << period <<"\t ptmin="<< ptmin << endl;
	AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
	//-------- Correction Maps ----------

	if(period == lhc18q) {
		AliJCorrectionMapTask *cmaptask = new AliJCorrectionMapTask("JCorrectionMapTask");
    	cmaptask->EnableCentFlattening("alien:///alice/cern.ch/user/j/jparkkil/legotrain/Cent/CentWeights_LHC18q_pass13.root");
    	cmaptask->EnableEffCorrection("alien:///alice/cern.ch/user/d/djkim/legotrain/efficieny/data/Eff--LHC18q-LHC18l8-0-Lists.root"); // needed but not used!
    	mgr->AddTask((AliAnalysisTask*) cmaptask);

    } else if(period == lhc18r) {
    	AliJCorrectionMapTask *cmaptask = new AliJCorrectionMapTask("JCorrectionMapTask");
    	cmaptask->EnableCentFlattening("alien:///alice/cern.ch/user/j/jparkkil/legotrain/Cent/CentWeights_LHC18r_pass13.root");
    	cmaptask->EnableEffCorrection("alien:///alice/cern.ch/user/d/djkim/legotrain/efficieny/data/Eff--LHC18q-LHC18l8-0-Lists.root"); // needed but not used!
    	mgr->AddTask((AliAnalysisTask*) cmaptask);
    }

    //-------- JFlucWagons -------
    const int Nsets  = 7; // number of configurations
 	AliJFFlucTask *myTask[Nsets];
	TString configNames[Nsets] = {
		"hybrid", // 0
		"global",
		"nqq",    // 2
		"subA",
		"SPD",    // 4
		"zvtx",
		"pileup"  // 6
	};
   	Int_t hybridCut = 768;
    Int_t globalCut = 96;
    UInt_t selEvt;
	if(period == lhc15o)  selEvt = AliVEvent::kINT7;
	else if(period == lhc18q || period == lhc18r)  selEvt = AliVEvent::kINT7|AliVEvent::kCentral|AliVEvent::kSemiCentral;
	// --- track related common configurations -----
	for(int i=0;i<Nsets;i++) {
		myTask[i] = new AliJFFlucTask(Form("jkl_nlsc_s_%s",configNames[i].Data()));
		if(i!=6) {
			myTask[i]->AddFlags(AliJFFlucTask::FLUC_EBE_WEIGHTING|AliJFFlucTask::FLUC_CUT_OUTLIERS);
			if(period == lhc18q || period == lhc18r) myTask[i]->AddFlags(AliJFFlucTask::FLUC_CENT_FLATTENING);
		}
		myTask[i]->SelectCollisionCandidates( selEvt );
		myTask[i]->SetCentDetName("V0M");
		myTask[i]->SelectSubevents(AliJFFlucTask::SUBEVENT_A|AliJFFlucTask::SUBEVENT_B);
		myTask[i]->SetTestFilterBit(hybridCut);
		myTask[i]->SetEtaRange(0.4, 0.8);
		myTask[i]->SetPtRange(ptmin, 5.0);
		myTask[i]->SetEffConfig(0,hybridCut);
	}
	// s_global
	int iS = 1;
	myTask[iS]->SetTestFilterBit(globalCut);
	myTask[iS]->SetEffConfig(0,globalCut);
	// s_nqq
	iS = 2;
	myTask[iS]->SetParticleCharge(-1);
    // s_subA
    iS = 3;
	myTask[iS]->SelectSubevents(AliJFFlucTask::SUBEVENT_A); // subA
	//
	//----------- Event related Check -------------
	// s_SPD
	iS = 4;
	myTask[iS]->SetCentDetName("CL1");
	// s_zvtx
	iS = 5;
	myTask[iS]->SetZVertexCut(8);
	// s_pileup
	iS = 6;
	if(period==lhc18q || period==lhc18r) {
		myTask[iS]->AddFlags(AliJFFlucTask::FLUC_EBE_WEIGHTING|AliJFFlucTask::FLUC_CENT_FLATTENING); // CAN|T overwrite Flags!!!
	} else if(period==lhc15o) {
		myTask[iS]->AddFlags(AliJFFlucTask::FLUC_EBE_WEIGHTING); // CAN|T overwrite Flags!!! no weightening for 15o
	}

	// Must add the tasks
	for(int i=0;i<Nsets;i++) mgr->AddTask((AliAnalysisTask*) myTask[i]);
	// Create containers for input/output
	AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();

	// Connect input/output
	for(int i=0;i<Nsets;i++) {
		mgr->ConnectInput(myTask[i], 0, cinput);
		AliAnalysisDataContainer *jHist = mgr->CreateContainer(Form("%scontainer",myTask[i]->GetName()),  TDirectory::Class(), AliAnalysisManager::kOutputContainer, Form("%s:%s",AliAnalysisManager::GetCommonFileName(), myTask[i]->GetName()));
		mgr->ConnectOutput(myTask[i], 1, jHist );
	}

	return myTask[0];
}

<commit_msg>using task name for subwagons<commit_after>//_____________________________________________________________________
AliAnalysisTask *AddTaskJFFlucMapMaster(TString taskName="JFFlucMaster", UInt_t period = 0, double ptmin = 0.5){
	// Load Custom Configuration and parameters
	enum { lhc15o=0, lhc18q=1, lhc18r=2 };
	cout << "AddTaskJFFlucMapMaster:: period=" << period <<"\t ptmin="<< ptmin << endl;
	AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
	//-------- Correction Maps ----------

	if(period == lhc18q) {
		AliJCorrectionMapTask *cmaptask = new AliJCorrectionMapTask("JCorrectionMapTask");
    	cmaptask->EnableCentFlattening("alien:///alice/cern.ch/user/j/jparkkil/legotrain/Cent/CentWeights_LHC18q_pass13.root");
    	cmaptask->EnableEffCorrection("alien:///alice/cern.ch/user/d/djkim/legotrain/efficieny/data/Eff--LHC18q-LHC18l8-0-Lists.root"); // needed but not used!
    	mgr->AddTask((AliAnalysisTask*) cmaptask);

    } else if(period == lhc18r) {
    	AliJCorrectionMapTask *cmaptask = new AliJCorrectionMapTask("JCorrectionMapTask");
    	cmaptask->EnableCentFlattening("alien:///alice/cern.ch/user/j/jparkkil/legotrain/Cent/CentWeights_LHC18r_pass13.root");
    	cmaptask->EnableEffCorrection("alien:///alice/cern.ch/user/d/djkim/legotrain/efficieny/data/Eff--LHC18q-LHC18l8-0-Lists.root"); // needed but not used!
    	mgr->AddTask((AliAnalysisTask*) cmaptask);
    }

    //-------- JFlucWagons -------
    const int Nsets  = 7; // number of configurations
 	AliJFFlucTask *myTask[Nsets];
	TString configNames[Nsets] = {
		"hybrid", // 0
		"global",
		"nqq",    // 2
		"subA",
		"SPD",    // 4
		"zvtx",
		"pileup"  // 6
	};
   	Int_t hybridCut = 768;
    Int_t globalCut = 96;
    UInt_t selEvt;
	if(period == lhc15o)  selEvt = AliVEvent::kINT7;
	else if(period == lhc18q || period == lhc18r)  selEvt = AliVEvent::kINT7|AliVEvent::kCentral|AliVEvent::kSemiCentral;
	// --- track related common configurations -----
	for(int i=0;i<Nsets;i++) {
		myTask[i] = new AliJFFlucTask(Form("%s_s_%s",taskName.Data(), configNames[i].Data()));
		if(i!=6) {
			myTask[i]->AddFlags(AliJFFlucTask::FLUC_EBE_WEIGHTING|AliJFFlucTask::FLUC_CUT_OUTLIERS);
			if(period == lhc18q || period == lhc18r) myTask[i]->AddFlags(AliJFFlucTask::FLUC_CENT_FLATTENING);
		}
		myTask[i]->SelectCollisionCandidates( selEvt );
		myTask[i]->SetCentDetName("V0M");
		myTask[i]->SelectSubevents(AliJFFlucTask::SUBEVENT_A|AliJFFlucTask::SUBEVENT_B);
		myTask[i]->SetTestFilterBit(hybridCut);
		myTask[i]->SetEtaRange(0.4, 0.8);
		myTask[i]->SetPtRange(ptmin, 5.0);
		myTask[i]->SetEffConfig(0,hybridCut);
	}
	// s_global
	int iS = 1;
	myTask[iS]->SetTestFilterBit(globalCut);
	myTask[iS]->SetEffConfig(0,globalCut);
	// s_nqq
	iS = 2;
	myTask[iS]->SetParticleCharge(-1);
    // s_subA
    iS = 3;
	myTask[iS]->SelectSubevents(AliJFFlucTask::SUBEVENT_A); // subA
	//
	//----------- Event related Check -------------
	// s_SPD
	iS = 4;
	myTask[iS]->SetCentDetName("CL1");
	// s_zvtx
	iS = 5;
	myTask[iS]->SetZVertexCut(8);
	// s_pileup
	iS = 6;
	if(period==lhc18q || period==lhc18r) {
		myTask[iS]->AddFlags(AliJFFlucTask::FLUC_EBE_WEIGHTING|AliJFFlucTask::FLUC_CENT_FLATTENING); // CAN|T overwrite Flags!!!
	} else if(period==lhc15o) {
		myTask[iS]->AddFlags(AliJFFlucTask::FLUC_EBE_WEIGHTING); // CAN|T overwrite Flags!!! no weightening for 15o
	}

	// Must add the tasks
	for(int i=0;i<Nsets;i++) mgr->AddTask((AliAnalysisTask*) myTask[i]);
	// Create containers for input/output
	AliAnalysisDataContainer *cinput  = mgr->GetCommonInputContainer();

	// Connect input/output
	for(int i=0;i<Nsets;i++) {
		mgr->ConnectInput(myTask[i], 0, cinput);
		AliAnalysisDataContainer *jHist = mgr->CreateContainer(Form("%scontainer",myTask[i]->GetName()),  TDirectory::Class(), AliAnalysisManager::kOutputContainer, Form("%s:%s",AliAnalysisManager::GetCommonFileName(), myTask[i]->GetName()));
		mgr->ConnectOutput(myTask[i], 1, jHist );
	}

	return myTask[0];
}

<|endoftext|>


<commit_before>#ifndef _SMRH_
#define _SMRH_

#include <list>
#include <vector>
#include <algorithm>
#include <atomic>
#include <boost/thread/tss.hpp>

namespace DNFC
{

typedef void *data_pointer;

/**
 * HazardPointerManager
 *
 * This class should not be used through HazardPointer template class.
 * This singleton private class providea  central managment point for safe memory reclamation.
 * It provide memory managment for system wide hazard pointers.
 */
class HazardPointerManager
{
private:
  template <std::size_t nbPtr>
  friend class HazardPointer;

  /**
   * HazardPointerRecord
   *
   * An object that hold informations about allocated hazard pointers in a Hazard pointer manager.
   */
  class HazardPointerRecord
  {
  public:
    std::unique_ptr<std::atomic<data_pointer>[]> hp;
    int hpSize;
    std::list<data_pointer> rlist;
    std::atomic<bool> active;
    HazardPointerRecord *next;

    std::atomic<data_pointer> &operator[](std::size_t index)
    {
      assert(index >= hpSize);
      return hp[index];
    }

    HazardPointerRecord &operator=(HazardPointerRecord &&other) = delete;
    HazardPointerRecord &operator=(const HazardPointerRecord &) = delete;

    HazardPointerRecord(std::size_t nbHp, HazardPointerRecord *head, bool active) : next(head),
                                                                                hpSize(nbHp)
    {
      this->active.store(active, std::memory_order_relaxed);
    }
    ~HazardPointerRecord(){};

  private:
    void resetHp(std::size_t nbHp)
    {
      if (nbHp > hpSize)
      {
      }
    }
  };

  static HazardPointerManager &get()
  {
    static HazardPointerManager m;
    return m;
  }

  // Does not allow to copy or move the manager
  HazardPointerManager &operator=(HazardPointerManager &&) = delete;
  HazardPointerManager &operator=(const HazardPointerManager &) = delete;

  // Does not allow to copy construct or move construct the manager
  HazardPointerManager(const HazardPointerManager &) = delete;
  HazardPointerManager(HazardPointerManager &&) = delete;
  HazardPointerManager() : nbhp(0){};
  ~HazardPointerManager(){};

  std::atomic<std::unique_ptr<HazardPointerRecord>> head;
  std::atomic<int> nbhp;

  /**
   * Subscribe a thread to the manager. During the time the thread is subscribed, it is
   * given a HazardPointerRecord object that allow it to protect 'nbHp' number of pointers.
   * */
  static void subscribe(std::size_t nbHp)
  {
    // First try to reuse a retire HP record
    boost::thread_specific_ptr<HazardPointerRecord> &myhp = getMyhp();
    bool expected = false;
    for (HazardPointerRecord *i = head.load(std::memory_order_relaxed); i; i = i->next)
    {
      if (i->active.load(std::memory_order_relaxed) ||
          !i->active.compare_exchange_strong(expected, true,
                                             std::memory_order_acquire, std::memory_order_relaxed))
        continue;

      // Sucessfully locked one record to use
      myhp.reset(i);
      return;
    }

    // No HP records available for reuse so we add new ones
    nbhp.fetch_add(nbPointers, std::memory_order_relaxed);

    // Allocate and push a new record
    myhp.reset(new HazardPointerRecord(
        nbHp,
        head.load(std::memory_order_relaxed),
        true));

    // Add the new record to the list
    while (!head.compare_exchange_weak(myhp->next, myhp.get(),
                                       std::memory_order_release,
                                       std::memory_order_relaxed))
      ;
  }

  /**
   *
   */
  static void unsubscribe()
  {
    boost::thread_specific_ptr<HazardPointerRecord> &myhp = getMyhp();
    if (!myhp.get())
      return;
    // Clear hp
    for (int i = 0; i < nbPointers; i++)
      myhp->hp[i].store(nullptr, atomics::memory_order_release);
    myhp->active.store(false, std::memory_order_relaxed);
    myhp.release();
  }

  unsigned int getBatchSize()
  {
    return (nbhp.load(std::memory_order_relaxed) * nbPointers * 2) + nbhp.load(std::memory_order_relaxed);
  }

  /**
   *
   */
  void scan()
  {
    // Stage 1
    boost::thread_specific_ptr<HazardPointerRecord> &myhp = getMyhp();
    std::vector<data_pointer> plist;
    for (HazardPointerRecord *i = head.load(std::memory_order_relaxed); i; i = i->next)
    {
      for (int j = 0; j < nbPointers; j++)
      {
        T hp = i->hp[j].load(std::memory_order_relaxed);
        if (hp.get())
          plist.push_back(hp);
      }
    }
    if (plist.size() <= 0)
      return;

    // Stage 2
    std::sort(plist.begin(), plist.end());
    std::list<data_pointer> localRList = myhp->rlist;
    myhp->rlist.clear();

    // Stage 3
    for (auto &&e : localRList)
    {
      if (std::binary_search(plist.begin(), plist.end(), e))
        myhp->rlist.push_front(e);
      else
        delete e;
    }
  }

  void help_scan()
  {
    boost::thread_specific_ptr<HazardPointerRecord> &myhp = getMyhp();
    bool expected = false;
    for (HazardPointerRecord *i = head.load(std::memory_order_relaxed); i; i = i->next)
    {
      // Trying to lock the next non-used hazard pointer record
      if (i->active.load(std::memory_order_relaxed) ||
          !i->active.compare_exchange_strong(expected, true,
                                             std::memory_order_acquire, std::memory_order_relaxed))
        continue;

      // Inserting the rlist of the node in myhp
      for (auto &&e : i->rlist)
      {
        myhp->rlist.push_front(e);

        // scan if we reached the threshold
        if (myhp->rlist.size() >= getBatchSize())
          scan();
      }
      // Release the record
      i->rlist.clear();
      i->active.store(false, std::memory_order_relaxed);
    }
  }
};

/**
 * HazardPointer
 *
 */
template <std::size_t NbPtr>
class HazardPointer
{
public:
  /**
   *
   */
  static constexpr const std::size_t capacity = NbPtr;

  /**
   *
   * @param index
   */
  std::atomic<data_pointer> &operator[](std::size_t index)
  {
    boost::thread_specific_ptr<HazardPointerRecord> &myhp = getMyhp();
    assert(index >= myhp->hp.size());
    return myhp->hp[index];
  }

  /**
   *
   * @param node
   */
  template <typename T>
  void deleteNode(T &&node)
  {
    boost::thread_specific_ptr<HazardPointerRecord> &myhp = getMyhp();
    if (!myhp.get())
      return;
    myhp->rlist.push_front(std::forward(node));
    if (myhp->rlist.size() >= getBatchSize())
    {
      scan();
      help_scan();
    }
  }

  /**
   *
   */
  HazardPointer()
  {
    HazardPointerManager::get()->subscribe(capacity);
  };

  /**
   *
   */
  ~HazardPointer()
  {
    HazardPointerManager::get()->unsubscribe();
  };

private:
  static boost::thread_specific_ptr<HazardPointerRecord> &getMyhp()
  {
    static boost::thread_specific_ptr<HazardPointerRecord> myhp;
    return myhp;
  }
};
} // namespace DNFC

#endif
<commit_msg>[WIP] HazardPointer KO: improsving memory footprint and structure<commit_after>#ifndef _SMRH_
#define _SMRH_

#include <list>
#include <vector>
#include <algorithm>
#include <atomic>
#include <boost/thread/tss.hpp>

namespace DNFC
{

// Verbose typedef
typedef void *data_pointer;

/**
 * HazardPointer
 *
 */
template <std::size_t NbPtr>
class HazardPointer
{
public:
  /**
   * Access a HazardPointer through the HazardPointerRecord assigned
   * @param index
   */
  std::atomic<data_pointer> &operator[](std::size_t index)
  {
    HazardPointerRecord &myhp = getMyhp();
    assert(myhp == nullptr && index >= myhp->hp.size());
    return myhp->hp[index];
  }

  /**
   * Safely delete a node.
   * @param node
   */
  template <typename T>
  void deleteNode(T &&node)
  {
    HazardPointerRecord &myhp = getMyhp();
    if (!myhp.get())
      return;
    myhp->rlist.push_front(std::forward(node));
    if (myhp->rlist.size() >= getBatchSize())
    {
      scan();
      help_scan();
    }
  }

  /**
   * Subscribe and get a HazarPointerRecord set with the right amount of pointers.
   */
  HazardPointer()
  {
    HazardPointerManager<NbPtr>::get().subscribe();
  };

  /**
   * Unsubscribe and release the HazardPointerRecord.
   */
  ~HazardPointer()
  {
    HazardPointerManager<NbPtr>::get().unsubscribe();
  };

private:
  /**
   * Thread local storage hazard pointer
   */
  HazardPointerRecord *getMyhp()
  {
    thread_local HazardPointerRecord *myhp;
    return myhp;
  }

  /**
   * HazardPointerRecord
   *
   * An object that hold informations about allocated hazard pointers in a Hazard pointer manager.
   */
  class HazardPointerRecord
  {
  public:
    std::atomic<data_pointer> hp[NbPtr];
    std::list<data_pointer> rlist;
    std::atomic<bool> active;
    HazardPointerRecord *next;

    HazardPointerRecord &operator=(HazardPointerRecord &&other) = delete;
    HazardPointerRecord &operator=(const HazardPointerRecord &) = delete;

    HazardPointerRecord(HazardPointerRecord *head, bool active) : next(head)
    {
      this->active.store(active, std::memory_order_relaxed);
    }
    ~HazardPointerRecord(){};

  private:
    void resetHp()
    {
      if (nbHp > hpSize)
      {
        // TODO
      }
    }
  };

  /**
   * HazardPointerManager
   *
   * This class should not be used through HazardPointer template class.
   * This singleton private class providea  central managment point for safe memory reclamation.
   * It provide memory managment for system wide hazard pointers.
   */
  template <std::size_t nbPtr>
  friend class HazardPointerManager;

  template <std::size_t nbPtr>
  class HazardPointerManager
  {
  private:
    static HazardPointerManager &get()
    {
      static HazardPointerManager m;
      return m;
    }

    // Does not allow to copy or move the manager
    HazardPointerManager &operator=(HazardPointerManager &&) = delete;
    HazardPointerManager &operator=(const HazardPointerManager &) = delete;

    // Does not allow to copy construct or move construct the manager
    HazardPointerManager(const HazardPointerManager &) = delete;
    HazardPointerManager(HazardPointerManager &&) = delete;
    HazardPointerManager() : nbhp(0){};
    ~HazardPointerManager(){};

    std::atomic<HazardPointerRecord *> head;
    std::atomic<int> nbhp;

    /**
     * Subscribe a thread to the manager. During the time the thread is subscribed, it is
     * given a HazardPointerRecord object that allow it to protect 'nbPtr' number of pointers.
     */
    static void subscribe()
    {
      // First try to reuse a retire HP record
      HazardPointerRecord &myhp = getMyhp();
      bool expected = false;
      for (HazardPointerRecord *i = head.load(std::memory_order_relaxed); i; i = i->next)
      {
        if (i->active.load(std::memory_order_relaxed) ||
            !i->active.compare_exchange_strong(expected, true,
                                               std::memory_order_acquire, std::memory_order_relaxed))
          continue;

        // Sucessfully locked one record to use
        myhp.reset(i);
        return;
      }

      // No HP records available for reuse so we add new ones
      nbhp.fetch_add(nbPointers, std::memory_order_relaxed);

      // Allocate and push a new record
      myhp.reset(new HazardPointerRecord(
          nbPtr,
          head.load(std::memory_order_relaxed),
          true));

      // Add the new record to the list
      while (!head.compare_exchange_weak(myhp->next, myhp.get(),
                                         std::memory_order_release,
                                         std::memory_order_relaxed))
        ;
    }

    /**
     * Unsubscribe the current thread from the manager. Its HazarPointerRecord is put back into the store
     * for reuse.
     */
    static void unsubscribe()
    {
      HazardPointerRecord &myhp = getMyhp();
      if (!myhp.get())
        return;
      // Clear hp
      for (int i = 0; i < nbPointers; i++)
        myhp->hp[i].store(nullptr, atomics::memory_order_release);
      myhp->active.store(false, std::memory_order_relaxed);
      myhp.release();
    }

    unsigned int getBatchSize()
    {
      return (nbhp.load(std::memory_order_relaxed) * nbPointers * 2) + nbhp.load(std::memory_order_relaxed);
    }

    /**
     * Scan function that is called to garbage collect the memory.
     */
    void scan()
    {
      // Stage 1
      HazardPointerRecord &myhp = getMyhp();
      std::vector<data_pointer> plist;
      for (HazardPointerRecord *i = head.load(std::memory_order_relaxed); i; i = i->next)
      {
        for (int j = 0; j < nbPointers; j++)
        {
          T hp = i->hp[j].load(std::memory_order_relaxed);
          if (hp.get())
            plist.push_back(hp);
        }
      }
      if (plist.size() <= 0)
        return;

      // Stage 2
      std::sort(plist.begin(), plist.end());
      std::list<data_pointer> localRList = myhp->rlist;
      myhp->rlist.clear();

      // Stage 3
      for (auto &&e : localRList)
      {
        if (std::binary_search(plist.begin(), plist.end(), e))
          myhp->rlist.push_front(e);
        else
          delete e;
      }
    }

    void help_scan()
    {
      HazardPointerRecord &myhp = getMyhp();
      bool expected = false;
      for (HazardPointerRecord *i = head.load(std::memory_order_relaxed); i; i = i->next)
      {
        // Trying to lock the next non-used hazard pointer record
        if (i->active.load(std::memory_order_relaxed) ||
            !i->active.compare_exchange_strong(expected, true,
                                               std::memory_order_acquire, std::memory_order_relaxed))
          continue;

        // Inserting the rlist of the node in myhp
        for (auto &&e : i->rlist)
        {
          myhp->rlist.push_front(e);

          // scan if we reached the threshold
          if (myhp->rlist.size() >= getBatchSize())
            scan();
        }
        // Release the record
        i->rlist.clear();
        i->active.store(false, std::memory_order_relaxed);
      }
    }
  };
};
} // namespace DNFC

#endif
<|endoftext|>