<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGLUtil.h"
#include "SkMatrix.h"
#include <stdio.h>

void GrGLClearErr(const GrGLInterface* gl) {
    while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
}

namespace {
const char *get_error_string(uint32_t err) {
    switch (err) {
    case GR_GL_NO_ERROR:
        return "";
    case GR_GL_INVALID_ENUM:
        return "Invalid Enum";
    case GR_GL_INVALID_VALUE:
        return "Invalid Value";
    case GR_GL_INVALID_OPERATION:
        return "Invalid Operation";
    case GR_GL_OUT_OF_MEMORY:
        return "Out of Memory";
    case GR_GL_CONTEXT_LOST:
        return "Context Lost";
    }
    return "Unknown";
}
}

void GrGLCheckErr(const GrGLInterface* gl,
                  const char* location,
                  const char* call) {
    uint32_t err = GR_GL_GET_ERROR(gl);
    if (GR_GL_NO_ERROR != err) {
        SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
        if (location) {
            SkDebugf(" at\n\t%s", location);
        }
        if (call) {
            SkDebugf("\n\t\t%s", call);
        }
        SkDebugf("\n");
    }
}

///////////////////////////////////////////////////////////////////////////////

#if GR_GL_LOG_CALLS
    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
#endif

#if GR_GL_CHECK_ERROR
    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
#endif

///////////////////////////////////////////////////////////////////////////////

GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GL version string.");
        return kNone_GrGLStandard;
    }

    int major, minor;

    // check for desktop
    int n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return kGL_GrGLStandard;
    }

    // check for ES 1
    char profile[2];
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
    if (4 == n) {
        // we no longer support ES1.
        return kNone_GrGLStandard;
    }

    // check for ES2
    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    if (2 == n) {
        return kGLES_GrGLStandard;
    }
    return kNone_GrGLStandard;
}

void GrGLGetDriverInfo(GrGLStandard standard,
                       GrGLVendor vendor,
                       const char* rendererString,
                       const char* versionString,
                       GrGLDriver* outDriver,
                       GrGLDriverVersion* outVersion) {
    int major, minor, rev, driverMajor, driverMinor;

    *outDriver = kUnknown_GrGLDriver;
    *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
    // These null checks are for test GL contexts that return nullptr in their
    // glGetString implementation.
    if (!rendererString) {
        rendererString = "";
    }
    if (!versionString) {
        versionString = "";
    }

    if (0 == strcmp(rendererString, "Chromium")) {
        *outDriver = kChromium_GrGLDriver;
        return;
    }

    if (standard == kGL_GrGLStandard) {
        if (kNVIDIA_GrGLVendor == vendor) {
            *outDriver = kNVIDIA_GrGLDriver;
            int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
                           &major, &minor, &rev, &driverMajor, &driverMinor);
            // Some older NVIDIA drivers don't report the driver version.
            if (5 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            }
            return;
        }
        int n = sscanf(versionString, "%d.%d Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        if (4 == n) {
            *outDriver = kMesa_GrGLDriver;
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            return;
        }
    }
    else {
        if (kNVIDIA_GrGLVendor == vendor) {
            *outDriver = kNVIDIA_GrGLDriver;
            int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
                           &major, &minor, &driverMajor, &driverMinor);
            // Some older NVIDIA drivers don't report the driver version.
            if (4 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            }
            return;
        }

        int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        if (4 == n) {
            *outDriver = kMesa_GrGLDriver;
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            return;
        }
        if (0 == strncmp("ANGLE", rendererString, 5)) {
            *outDriver = kANGLE_GrGLDriver;
            n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
                                                                      &driverMinor);
            if (4 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            }
            return;
        }
    }

    if (kIntel_GrGLVendor == vendor) {
        // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
        *outDriver = kIntel_GrGLDriver;
    }
}

GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GL version string.");
        return GR_GL_INVALID_VER;
    }

    int major, minor;

    // check for mesa
    int mesaMajor, mesaMinor;
    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return GR_GL_VER(major, minor);
    }

    char profile[2];
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
               &major, &minor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GL_VER(major, minor);
    }

    return GR_GL_INVALID_VER;
}

GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GLSL version string.");
        return GR_GLSL_INVALID_VER;
    }

    int major, minor;

    int n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }

    n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }

#ifdef SK_BUILD_FOR_ANDROID
    // android hack until the gpu vender updates their drivers
    n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }
#endif

    return GR_GLSL_INVALID_VER;
}

GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    if (vendorString) {
        if (0 == strcmp(vendorString, "ARM")) {
            return kARM_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Imagination Technologies")) {
            return kImagination_GrGLVendor;
        }
        if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
            return kIntel_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Qualcomm")) {
            return kQualcomm_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
            return kNVIDIA_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
            return kATI_GrGLVendor;
        }
    }
    return kOther_GrGLVendor;
}

GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    if (rendererString) {
        if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
            return kTegra3_GrGLRenderer;
        } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
            return kTegra2_GrGLRenderer;
        }
        int lastDigit;
        int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
        if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
            return kPowerVR54x_GrGLRenderer;
        }
        // certain iOS devices also use PowerVR54x GPUs
        static const char kAppleA4Str[] = "Apple A4";
        static const char kAppleA5Str[] = "Apple A5";
        static const char kAppleA6Str[] = "Apple A6";
        if (0 == strncmp(rendererString, kAppleA4Str,
                         SK_ARRAY_COUNT(kAppleA4Str)-1) ||
            0 == strncmp(rendererString, kAppleA5Str,
                         SK_ARRAY_COUNT(kAppleA5Str)-1) ||
            0 == strncmp(rendererString, kAppleA6Str,
                         SK_ARRAY_COUNT(kAppleA6Str)-1)) {
            return kPowerVR54x_GrGLRenderer;
        }
        static const char kPowerVRRogueStr[] = "PowerVR Rogue";
        static const char kAppleA7Str[] = "Apple A7";
        static const char kAppleA8Str[] = "Apple A8";
        if (0 == strncmp(rendererString, kPowerVRRogueStr,
                         SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
            0 == strncmp(rendererString, kAppleA7Str,
                         SK_ARRAY_COUNT(kAppleA7Str)-1) ||
            0 == strncmp(rendererString, kAppleA8Str,
                         SK_ARRAY_COUNT(kAppleA8Str)-1)) {
            return kPowerVRRogue_GrGLRenderer;
        }
        int adrenoNumber;
        n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
        if (1 == n) {
            if (adrenoNumber >= 300) {
                if (adrenoNumber < 400) {
                    return kAdreno3xx_GrGLRenderer;
                }
                if (adrenoNumber < 500) {
                    return kAdreno4xx_GrGLRenderer;
                }
                if (adrenoNumber < 600) {
                    return kAdreno5xx_GrGLRenderer;
                }
            }
        }
        if (0 == strcmp("Mesa Offscreen", rendererString)) {
            return kOSMesa_GrGLRenderer;
        }
    }
    return kOther_GrGLRenderer;
}

GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    return GrGLGetVersionFromString((const char*) v);
}

GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    return GrGLGetGLSLVersionFromString((const char*) v);
}

GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    return GrGLGetVendorFromString((const char*) v);
}

GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
    return GrGLGetRendererFromString((const char*) v);
}

GrGLenum GrToGLStencilFunc(GrStencilTest test) {
    static const GrGLenum gTable[kGrStencilTestCount] = {
        GR_GL_ALWAYS,           // kAlways
        GR_GL_NEVER,            // kNever
        GR_GL_GREATER,          // kGreater
        GR_GL_GEQUAL,           // kGEqual
        GR_GL_LESS,             // kLess
        GR_GL_LEQUAL,           // kLEqual
        GR_GL_EQUAL,            // kEqual
        GR_GL_NOTEQUAL,         // kNotEqual
    };
    GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
    GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
    GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
    GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
    GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
    GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
    GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
    GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
    SkASSERT(test < (GrStencilTest)kGrStencilTestCount);

    return gTable[(int)test];
}
<commit_msg>Detect Chrome either by renderer or version strings.<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGLUtil.h"
#include "SkMatrix.h"
#include <stdio.h>

void GrGLClearErr(const GrGLInterface* gl) {
    while (GR_GL_NO_ERROR != gl->fFunctions.fGetError()) {}
}

namespace {
const char *get_error_string(uint32_t err) {
    switch (err) {
    case GR_GL_NO_ERROR:
        return "";
    case GR_GL_INVALID_ENUM:
        return "Invalid Enum";
    case GR_GL_INVALID_VALUE:
        return "Invalid Value";
    case GR_GL_INVALID_OPERATION:
        return "Invalid Operation";
    case GR_GL_OUT_OF_MEMORY:
        return "Out of Memory";
    case GR_GL_CONTEXT_LOST:
        return "Context Lost";
    }
    return "Unknown";
}
}

void GrGLCheckErr(const GrGLInterface* gl,
                  const char* location,
                  const char* call) {
    uint32_t err = GR_GL_GET_ERROR(gl);
    if (GR_GL_NO_ERROR != err) {
        SkDebugf("---- glGetError 0x%x(%s)", err, get_error_string(err));
        if (location) {
            SkDebugf(" at\n\t%s", location);
        }
        if (call) {
            SkDebugf("\n\t\t%s", call);
        }
        SkDebugf("\n");
    }
}

///////////////////////////////////////////////////////////////////////////////

#if GR_GL_LOG_CALLS
    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
#endif

#if GR_GL_CHECK_ERROR
    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
#endif

///////////////////////////////////////////////////////////////////////////////

GrGLStandard GrGLGetStandardInUseFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GL version string.");
        return kNone_GrGLStandard;
    }

    int major, minor;

    // check for desktop
    int n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return kGL_GrGLStandard;
    }

    // check for ES 1
    char profile[2];
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1, &major, &minor);
    if (4 == n) {
        // we no longer support ES1.
        return kNone_GrGLStandard;
    }

    // check for ES2
    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    if (2 == n) {
        return kGLES_GrGLStandard;
    }
    return kNone_GrGLStandard;
}

void GrGLGetDriverInfo(GrGLStandard standard,
                       GrGLVendor vendor,
                       const char* rendererString,
                       const char* versionString,
                       GrGLDriver* outDriver,
                       GrGLDriverVersion* outVersion) {
    int major, minor, rev, driverMajor, driverMinor;

    *outDriver = kUnknown_GrGLDriver;
    *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
    // These null checks are for test GL contexts that return nullptr in their
    // glGetString implementation.
    if (!rendererString) {
        rendererString = "";
    }
    if (!versionString) {
        versionString = "";
    }

    if (0 == strcmp(rendererString, "Chromium") ||
        2 == sscanf(versionString, "OpenGL ES %d.%d Chromium", &major, &minor)) {
        *outDriver = kChromium_GrGLDriver;
        return;
    }

    if (standard == kGL_GrGLStandard) {
        if (kNVIDIA_GrGLVendor == vendor) {
            *outDriver = kNVIDIA_GrGLDriver;
            int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
                           &major, &minor, &rev, &driverMajor, &driverMinor);
            // Some older NVIDIA drivers don't report the driver version.
            if (5 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            }
            return;
        }
        int n = sscanf(versionString, "%d.%d Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        if (4 == n) {
            *outDriver = kMesa_GrGLDriver;
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            return;
        }
    }
    else {
        if (kNVIDIA_GrGLVendor == vendor) {
            *outDriver = kNVIDIA_GrGLDriver;
            int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
                           &major, &minor, &driverMajor, &driverMinor);
            // Some older NVIDIA drivers don't report the driver version.
            if (4 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            }
            return;
        }

        int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
                       &major, &minor, &driverMajor, &driverMinor);
        if (4 == n) {
            *outDriver = kMesa_GrGLDriver;
            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            return;
        }
        if (0 == strncmp("ANGLE", rendererString, 5)) {
            *outDriver = kANGLE_GrGLDriver;
            n = sscanf(versionString, "OpenGL ES %d.%d (ANGLE %d.%d", &major, &minor, &driverMajor,
                                                                      &driverMinor);
            if (4 == n) {
                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
            }
            return;
        }
    }

    if (kIntel_GrGLVendor == vendor) {
        // We presume we're on the Intel driver since it hasn't identified itself as Mesa.
        *outDriver = kIntel_GrGLDriver;
    }
}

GrGLVersion GrGLGetVersionFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GL version string.");
        return GR_GL_INVALID_VER;
    }

    int major, minor;

    // check for mesa
    int mesaMajor, mesaMinor;
    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return GR_GL_VER(major, minor);
    }

    char profile[2];
    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
               &major, &minor);
    if (4 == n) {
        return GR_GL_VER(major, minor);
    }

    n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GL_VER(major, minor);
    }

    return GR_GL_INVALID_VER;
}

GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
    if (nullptr == versionString) {
        SkDebugf("nullptr GLSL version string.");
        return GR_GLSL_INVALID_VER;
    }

    int major, minor;

    int n = sscanf(versionString, "%d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }

    n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }

#ifdef SK_BUILD_FOR_ANDROID
    // android hack until the gpu vender updates their drivers
    n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
    if (2 == n) {
        return GR_GLSL_VER(major, minor);
    }
#endif

    return GR_GLSL_INVALID_VER;
}

GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
    if (vendorString) {
        if (0 == strcmp(vendorString, "ARM")) {
            return kARM_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Imagination Technologies")) {
            return kImagination_GrGLVendor;
        }
        if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) {
            return kIntel_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "Qualcomm")) {
            return kQualcomm_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
            return kNVIDIA_GrGLVendor;
        }
        if (0 == strcmp(vendorString, "ATI Technologies Inc.")) {
            return kATI_GrGLVendor;
        }
    }
    return kOther_GrGLVendor;
}

GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
    if (rendererString) {
        if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
            return kTegra3_GrGLRenderer;
        } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
            return kTegra2_GrGLRenderer;
        }
        int lastDigit;
        int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
        if (1 == n && lastDigit >= 0 && lastDigit <= 9) {
            return kPowerVR54x_GrGLRenderer;
        }
        // certain iOS devices also use PowerVR54x GPUs
        static const char kAppleA4Str[] = "Apple A4";
        static const char kAppleA5Str[] = "Apple A5";
        static const char kAppleA6Str[] = "Apple A6";
        if (0 == strncmp(rendererString, kAppleA4Str,
                         SK_ARRAY_COUNT(kAppleA4Str)-1) ||
            0 == strncmp(rendererString, kAppleA5Str,
                         SK_ARRAY_COUNT(kAppleA5Str)-1) ||
            0 == strncmp(rendererString, kAppleA6Str,
                         SK_ARRAY_COUNT(kAppleA6Str)-1)) {
            return kPowerVR54x_GrGLRenderer;
        }
        static const char kPowerVRRogueStr[] = "PowerVR Rogue";
        static const char kAppleA7Str[] = "Apple A7";
        static const char kAppleA8Str[] = "Apple A8";
        if (0 == strncmp(rendererString, kPowerVRRogueStr,
                         SK_ARRAY_COUNT(kPowerVRRogueStr)-1) ||
            0 == strncmp(rendererString, kAppleA7Str,
                         SK_ARRAY_COUNT(kAppleA7Str)-1) ||
            0 == strncmp(rendererString, kAppleA8Str,
                         SK_ARRAY_COUNT(kAppleA8Str)-1)) {
            return kPowerVRRogue_GrGLRenderer;
        }
        int adrenoNumber;
        n = sscanf(rendererString, "Adreno (TM) %d", &adrenoNumber);
        if (1 == n) {
            if (adrenoNumber >= 300) {
                if (adrenoNumber < 400) {
                    return kAdreno3xx_GrGLRenderer;
                }
                if (adrenoNumber < 500) {
                    return kAdreno4xx_GrGLRenderer;
                }
                if (adrenoNumber < 600) {
                    return kAdreno5xx_GrGLRenderer;
                }
            }
        }
        if (0 == strcmp("Mesa Offscreen", rendererString)) {
            return kOSMesa_GrGLRenderer;
        }
    }
    return kOther_GrGLRenderer;
}

GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
    return GrGLGetVersionFromString((const char*) v);
}

GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
    return GrGLGetGLSLVersionFromString((const char*) v);
}

GrGLVendor GrGLGetVendor(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_VENDOR));
    return GrGLGetVendorFromString((const char*) v);
}

GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
    const GrGLubyte* v;
    GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
    return GrGLGetRendererFromString((const char*) v);
}

GrGLenum GrToGLStencilFunc(GrStencilTest test) {
    static const GrGLenum gTable[kGrStencilTestCount] = {
        GR_GL_ALWAYS,           // kAlways
        GR_GL_NEVER,            // kNever
        GR_GL_GREATER,          // kGreater
        GR_GL_GEQUAL,           // kGEqual
        GR_GL_LESS,             // kLess
        GR_GL_LEQUAL,           // kLEqual
        GR_GL_EQUAL,            // kEqual
        GR_GL_NOTEQUAL,         // kNotEqual
    };
    GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
    GR_STATIC_ASSERT(1 == (int)GrStencilTest::kNever);
    GR_STATIC_ASSERT(2 == (int)GrStencilTest::kGreater);
    GR_STATIC_ASSERT(3 == (int)GrStencilTest::kGEqual);
    GR_STATIC_ASSERT(4 == (int)GrStencilTest::kLess);
    GR_STATIC_ASSERT(5 == (int)GrStencilTest::kLEqual);
    GR_STATIC_ASSERT(6 == (int)GrStencilTest::kEqual);
    GR_STATIC_ASSERT(7 == (int)GrStencilTest::kNotEqual);
    SkASSERT(test < (GrStencilTest)kGrStencilTestCount);

    return gTable[(int)test];
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/storage.hpp"
#include <deque>
#include "libtorrent/disk_io_thread.hpp"

namespace libtorrent
{

	disk_io_thread::disk_io_thread(int block_size)
		: m_abort(false)
		, m_queue_buffer_size(0)
		, m_pool(block_size)
		, m_disk_io_thread(boost::ref(*this))
	{}

	disk_io_thread::~disk_io_thread()
	{
		boost::mutex::scoped_lock l(m_mutex);
		m_abort = true;
		m_signal.notify_all();
		l.unlock();

		m_disk_io_thread.join();
	}

	// aborts read operations
	void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s)
	{
		boost::mutex::scoped_lock l(m_mutex);
		// read jobs are aborted, write and move jobs are syncronized
		for (std::deque<disk_io_job>::iterator i = m_jobs.begin();
			i != m_jobs.end();)
		{
			if (i->storage != s)
			{
				++i;
				continue;
			}
			if (i->action == disk_io_job::read)
			{
				i->callback(-1, *i);
				m_jobs.erase(i++);
				continue;
			}
			++i;
		}
		m_signal.notify_all();
	}

	bool range_overlap(int start1, int length1, int start2, int length2)
	{
		return (start1 <= start2 && start1 + length1 > start2)
			|| (start2 <= start1 && start2 + length2 > start1);
	}

	namespace
	{
		bool operator<(disk_io_job const& lhs, disk_io_job const& rhs)
		{
			if (lhs.storage.get() < rhs.storage.get()) return true;
			if (lhs.storage.get() > rhs.storage.get()) return false;
			if (lhs.piece < rhs.piece) return true;
			if (lhs.piece > rhs.piece) return false;
			if (lhs.offset < rhs.offset) return true;
//			if (lhs.offset > rhs.offset) return false;
			return false;
		}
	}

	void disk_io_thread::add_job(disk_io_job const& j
		, boost::function<void(int, disk_io_job const&)> const& f)
	{
		assert(!j.callback);
		boost::mutex::scoped_lock l(m_mutex);

		std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin();
		if (j.action == disk_io_job::read)
		{
			// when we're reading, we may not skip
			// ahead of any write operation that overlaps
			// the region we're reading
			for (; i != m_jobs.rend(); ++i)
			{
				if (i->action == disk_io_job::read && *i < j)
					break;
				if (i->action == disk_io_job::write
					&& i->storage == j.storage
					&& i->piece == j.piece
					&& range_overlap(i->offset, i->buffer_size
						, j.offset, j.buffer_size))
				{
					// we have to stop, and we haven't
					// found a suitable place for this job
					// so just queue it up at the end
					i = m_jobs.rbegin();
					break;
				}
			}
		}
		else if (j.action == disk_io_job::write)
		{
			for (; i != m_jobs.rend(); ++i)
			{
				if (i->action == disk_io_job::write && *i < j)
				{
					if (i != m_jobs.rbegin()
						&& i.base()->storage.get() != j.storage.get())
						i = m_jobs.rbegin();
					break;
				}
			}
		}

		if (i == m_jobs.rend()) i = m_jobs.rbegin();

		std::deque<disk_io_job>::iterator k = m_jobs.insert(i.base(), j);
		k->callback.swap(const_cast<boost::function<void(int, disk_io_job const&)>&>(f));
		if (j.action == disk_io_job::write)
			m_queue_buffer_size += j.buffer_size;
		assert(j.storage.get());
		m_signal.notify_all();
	}

	char* disk_io_thread::allocate_buffer()
	{
		boost::mutex::scoped_lock l(m_mutex);
		return (char*)m_pool.ordered_malloc();
	}

	void disk_io_thread::operator()()
	{
		for (;;)
		{
			boost::mutex::scoped_lock l(m_mutex);
			while (m_jobs.empty() && !m_abort)
				m_signal.wait(l);
			if (m_abort && m_jobs.empty()) return;

			boost::function<void(int, disk_io_job const&)> handler;
			handler.swap(m_jobs.front().callback);
			disk_io_job j = m_jobs.front();
			m_jobs.pop_front();
			m_queue_buffer_size -= j.buffer_size;
			l.unlock();

			int ret = 0;

			try
			{
//				std::cerr << "DISK THREAD: executing job: " << j.action << std::endl;
				switch (j.action)
				{
					case disk_io_job::read:
						l.lock();
						j.buffer = (char*)m_pool.ordered_malloc();
						l.unlock();
						if (j.buffer == 0)
						{
							ret = -1;
							j.str = "out of memory";
						}
						else
						{
							ret = j.storage->read_impl(j.buffer, j.piece, j.offset
								, j.buffer_size);

							// simulates slow drives
							// usleep(300);
						}
						break;
					case disk_io_job::write:
						assert(j.buffer);
						j.storage->write_impl(j.buffer, j.piece, j.offset
							, j.buffer_size);

						// simulates a slow drive
						// usleep(300);
						break;
					case disk_io_job::hash:
						{
							sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
							j.str.resize(20);
							std::memcpy(&j.str[0], &h[0], 20);
						}
						break;
					case disk_io_job::move_storage:
						ret = j.storage->move_storage_impl(j.str) ? 1 : 0;
						break;
					case disk_io_job::release_files:
						j.storage->release_files_impl();
						break;
				}
			}
			catch (std::exception& e)
			{
//				std::cerr << "DISK THREAD: exception: " << e.what() << std::endl;
				j.str = e.what();
				ret = -1;
			}

//			if (!handler) std::cerr << "DISK THREAD: no callback specified" << std::endl;
//			else std::cerr << "DISK THREAD: invoking callback" << std::endl;
			try { if (handler) handler(ret, j); }
			catch (std::exception&) {}

			if (j.buffer) m_pool.ordered_free(j.buffer);
		}
	}
}

<commit_msg>fixed mutex issue in disk io thread<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/storage.hpp"
#include <deque>
#include "libtorrent/disk_io_thread.hpp"

namespace libtorrent
{

	disk_io_thread::disk_io_thread(int block_size)
		: m_abort(false)
		, m_queue_buffer_size(0)
		, m_pool(block_size)
		, m_disk_io_thread(boost::ref(*this))
	{}

	disk_io_thread::~disk_io_thread()
	{
		boost::mutex::scoped_lock l(m_mutex);
		m_abort = true;
		m_signal.notify_all();
		l.unlock();

		m_disk_io_thread.join();
	}

	// aborts read operations
	void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s)
	{
		boost::mutex::scoped_lock l(m_mutex);
		// read jobs are aborted, write and move jobs are syncronized
		for (std::deque<disk_io_job>::iterator i = m_jobs.begin();
			i != m_jobs.end();)
		{
			if (i->storage != s)
			{
				++i;
				continue;
			}
			if (i->action == disk_io_job::read)
			{
				i->callback(-1, *i);
				m_jobs.erase(i++);
				continue;
			}
			++i;
		}
		m_signal.notify_all();
	}

	bool range_overlap(int start1, int length1, int start2, int length2)
	{
		return (start1 <= start2 && start1 + length1 > start2)
			|| (start2 <= start1 && start2 + length2 > start1);
	}

	namespace
	{
		bool operator<(disk_io_job const& lhs, disk_io_job const& rhs)
		{
			if (lhs.storage.get() < rhs.storage.get()) return true;
			if (lhs.storage.get() > rhs.storage.get()) return false;
			if (lhs.piece < rhs.piece) return true;
			if (lhs.piece > rhs.piece) return false;
			if (lhs.offset < rhs.offset) return true;
//			if (lhs.offset > rhs.offset) return false;
			return false;
		}
	}

	void disk_io_thread::add_job(disk_io_job const& j
		, boost::function<void(int, disk_io_job const&)> const& f)
	{
		assert(!j.callback);
		boost::mutex::scoped_lock l(m_mutex);

		std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin();
		if (j.action == disk_io_job::read)
		{
			// when we're reading, we may not skip
			// ahead of any write operation that overlaps
			// the region we're reading
			for (; i != m_jobs.rend(); ++i)
			{
				if (i->action == disk_io_job::read && *i < j)
					break;
				if (i->action == disk_io_job::write
					&& i->storage == j.storage
					&& i->piece == j.piece
					&& range_overlap(i->offset, i->buffer_size
						, j.offset, j.buffer_size))
				{
					// we have to stop, and we haven't
					// found a suitable place for this job
					// so just queue it up at the end
					i = m_jobs.rbegin();
					break;
				}
			}
		}
		else if (j.action == disk_io_job::write)
		{
			for (; i != m_jobs.rend(); ++i)
			{
				if (i->action == disk_io_job::write && *i < j)
				{
					if (i != m_jobs.rbegin()
						&& i.base()->storage.get() != j.storage.get())
						i = m_jobs.rbegin();
					break;
				}
			}
		}

		if (i == m_jobs.rend()) i = m_jobs.rbegin();

		std::deque<disk_io_job>::iterator k = m_jobs.insert(i.base(), j);
		k->callback.swap(const_cast<boost::function<void(int, disk_io_job const&)>&>(f));
		if (j.action == disk_io_job::write)
			m_queue_buffer_size += j.buffer_size;
		assert(j.storage.get());
		m_signal.notify_all();
	}

	char* disk_io_thread::allocate_buffer()
	{
		boost::mutex::scoped_lock l(m_mutex);
		return (char*)m_pool.ordered_malloc();
	}

	void disk_io_thread::operator()()
	{
		for (;;)
		{
			boost::mutex::scoped_lock l(m_mutex);
			while (m_jobs.empty() && !m_abort)
				m_signal.wait(l);
			if (m_abort && m_jobs.empty()) return;

			boost::function<void(int, disk_io_job const&)> handler;
			handler.swap(m_jobs.front().callback);
			disk_io_job j = m_jobs.front();
			m_jobs.pop_front();
			m_queue_buffer_size -= j.buffer_size;
			l.unlock();

			int ret = 0;

			try
			{
//				std::cerr << "DISK THREAD: executing job: " << j.action << std::endl;
				switch (j.action)
				{
					case disk_io_job::read:
						l.lock();
						j.buffer = (char*)m_pool.ordered_malloc();
						l.unlock();
						if (j.buffer == 0)
						{
							ret = -1;
							j.str = "out of memory";
						}
						else
						{
							ret = j.storage->read_impl(j.buffer, j.piece, j.offset
								, j.buffer_size);

							// simulates slow drives
							// usleep(300);
						}
						break;
					case disk_io_job::write:
						assert(j.buffer);
						j.storage->write_impl(j.buffer, j.piece, j.offset
							, j.buffer_size);

						// simulates a slow drive
						// usleep(300);
						break;
					case disk_io_job::hash:
						{
							sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
							j.str.resize(20);
							std::memcpy(&j.str[0], &h[0], 20);
						}
						break;
					case disk_io_job::move_storage:
						ret = j.storage->move_storage_impl(j.str) ? 1 : 0;
						break;
					case disk_io_job::release_files:
						j.storage->release_files_impl();
						break;
				}
			}
			catch (std::exception& e)
			{
//				std::cerr << "DISK THREAD: exception: " << e.what() << std::endl;
				j.str = e.what();
				ret = -1;
			}

//			if (!handler) std::cerr << "DISK THREAD: no callback specified" << std::endl;
//			else std::cerr << "DISK THREAD: invoking callback" << std::endl;
			try { if (handler) handler(ret, j); }
			catch (std::exception&) {}

			if (j.buffer)
			{
				l.lock();
				m_pool.ordered_free(j.buffer);
			}
		}
	}
}

<|endoftext|>


<commit_before>#include "DataSetModel.hh"

#include "DataSetItem.hh"
#include "MetaTypes.hh"

#include <QDebug>
#include <QIcon>

namespace aleph
{

namespace gui
{

DataSetModel::DataSetModel( QObject* parent )
  : QAbstractItemModel( parent )
  , _root( new DataSetItem( QString(), QVariant() ) )
{
  QList<DataSetItem*> topLevelItems = {
      new DataSetItem( tr("Persistence diagrams"), QVariant::fromValue( PersistenceDiagram() ), _root ),
      new DataSetItem( tr("Point clouds")        , QVariant::fromValue( SimplicialComplex()  ), _root ),
      new DataSetItem( tr("Simplicial complexes"), QVariant(), _root )
  };

  foreach( DataSetItem* item, topLevelItems )
  _root->append( item );
}

DataSetModel::~DataSetModel()
{
  delete _root;
}

QModelIndex DataSetModel::parent( const QModelIndex& index ) const
{
  if( !index.isValid() )
    return QModelIndex();

  auto child  = static_cast<DataSetItem*>( index.internalPointer() );
  auto parent = child->parent();

  if( parent == _root )
    return QModelIndex();

  return this->createIndex( parent->row(), 0, parent );
}

QModelIndex DataSetModel::index( int row, int column,
                                 const QModelIndex& parent ) const
{
  if( !this->hasIndex( row, column, parent ) )
    return QModelIndex();

  DataSetItem* parentItem = nullptr;
  if( !parent.isValid() )
    parentItem = _root;
  else
    parentItem = static_cast<DataSetItem*>( parent.internalPointer() );

  auto child = parentItem->child( row );
  if( child )
    return this->createIndex( row, column, child );
  else
    return QModelIndex();
}

int DataSetModel::rowCount( const QModelIndex& parent ) const
{
  DataSetItem* parentItem = nullptr;
  if( parent.column() > 0 )
    return 0;

  if( !parent.isValid() )
    parentItem = _root;
  else
    parentItem = static_cast<DataSetItem*>( parent.internalPointer() );

  return parentItem->childCount();
}

int DataSetModel::columnCount( const QModelIndex& parent ) const
{
  if( parent.isValid() )
    return static_cast<DataSetItem*>( parent.internalPointer() )->columnCount();
  else
    return _root->columnCount();
}

QVariant DataSetModel::headerData( int section,
                                   Qt::Orientation orientation,
                                   int role ) const
{
  if( orientation == Qt::Horizontal && role == Qt::DisplayRole )
    return DataSetItem::columnNames[section];

  return QVariant();
}

QVariant DataSetModel::data( const QModelIndex& index, int role ) const
{
  if( !index.isValid() )
    return QVariant();

  DataSetItem* item = static_cast<DataSetItem*>( index.internalPointer() );

  if( role == Qt::DecorationRole && index.column() == 0 && item->parent() == _root )
    return QIcon::fromTheme( "folder" );
  else if( role == Qt::DisplayRole )
    return item->data( index.column() );

  return QVariant();
}

void DataSetModel::add( const QString& title, const QVariant& data )
{
  int id_PersistenceDiagram = qMetaTypeId<PersistenceDiagram>();
  int id_SimplicialComplex  = qMetaTypeId<SimplicialComplex>();
  int userType              = data.userType();

  if( userType != id_PersistenceDiagram && userType != id_SimplicialComplex )
  {
    qDebug() << "Ignoring unknown user type";
    return;
  }

  for( int i = 0; i < _root->childCount(); i++ )
  {
    auto child = _root->child( i );
    if( child && child->type() == userType )
    {
      qDebug() << "Found proper parent item; adding data";
      child->append( new DataSetItem( title, data, child ) );
    }
  }
}

} // namespace gui

} // namespace aleph
<commit_msg>Fixed addition of simplicial complexes to data set viewer<commit_after>#include "DataSetModel.hh"

#include "DataSetItem.hh"
#include "MetaTypes.hh"

#include <QDebug>
#include <QIcon>

namespace aleph
{

namespace gui
{

DataSetModel::DataSetModel( QObject* parent )
  : QAbstractItemModel( parent )
  , _root( new DataSetItem( QString(), QVariant() ) )
{
  QList<DataSetItem*> topLevelItems = {
      new DataSetItem( tr("Persistence diagrams"), QVariant::fromValue( PersistenceDiagram() ), _root ),
      new DataSetItem( tr("Point clouds")        , QVariant(), _root ),
      new DataSetItem( tr("Simplicial complexes"), QVariant::fromValue( SimplicialComplex()  ), _root )
  };

  foreach( DataSetItem* item, topLevelItems )
  _root->append( item );
}

DataSetModel::~DataSetModel()
{
  delete _root;
}

QModelIndex DataSetModel::parent( const QModelIndex& index ) const
{
  if( !index.isValid() )
    return QModelIndex();

  auto child  = static_cast<DataSetItem*>( index.internalPointer() );
  auto parent = child->parent();

  if( parent == _root )
    return QModelIndex();

  return this->createIndex( parent->row(), 0, parent );
}

QModelIndex DataSetModel::index( int row, int column,
                                 const QModelIndex& parent ) const
{
  if( !this->hasIndex( row, column, parent ) )
    return QModelIndex();

  DataSetItem* parentItem = nullptr;
  if( !parent.isValid() )
    parentItem = _root;
  else
    parentItem = static_cast<DataSetItem*>( parent.internalPointer() );

  auto child = parentItem->child( row );
  if( child )
    return this->createIndex( row, column, child );
  else
    return QModelIndex();
}

int DataSetModel::rowCount( const QModelIndex& parent ) const
{
  DataSetItem* parentItem = nullptr;
  if( parent.column() > 0 )
    return 0;

  if( !parent.isValid() )
    parentItem = _root;
  else
    parentItem = static_cast<DataSetItem*>( parent.internalPointer() );

  return parentItem->childCount();
}

int DataSetModel::columnCount( const QModelIndex& parent ) const
{
  if( parent.isValid() )
    return static_cast<DataSetItem*>( parent.internalPointer() )->columnCount();
  else
    return _root->columnCount();
}

QVariant DataSetModel::headerData( int section,
                                   Qt::Orientation orientation,
                                   int role ) const
{
  if( orientation == Qt::Horizontal && role == Qt::DisplayRole )
    return DataSetItem::columnNames[section];

  return QVariant();
}

QVariant DataSetModel::data( const QModelIndex& index, int role ) const
{
  if( !index.isValid() )
    return QVariant();

  DataSetItem* item = static_cast<DataSetItem*>( index.internalPointer() );

  if( role == Qt::DecorationRole && index.column() == 0 && item->parent() == _root )
    return QIcon::fromTheme( "folder" );
  else if( role == Qt::DisplayRole )
    return item->data( index.column() );

  return QVariant();
}

void DataSetModel::add( const QString& title, const QVariant& data )
{
  int id_PersistenceDiagram = qMetaTypeId<PersistenceDiagram>();
  int id_SimplicialComplex  = qMetaTypeId<SimplicialComplex>();
  int userType              = data.userType();

  if( userType != id_PersistenceDiagram && userType != id_SimplicialComplex )
  {
    qDebug() << "Ignoring unknown user type";
    return;
  }

  for( int i = 0; i < _root->childCount(); i++ )
  {
    auto child = _root->child( i );
    if( child && child->type() == userType )
    {
      qDebug() << "Found proper parent item; adding data";
      child->append( new DataSetItem( title, data, child ) );
    }
  }
}

} // namespace gui

} // namespace aleph
<|endoftext|>


<commit_before>#pragma once

#include <mapbox/geojsonvt/types.hpp>

namespace mapbox {
namespace geojsonvt {

struct Tile {
    mapbox::geometry::feature_collection<int16_t> features;
    uint32_t num_points = 0;
    uint32_t num_simplified = 0;
};

namespace detail {

class InternalTile {
public:
    const uint8_t z;
    const uint32_t x;
    const uint32_t y;

    vt_features source_features;
    bool is_solid = false;
    mapbox::geometry::box<double> bbox = { { 2, 1 }, { -1, 0 } };

    Tile tile;

    InternalTile(const vt_features& source,
                 const uint8_t z_,
                 const uint32_t x_,
                 const uint32_t y_,
                 const uint16_t extent_,
                 const uint16_t buffer,
                 const double tolerance_)
        : z(z_),
          x(x_),
          y(y_),
          z2(std::pow(2, z)),
          extent(extent_),
          tolerance(tolerance_),
          sq_tolerance(tolerance_ * tolerance_) {

        for (const auto& feature : source) {
            const auto& geom = feature.geometry;
            const auto& props = feature.properties;

            tile.num_points += feature.num_points;

            vt_geometry::visit(geom, [&] (const auto& g) {
                visit(transform(g), props);
            });

            bbox.min.x = std::min(feature.bbox.min.x, bbox.min.x);
            bbox.min.y = std::min(feature.bbox.min.y, bbox.min.y);
            bbox.max.x = std::max(feature.bbox.max.x, bbox.max.x);
            bbox.max.y = std::max(feature.bbox.max.y, bbox.max.y);
        }

        is_solid = isSolid(buffer);
    }

private:
    const double z2;
    const uint16_t extent;
    const double tolerance;
    const double sq_tolerance;

    bool isSolid(const uint16_t buffer) {
        if (tile.features.size() != 1)
            return false;

        const auto& geom = tile.features.front().geometry;
        if (!geom.is<mapbox::geometry::polygon<int16_t>>())
            return false;

        const auto& rings = geom.get<mapbox::geometry::polygon<int16_t>>();
        if (rings.size() > 1)
            return false;

        const auto& ring = rings.front();
        if (ring.size() != 5)
            return false;

        const int16_t min = -static_cast<int16_t>(buffer);
        const int16_t max = static_cast<int16_t>(extent + buffer);
        for (const auto& p : ring) {
            if ((p.x != min && p.x != max) || (p.y != min && p.y != max))
                return false;
        }

        return true;
    }

    void visit(const geometry::point<int16_t>& point, const property_map& props) {
        tile.features.push_back({ { point }, props });
    }

    void visit(const geometry::line_string<int16_t>& line, const property_map& props) {
        if (!line.empty())
            tile.features.push_back({ { line }, props });
    }

    void visit(const geometry::polygon<int16_t>& polygon, const property_map& props) {
        if (!polygon.empty())
            tile.features.push_back({ { polygon }, props });
    }

    template <class T>
    void visit(const T& multi, const property_map& props) {
        switch (multi.size()) {
        case 0: break;
        case 1:  tile.features.push_back({ { multi[0] }, props }); break;
        default: tile.features.push_back({ { multi }, props });    break;
        }
    }

    mapbox::geometry::point<int16_t> transform(const vt_point& p) {
        ++tile.num_simplified;
        return { static_cast<int16_t>(std::round((p.x * z2 - x) * extent)),
                 static_cast<int16_t>(std::round((p.y * z2 - y) * extent)) };
    }

    mapbox::geometry::multi_point<int16_t> transform(const vt_multi_point& points) {
        mapbox::geometry::multi_point<int16_t> result;
        result.reserve(points.size());
        for (const auto& p : points) {
            result.push_back(transform(p));
        }
        return result;
    }

    mapbox::geometry::line_string<int16_t> transform(const vt_line_string& line) {
        mapbox::geometry::line_string<int16_t> result;
        if (line.dist > tolerance) {
            for (const auto& p : line) {
                if (p.z > sq_tolerance)
                    result.push_back(transform(p));
            }
        }
        return result;
    }

    mapbox::geometry::linear_ring<int16_t> transform(const vt_linear_ring& ring) {
        mapbox::geometry::linear_ring<int16_t> result;
        if (ring.area > sq_tolerance) {
            for (const auto& p : ring) {
                if (p.z > sq_tolerance)
                    result.push_back(transform(p));
            }
        }
        return result;
    }

    mapbox::geometry::multi_line_string<int16_t> transform(const vt_multi_line_string& lines) {
        mapbox::geometry::multi_line_string<int16_t> result;
        for (const auto& line : lines) {
            if (line.dist > tolerance)
                result.push_back(transform(line));
        }
        return result;
    }

    mapbox::geometry::polygon<int16_t> transform(const vt_polygon& rings) {
        mapbox::geometry::polygon<int16_t> result;
        for (const auto& ring : rings) {
            if (ring.area > sq_tolerance)
                result.push_back(transform(ring));
        }
        return result;
    }

    mapbox::geometry::multi_polygon<int16_t> transform(const vt_multi_polygon& polygons) {
        mapbox::geometry::multi_polygon<int16_t> result;
        for (const auto& polygon : polygons) {
            const auto p = transform(polygon);
            if (!p.empty())
                result.push_back(p);
        }
        return result;
    }
};

} // namespace detail
} // namespace geojsonvt
} // namespace mapbox
<commit_msg>Fewer copies<commit_after>#pragma once

#include <mapbox/geojsonvt/types.hpp>

namespace mapbox {
namespace geojsonvt {

struct Tile {
    mapbox::geometry::feature_collection<int16_t> features;
    uint32_t num_points = 0;
    uint32_t num_simplified = 0;
};

namespace detail {

class InternalTile {
public:
    const uint8_t z;
    const uint32_t x;
    const uint32_t y;

    vt_features source_features;
    bool is_solid = false;
    mapbox::geometry::box<double> bbox = { { 2, 1 }, { -1, 0 } };

    Tile tile;

    InternalTile(const vt_features& source,
                 const uint8_t z_,
                 const uint32_t x_,
                 const uint32_t y_,
                 const uint16_t extent_,
                 const uint16_t buffer,
                 const double tolerance_)
        : z(z_),
          x(x_),
          y(y_),
          z2(std::pow(2, z)),
          extent(extent_),
          tolerance(tolerance_),
          sq_tolerance(tolerance_ * tolerance_) {

        for (const auto& feature : source) {
            const auto& geom = feature.geometry;
            const auto& props = feature.properties;

            tile.num_points += feature.num_points;

            vt_geometry::visit(geom, [&] (const auto& g) {
                visit(transform(g), props);
            });

            bbox.min.x = std::min(feature.bbox.min.x, bbox.min.x);
            bbox.min.y = std::min(feature.bbox.min.y, bbox.min.y);
            bbox.max.x = std::max(feature.bbox.max.x, bbox.max.x);
            bbox.max.y = std::max(feature.bbox.max.y, bbox.max.y);
        }

        is_solid = isSolid(buffer);
    }

private:
    const double z2;
    const uint16_t extent;
    const double tolerance;
    const double sq_tolerance;

    bool isSolid(const uint16_t buffer) {
        if (tile.features.size() != 1)
            return false;

        const auto& geom = tile.features.front().geometry;
        if (!geom.is<mapbox::geometry::polygon<int16_t>>())
            return false;

        const auto& rings = geom.get<mapbox::geometry::polygon<int16_t>>();
        if (rings.size() > 1)
            return false;

        const auto& ring = rings.front();
        if (ring.size() != 5)
            return false;

        const int16_t min = -static_cast<int16_t>(buffer);
        const int16_t max = static_cast<int16_t>(extent + buffer);
        for (const auto& p : ring) {
            if ((p.x != min && p.x != max) || (p.y != min && p.y != max))
                return false;
        }

        return true;
    }

    void visit(geometry::point<int16_t>&& point, const property_map& props) {
        tile.features.push_back({ std::move(point), props });
    }

    void visit(geometry::line_string<int16_t>&& line, const property_map& props) {
        if (!line.empty())
            tile.features.push_back({ std::move(line), props });
    }

    void visit(geometry::polygon<int16_t>&& polygon, const property_map& props) {
        if (!polygon.empty())
            tile.features.push_back({ std::move(polygon), props });
    }

    template <class T>
    void visit(T&& multi, const property_map& props) {
        switch (multi.size()) {
        case 0: break;
        case 1:  tile.features.push_back({ std::move(multi[0]), props }); break;
        default: tile.features.push_back({ std::move(multi),    props }); break;
        }
    }

    mapbox::geometry::point<int16_t> transform(const vt_point& p) {
        ++tile.num_simplified;
        return { static_cast<int16_t>(std::round((p.x * z2 - x) * extent)),
                 static_cast<int16_t>(std::round((p.y * z2 - y) * extent)) };
    }

    mapbox::geometry::multi_point<int16_t> transform(const vt_multi_point& points) {
        mapbox::geometry::multi_point<int16_t> result;
        result.reserve(points.size());
        for (const auto& p : points) {
            result.push_back(transform(p));
        }
        return result;
    }

    mapbox::geometry::line_string<int16_t> transform(const vt_line_string& line) {
        mapbox::geometry::line_string<int16_t> result;
        if (line.dist > tolerance) {
            for (const auto& p : line) {
                if (p.z > sq_tolerance)
                    result.push_back(transform(p));
            }
        }
        return result;
    }

    mapbox::geometry::linear_ring<int16_t> transform(const vt_linear_ring& ring) {
        mapbox::geometry::linear_ring<int16_t> result;
        if (ring.area > sq_tolerance) {
            for (const auto& p : ring) {
                if (p.z > sq_tolerance)
                    result.push_back(transform(p));
            }
        }
        return result;
    }

    mapbox::geometry::multi_line_string<int16_t> transform(const vt_multi_line_string& lines) {
        mapbox::geometry::multi_line_string<int16_t> result;
        for (const auto& line : lines) {
            if (line.dist > tolerance)
                result.push_back(transform(line));
        }
        return result;
    }

    mapbox::geometry::polygon<int16_t> transform(const vt_polygon& rings) {
        mapbox::geometry::polygon<int16_t> result;
        for (const auto& ring : rings) {
            if (ring.area > sq_tolerance)
                result.push_back(transform(ring));
        }
        return result;
    }

    mapbox::geometry::multi_polygon<int16_t> transform(const vt_multi_polygon& polygons) {
        mapbox::geometry::multi_polygon<int16_t> result;
        for (const auto& polygon : polygons) {
            const auto p = transform(polygon);
            if (!p.empty())
                result.push_back(p);
        }
        return result;
    }
};

} // namespace detail
} // namespace geojsonvt
} // namespace mapbox
<|endoftext|>


<commit_before>/* Copyright (C) 2017 INRA
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublipnse, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef ORG_VLEPROJECT_BARYONYX_SOLVER_ITM_HPP
#define ORG_VLEPROJECT_BARYONYX_SOLVER_ITM_HPP

#include <baryonyx/core-compare>
#include <baryonyx/core-out>
#include <utility>

namespace baryonyx {
namespace itm {

result
inequalities_1coeff_wedelin_solve(const std::shared_ptr<context>& ctx,
                                  problem& pb);

result
inequalities_1coeff_wedelin_optimize(const std::shared_ptr<context>& ctx,
                                     problem& pb,
                                     int thread);

result
inequalities_Zcoeff_wedelin_solve(const std::shared_ptr<context>& ctx,
                                  problem& pb);

result
inequalities_Zcoeff_wedelin_optimize(const std::shared_ptr<context>& ctx,
                                     problem& pb,
                                     int thread);

enum class floating_point_type
{
    float_type,
    double_type,
    longdouble_type
};

inline const char*
floating_point_type_to_string(floating_point_type type) noexcept
{
    static const char* ret[] = {
        "float", "double", "longdouble",
    };

    switch (type) {
    case floating_point_type::float_type:
        return ret[0];
    case floating_point_type::double_type:
        return ret[1];
    case floating_point_type::longdouble_type:
        return ret[2];
    default:
        return ret[0];
    };
}

inline floating_point_type
get_floating_point_type(const std::shared_ptr<context>& ctx) noexcept
{
    auto str = ctx->get_string_parameter("floating-point-type", "double");

    if (str == "float")
        return floating_point_type::float_type;
    if (str == "longdouble")
        return floating_point_type::longdouble_type;

    return floating_point_type::double_type;
}

enum class constraint_order
{
    none,
    reversing,
    random_sorting,
    infeasibility_decr,
    infeasibility_incr,
};

inline const char*
constraint_order_to_string(constraint_order type) noexcept
{
    static const char* ret[] = {
        "none",
        "reversing",
        "random-sorting",
        "infeasibility-decr",
        "infeasibility-incr",
    };

    switch (type) {
    case constraint_order::none:
        return ret[0];
    case constraint_order::reversing:
        return ret[1];
    case constraint_order::random_sorting:
        return ret[2];
    case constraint_order::infeasibility_decr:
        return ret[3];
    case constraint_order::infeasibility_incr:
        return ret[4];
    default:
        return ret[0];
    }
}

inline constraint_order
get_constraint_order(const std::shared_ptr<context>& ctx) noexcept
{
    auto str = ctx->get_string_parameter("constraint-order", "none");

    if (str == "reversing")
        return constraint_order::reversing;
    if (str == "random-sorting")
        return constraint_order::random_sorting;
    if (str == "infeasibility-decr")
        return constraint_order::infeasibility_decr;
    if (str == "infeasibility-incr")
        return constraint_order::infeasibility_incr;

    return constraint_order::none;
}

struct parameters
{
    parameters(const std::shared_ptr<context>& ctx)
      : preprocessing(ctx->get_string_parameter("preprocessing", "none"))
      , norm(ctx->get_string_parameter("norm", "inf"))
      , time_limit(ctx->get_real_parameter("time-limit", -1.0))
      , theta(ctx->get_real_parameter("theta", 0.5))
      , delta(ctx->get_real_parameter("delta", 0.01))
      , kappa_min(ctx->get_real_parameter("kappa-min", 0.0))
      , kappa_step(ctx->get_real_parameter("kappa-step", 1.e-3))
      , kappa_max(ctx->get_real_parameter("kappa-max", 0.6))
      , alpha(ctx->get_real_parameter("alpha", 1.0))
      , pushing_k_factor(ctx->get_real_parameter("pushing-k-factor", 0.9))
      , pushing_objective_amplifier(
          ctx->get_real_parameter("pushing-objective-amplifier", 5))
      , pushes_limit(ctx->get_integer_parameter("pushes-limit", 10))
      , pushing_iteration_limit(
          ctx->get_integer_parameter("pushing-iteration-limit", 20))
      , limit(ctx->get_integer_parameter("limit", 1000))
      , w(ctx->get_integer_parameter("w", 500))
      , print_level(ctx->get_integer_parameter("print-level", 0))
      , order(get_constraint_order(ctx))
      , float_type(get_floating_point_type(ctx))
    {
        if (limit < 0)
            limit = std::numeric_limits<int>::max();

        ctx->info("solver parameters:\n"
                  "  - preprocessing: %s\n"
                  "  - constraint-order: %s\n"
                  "  - time-limit: %.10g\n"
                  "  - theta: %.10g\n"
                  "  - delta: %.10g\n"
                  "  - limit: %d\n"
                  "  - kappa: %.10g %.10g %.10g\n"
                  "  - alpha: %.10g\n"
                  "  - w: %d\n"
                  "  - norm: %s\n"
                  "  - print-level: %d\n"
                  "  - float-point-type: %s\n",
                  preprocessing.c_str(),
                  constraint_order_to_string(order),
                  time_limit,
                  theta,
                  delta,
                  limit,
                  kappa_min,
                  kappa_step,
                  kappa_max,
                  alpha,
                  w,
                  norm.c_str(),
                  print_level,
                  floating_point_type_to_string(float_type));

        if (ctx->optimize())
            ctx->info("optimizer parameters:\n"
                      "  - pushed-limit: %d\n"
                      "  - pushing-objective-amplifier: %.10g\n"
                      "  - pushing-iteration-limit: %d\n"
                      "  - pushing-k-factor: %.10g\n",
                      pushes_limit,
                      pushing_objective_amplifier,
                      pushing_iteration_limit,
                      pushing_k_factor);
    }

    std::string preprocessing;
    std::string norm;
    double time_limit;
    double theta;
    double delta;
    double kappa_min;
    double kappa_step;
    double kappa_max;
    double alpha;
    double pushing_k_factor;
    double pushing_objective_amplifier;
    int pushes_limit;
    int pushing_iteration_limit;
    int limit;
    int w;
    int print_level;
    constraint_order order;
    floating_point_type float_type;
};

struct merged_constraint
{
    merged_constraint(std::vector<function_element> elements_,
                      int min_,
                      int max_,
                      int id_)
      : elements(std::move(elements_))
      , min(min_)
      , max(max_)
      , id(id_)
    {
    }

    std::vector<function_element> elements;
    int min;
    int max;
    int id;
};

std::vector<merged_constraint>
make_merged_constraints(const std::shared_ptr<context>& ctx,
                        const problem& pb,
                        const parameters& p);
}
}

#endif
<commit_msg>itm: fix help imformation<commit_after>/* Copyright (C) 2017 INRA
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublipnse, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef ORG_VLEPROJECT_BARYONYX_SOLVER_ITM_HPP
#define ORG_VLEPROJECT_BARYONYX_SOLVER_ITM_HPP

#include <baryonyx/core-compare>
#include <baryonyx/core-out>
#include <utility>

namespace baryonyx {
namespace itm {

result
inequalities_1coeff_wedelin_solve(const std::shared_ptr<context>& ctx,
                                  problem& pb);

result
inequalities_1coeff_wedelin_optimize(const std::shared_ptr<context>& ctx,
                                     problem& pb,
                                     int thread);

result
inequalities_Zcoeff_wedelin_solve(const std::shared_ptr<context>& ctx,
                                  problem& pb);

result
inequalities_Zcoeff_wedelin_optimize(const std::shared_ptr<context>& ctx,
                                     problem& pb,
                                     int thread);

enum class floating_point_type
{
    float_type,
    double_type,
    longdouble_type
};

inline const char*
floating_point_type_to_string(floating_point_type type) noexcept
{
    static const char* ret[] = {
        "float", "double", "longdouble",
    };

    switch (type) {
    case floating_point_type::float_type:
        return ret[0];
    case floating_point_type::double_type:
        return ret[1];
    case floating_point_type::longdouble_type:
        return ret[2];
    default:
        return ret[0];
    };
}

inline floating_point_type
get_floating_point_type(const std::shared_ptr<context>& ctx) noexcept
{
    auto str = ctx->get_string_parameter("floating-point-type", "double");

    if (str == "float")
        return floating_point_type::float_type;
    if (str == "longdouble")
        return floating_point_type::longdouble_type;

    return floating_point_type::double_type;
}

enum class constraint_order
{
    none,
    reversing,
    random_sorting,
    infeasibility_decr,
    infeasibility_incr,
};

inline const char*
constraint_order_to_string(constraint_order type) noexcept
{
    static const char* ret[] = {
        "none",
        "reversing",
        "random-sorting",
        "infeasibility-decr",
        "infeasibility-incr",
    };

    switch (type) {
    case constraint_order::none:
        return ret[0];
    case constraint_order::reversing:
        return ret[1];
    case constraint_order::random_sorting:
        return ret[2];
    case constraint_order::infeasibility_decr:
        return ret[3];
    case constraint_order::infeasibility_incr:
        return ret[4];
    default:
        return ret[0];
    }
}

inline constraint_order
get_constraint_order(const std::shared_ptr<context>& ctx) noexcept
{
    auto str = ctx->get_string_parameter("constraint-order", "none");

    if (str == "reversing")
        return constraint_order::reversing;
    if (str == "random-sorting")
        return constraint_order::random_sorting;
    if (str == "infeasibility-decr")
        return constraint_order::infeasibility_decr;
    if (str == "infeasibility-incr")
        return constraint_order::infeasibility_incr;

    return constraint_order::none;
}

struct parameters
{
    parameters(const std::shared_ptr<context>& ctx)
      : preprocessing(ctx->get_string_parameter("preprocessing", "none"))
      , norm(ctx->get_string_parameter("norm", "inf"))
      , time_limit(ctx->get_real_parameter("time-limit", -1.0))
      , theta(ctx->get_real_parameter("theta", 0.5))
      , delta(ctx->get_real_parameter("delta", 0.01))
      , kappa_min(ctx->get_real_parameter("kappa-min", 0.0))
      , kappa_step(ctx->get_real_parameter("kappa-step", 1.e-3))
      , kappa_max(ctx->get_real_parameter("kappa-max", 0.6))
      , alpha(ctx->get_real_parameter("alpha", 1.0))
      , pushing_k_factor(ctx->get_real_parameter("pushing-k-factor", 0.9))
      , pushing_objective_amplifier(
          ctx->get_real_parameter("pushing-objective-amplifier", 5))
      , pushes_limit(ctx->get_integer_parameter("pushes-limit", 10))
      , pushing_iteration_limit(
          ctx->get_integer_parameter("pushing-iteration-limit", 20))
      , limit(ctx->get_integer_parameter("limit", 1000))
      , w(ctx->get_integer_parameter("w", 500))
      , print_level(ctx->get_integer_parameter("print-level", 0))
      , order(get_constraint_order(ctx))
      , float_type(get_floating_point_type(ctx))
    {
        if (limit < 0)
            limit = std::numeric_limits<int>::max();

        ctx->info("solver parameters:\n"
                  "  - preprocessing: %s\n"
                  "  - constraint-order: %s\n"
                  "  - time-limit: %.10g\n"
                  "  - theta: %.10g\n"
                  "  - delta: %.10g\n"
                  "  - limit: %d\n"
                  "  - kappa: %.10g %.10g %.10g\n"
                  "  - alpha: %.10g\n"
                  "  - w: %d\n"
                  "  - norm: %s\n"
                  "  - print-level: %d\n"
                  "  - floating-point-type: %s\n",
                  preprocessing.c_str(),
                  constraint_order_to_string(order),
                  time_limit,
                  theta,
                  delta,
                  limit,
                  kappa_min,
                  kappa_step,
                  kappa_max,
                  alpha,
                  w,
                  norm.c_str(),
                  print_level,
                  floating_point_type_to_string(float_type));

        if (ctx->optimize())
            ctx->info("optimizer parameters:\n"
                      "  - pushes-limit: %d\n"
                      "  - pushing-objective-amplifier: %.10g\n"
                      "  - pushing-iteration-limit: %d\n"
                      "  - pushing-k-factor: %.10g\n",
                      pushes_limit,
                      pushing_objective_amplifier,
                      pushing_iteration_limit,
                      pushing_k_factor);
    }

    std::string preprocessing;
    std::string norm;
    double time_limit;
    double theta;
    double delta;
    double kappa_min;
    double kappa_step;
    double kappa_max;
    double alpha;
    double pushing_k_factor;
    double pushing_objective_amplifier;
    int pushes_limit;
    int pushing_iteration_limit;
    int limit;
    int w;
    int print_level;
    constraint_order order;
    floating_point_type float_type;
};

struct merged_constraint
{
    merged_constraint(std::vector<function_element> elements_,
                      int min_,
                      int max_,
                      int id_)
      : elements(std::move(elements_))
      , min(min_)
      , max(max_)
      , id(id_)
    {
    }

    std::vector<function_element> elements;
    int min;
    int max;
    int id;
};

std::vector<merged_constraint>
make_merged_constraints(const std::shared_ptr<context>& ctx,
                        const problem& pb,
                        const parameters& p);
}
}

#endif
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

#include "min_heap.hpp"

#define LEFT_CHILD(i) ((i << 1) + 1)
#define RIGHT_CHILD(i) ((i << 1) + 2)
#define PARENT_ENTRY(i) ((i - 1) >> 1)

template <class P, class V> MinHeap<P, V>::MinHeap(int size) {
    this->length = size;
    this->occupied = 0;
    this->map = (int *) calloc(size, sizeof(int));
    this->array = (struct MinHeapElement<P, V> *) calloc(size, sizeof(MinHeapElement<P, V>));

    for (int i = 0; i < size; i++) {
        this->map[i] = -1;
    }
}

template <class P, class V> MinHeap<P, V>::~MinHeap() {
    free(this->map);
    free(this->array);
}

template <class P, class V> void MinHeap<P, V>::swap(V ia, V ib) {
    MinHeapElement<P, V> *a, *b, tmp;

    a = this->array + ia;
    b = this->array + ib;

    tmp = *a;
    *a = *b;
    *b = tmp;

    this->map[b->value] = ib;
    this->map[a->value] = ia;
}

template <class P, class V> void MinHeap<P, V>::update(V index) {
    MinHeapElement<P, V> *elem, *parent;
    int parent_index;

    while (index > 0) {
        parent_index = PARENT_ENTRY(index);

        elem = this->array + index;
        parent = this->array + parent_index;

        if (elem->priority < parent->priority) {
            this->swap(index, parent_index);
            index = parent_index;
        } else {
            break;
        }
    }
}

template <class P, class V> void MinHeap<P, V>::decrease_raw(P priority, V value) {
    int index = this->map[value];

    if (index != -1) {
        #pragma omp critical(min_heap_lock)
        {
            this->array[index].priority = priority;
            this->update(index);
        }
    }
}

template <class P, class V> bool MinHeap<P, V>::decrease(P priority, V value) {
    int index = this->map[value];

    if (index != -1 && priority < this->array[index].priority) {
        #pragma omp critical(min_heap_lock)
        {
            this->array[index].priority = priority;
            this->update(index);
        }

        return true;
    } else {
        return false;
    }
}

template <class P, class V> void MinHeap<P, V>::insert(P priority, V value) {
    MinHeapElement<P, V> *elem;
    int index;

    index = this->occupied++;
    elem = this->array + index;

    elem->priority = priority;
    elem->value = value;

    this->map[value] = index;

    this->update(index);
}

template <class P, class V> V MinHeap<P, V>::extract() {
    MinHeapElement<P, V> *elem, *child_left, *child_right, *child_smallest;
    V rv = this->array[0].value, index, child_index;

    this->map[this->array[0].value] = -1;
    elem = this->array + --this->occupied;
    this->array[0].priority = elem->priority;
    this->array[0].value = elem->value;
    this->map[this->array[0].value] = 0;

    index = 0;

    while (index < this->occupied) {
        elem = this->array + index;

        if (LEFT_CHILD(index) < this->occupied) {
            child_left = this->array + LEFT_CHILD(index);
        } else {
            child_left = NULL;
        }

        if (RIGHT_CHILD(index) < this->occupied) {
            child_right = this->array + RIGHT_CHILD(index);
        } else {
            child_right = NULL;
        }

        if (child_right && child_right->priority < child_left->priority) {
            child_smallest = child_right;
            child_index = RIGHT_CHILD(index);
        } else if (child_right && child_left->priority <= child_right->priority) {
            child_smallest = child_left;
            child_index = LEFT_CHILD(index);
        } else if (child_left) {
            child_smallest = child_left;
            child_index = LEFT_CHILD(index);
        } else {
            break;
        }

        if (elem->priority > child_smallest->priority) {
            this->swap(index, child_index);
            index = child_index;
        } else {
            break;
        }
    }

    return rv;
}

template class MinHeap<float, int>;
<commit_msg>Fix a typo in the min heap.<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

#include "min_heap.hpp"

#define LEFT_CHILD(i) ((i << 1) + 1)
#define RIGHT_CHILD(i) ((i << 1) + 2)
#define PARENT_ENTRY(i) ((i - 1) >> 1)

template <class P, class V> MinHeap<P, V>::MinHeap(int size) {
    this->length = size;
    this->occupied = 0;
    this->map = (int *) calloc(size, sizeof(int));
    this->array = (MinHeapElement<P, V> *) calloc(size, sizeof(MinHeapElement<P, V>));

    for (int i = 0; i < size; i++) {
        this->map[i] = -1;
    }
}

template <class P, class V> MinHeap<P, V>::~MinHeap() {
    free(this->map);
    free(this->array);
}

template <class P, class V> void MinHeap<P, V>::swap(V ia, V ib) {
    MinHeapElement<P, V> *a, *b, tmp;

    a = this->array + ia;
    b = this->array + ib;

    tmp = *a;
    *a = *b;
    *b = tmp;

    this->map[b->value] = ib;
    this->map[a->value] = ia;
}

template <class P, class V> void MinHeap<P, V>::update(V index) {
    MinHeapElement<P, V> *elem, *parent;
    int parent_index;

    while (index > 0) {
        parent_index = PARENT_ENTRY(index);

        elem = this->array + index;
        parent = this->array + parent_index;

        if (elem->priority < parent->priority) {
            this->swap(index, parent_index);
            index = parent_index;
        } else {
            break;
        }
    }
}

template <class P, class V> void MinHeap<P, V>::decrease_raw(P priority, V value) {
    int index = this->map[value];

    if (index != -1) {
        #pragma omp critical(min_heap_lock)
        {
            this->array[index].priority = priority;
            this->update(index);
        }
    }
}

template <class P, class V> bool MinHeap<P, V>::decrease(P priority, V value) {
    int index = this->map[value];

    if (index != -1 && priority < this->array[index].priority) {
        #pragma omp critical(min_heap_lock)
        {
            this->array[index].priority = priority;
            this->update(index);
        }

        return true;
    } else {
        return false;
    }
}

template <class P, class V> void MinHeap<P, V>::insert(P priority, V value) {
    MinHeapElement<P, V> *elem;
    int index;

    index = this->occupied++;
    elem = this->array + index;

    elem->priority = priority;
    elem->value = value;

    this->map[value] = index;

    this->update(index);
}

template <class P, class V> V MinHeap<P, V>::extract() {
    MinHeapElement<P, V> *elem, *child_left, *child_right, *child_smallest;
    V rv = this->array[0].value, index, child_index;

    this->map[this->array[0].value] = -1;
    elem = this->array + --this->occupied;
    this->array[0].priority = elem->priority;
    this->array[0].value = elem->value;
    this->map[this->array[0].value] = 0;

    index = 0;

    while (index < this->occupied) {
        elem = this->array + index;

        if (LEFT_CHILD(index) < this->occupied) {
            child_left = this->array + LEFT_CHILD(index);
        } else {
            child_left = NULL;
        }

        if (RIGHT_CHILD(index) < this->occupied) {
            child_right = this->array + RIGHT_CHILD(index);
        } else {
            child_right = NULL;
        }

        if (child_right && child_right->priority < child_left->priority) {
            child_smallest = child_right;
            child_index = RIGHT_CHILD(index);
        } else if (child_right && child_left->priority <= child_right->priority) {
            child_smallest = child_left;
            child_index = LEFT_CHILD(index);
        } else if (child_left) {
            child_smallest = child_left;
            child_index = LEFT_CHILD(index);
        } else {
            break;
        }

        if (elem->priority > child_smallest->priority) {
            this->swap(index, child_index);
            index = child_index;
        } else {
            break;
        }
    }

    return rv;
}

template class MinHeap<float, int>;
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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
 *
 * 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 "modules/monitor/common/can_checker_factory.h"

#include "modules/monitor/hwmonitor/hw/esdcan/esdcan_checker.h"

/**
 * @file: hw_checker_factory.cc
 */

namespace apollo {
namespace monitor {

using ::apollo::drivers::canbus::CANCardParameter;
using ::apollo::monitor::HwCheckerInterface;
using ::apollo::monitor::hw::EsdCanChecker;

CanCheckerFactory::CanCheckerFactory() {}

void CanCheckerFactory::RegisterCanCheckers() {
  Register(CANCardParameter::FAKE_CAN,
           []() -> HwCheckerInterface* { return new EsdCanChecker(); });
}

std::unique_ptr<HwCheckerInterface> CanCheckerFactory::CreateCanChecker(
    const CANCardParameter& parameter) {
  auto factory = CreateObject(parameter.brand());
  if (!factory) {
    AERROR << "Failed to create CAN checker with parameter: "
           << parameter.DebugString();
  }
  return factory;
}

}  // namespace monitor
}  // namespace apollo

<commit_msg>Monitor: fix can_checker_factory<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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
 *
 * 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 "modules/monitor/common/can_checker_factory.h"

#include "modules/monitor/hwmonitor/hw/esdcan/esdcan_checker.h"

/**
 * @file: hw_checker_factory.cc
 */

namespace apollo {
namespace monitor {

using ::apollo::drivers::canbus::CANCardParameter;
using ::apollo::monitor::HwCheckerInterface;
using ::apollo::monitor::hw::EsdCanChecker;

CanCheckerFactory::CanCheckerFactory() {}

void CanCheckerFactory::RegisterCanCheckers() {
  Register(CANCardParameter::ESD_CAN,
           []() -> HwCheckerInterface* { return new EsdCanChecker(); });
}

std::unique_ptr<HwCheckerInterface> CanCheckerFactory::CreateCanChecker(
    const CANCardParameter& parameter) {
  auto factory = CreateObject(parameter.brand());
  if (!factory) {
    AERROR << "Failed to create CAN checker with parameter: "
           << parameter.DebugString();
  }
  return factory;
}

}  // namespace monitor
}  // namespace apollo
<|endoftext|>