<commit_before>// #define X(FORMAT, SIZE, TYPE, VK, DX, GLI, GLF, GLT)
X(rhi::image_format::rgba_unorm8,  4*1, rhi::attachment_type::color, VK_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,      GL_RGBA8,        GL_RGBA,         GL_UNSIGNED_BYTE)
X(rhi::image_format::rgba_srgb8,   4*1, rhi::attachment_type::color, VK_FORMAT_R8G8B8A8_SRGB,       DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8, GL_RGBA,         GL_UNSIGNED_BYTE)
X(rhi::image_format::rgba_norm8,   4*1, rhi::attachment_type::color, VK_FORMAT_R8G8B8A8_SNORM,      DXGI_FORMAT_R8G8B8A8_SNORM,      GL_RGBA8_SNORM,  GL_RGBA,         GL_BYTE)
X(rhi::image_format::rgba_uint8,   4*1, rhi::attachment_type::color, VK_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_R8G8B8A8_UINT,       GL_RGBA8UI,      GL_RGBA_INTEGER, GL_UNSIGNED_BYTE)
X(rhi::image_format::rgba_int8,    4*1, rhi::attachment_type::color, VK_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_R8G8B8A8_SINT,       GL_RGBA8I,       GL_RGBA_INTEGER, GL_BYTE)
X(rhi::image_format::rgba_unorm16, 4*2, rhi::attachment_type::color, VK_FORMAT_R16G16B16A16_UNORM,  DXGI_FORMAT_R16G16B16A16_UNORM,  GL_RGBA16,       GL_RGBA,         GL_UNSIGNED_SHORT)
X(rhi::image_format::rgba_norm16,  4*2, rhi::attachment_type::color, VK_FORMAT_R16G16B16A16_SNORM,  DXGI_FORMAT_R16G16B16A16_SNORM,  GL_RGBA16_SNORM, GL_RGBA,         GL_SHORT)
X(rhi::image_format::rgba_uint16,  4*2, rhi::attachment_type::color, VK_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_R16G16B16A16_UINT,   GL_RGBA16UI,     GL_RGBA_INTEGER, GL_UNSIGNED_SHORT)
X(rhi::image_format::rgba_int16,   4*2, rhi::attachment_type::color, VK_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_R16G16B16A16_SINT,   GL_RGBA16I,      GL_RGBA_INTEGER, GL_SHORT)
X(rhi::image_format::rgba_float16, 4*2, rhi::attachment_type::color, VK_FORMAT_R16G16B16A16_SFLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,  GL_RGBA16F,      GL_RGBA,         GL_HALF_FLOAT)
X(rhi::image_format::rgba_uint32,  4*4, rhi::attachment_type::color, VK_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_R32G32B32A32_UINT,   GL_RGBA32UI,     GL_RGBA_INTEGER, GL_UNSIGNED_INT)
X(rhi::image_format::rgba_int32,   4*4, rhi::attachment_type::color, VK_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_R32G32B32A32_SINT,   GL_RGBA32I,      GL_RGBA_INTEGER, GL_INT)
X(rhi::image_format::rgba_float32, 4*4, rhi::attachment_type::color, VK_FORMAT_R32G32B32A32_SFLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,  GL_RGBA32F,      GL_RGBA,         GL_FLOAT)
X(rhi::image_format::rgb_uint32,   3*4, rhi::attachment_type::color, VK_FORMAT_R32G32B32_UINT,      DXGI_FORMAT_R32G32B32_UINT,      GL_RGB32UI,      GL_RGB_INTEGER,  GL_UNSIGNED_INT)
X(rhi::image_format::rgb_int32,    3*4, rhi::attachment_type::color, VK_FORMAT_R32G32B32_SINT,      DXGI_FORMAT_R32G32B32_SINT,      GL_RGB32I,       GL_RGB_INTEGER,  GL_INT)
X(rhi::image_format::rgb_float32,  3*4, rhi::attachment_type::color, VK_FORMAT_R32G32B32_SFLOAT,    DXGI_FORMAT_R32G32B32_FLOAT,     GL_RGB32F,       GL_RGB,          GL_FLOAT)
X(rhi::image_format::rg_unorm8,    2*1, rhi::attachment_type::color, VK_FORMAT_R8G8_UNORM,          DXGI_FORMAT_R8G8_UNORM,          GL_RG8,          GL_RG,           GL_UNSIGNED_BYTE)
X(rhi::image_format::rg_norm8,     2*1, rhi::attachment_type::color, VK_FORMAT_R8G8_SNORM,          DXGI_FORMAT_R8G8_SNORM,          GL_RG8_SNORM,    GL_RG,           GL_BYTE)
X(rhi::image_format::rg_uint8,     2*1, rhi::attachment_type::color, VK_FORMAT_R8G8_UINT,           DXGI_FORMAT_R8G8_UINT,           GL_RG8UI,        GL_RG_INTEGER,   GL_UNSIGNED_BYTE)
X(rhi::image_format::rg_int8,      2*1, rhi::attachment_type::color, VK_FORMAT_R8G8_SINT,           DXGI_FORMAT_R8G8_SINT,           GL_RG8I,         GL_RG_INTEGER,   GL_BYTE)
X(rhi::image_format::rg_unorm16,   2*2, rhi::attachment_type::color, VK_FORMAT_R16G16_UNORM,        DXGI_FORMAT_R16G16_UNORM,        GL_RG16,         GL_RG,           GL_UNSIGNED_SHORT)
X(rhi::image_format::rg_norm16,    2*2, rhi::attachment_type::color, VK_FORMAT_R16G16_SNORM,        DXGI_FORMAT_R16G16_SNORM,        GL_RG16_SNORM,   GL_RG,           GL_SHORT)
X(rhi::image_format::rg_uint16,    2*2, rhi::attachment_type::color, VK_FORMAT_R16G16_UINT,         DXGI_FORMAT_R16G16_UINT,         GL_RG16UI,       GL_RG_INTEGER,   GL_UNSIGNED_SHORT)
X(rhi::image_format::rg_int16,     2*2, rhi::attachment_type::color, VK_FORMAT_R16G16_SINT,         DXGI_FORMAT_R16G16_SINT,         GL_RG16I,        GL_RG_INTEGER,   GL_SHORT)
X(rhi::image_format::rg_float16,   2*2, rhi::attachment_type::color, VK_FORMAT_R16G16_SFLOAT,       DXGI_FORMAT_R16G16_FLOAT,        GL_RG16F,        GL_RG,           GL_HALF_FLOAT)
X(rhi::image_format::rg_uint32,    2*4, rhi::attachment_type::color, VK_FORMAT_R32G32_UINT,         DXGI_FORMAT_R32G32_UINT,         GL_RG32UI,       GL_RG_INTEGER,   GL_UNSIGNED_INT)
X(rhi::image_format::rg_int32,     2*4, rhi::attachment_type::color, VK_FORMAT_R32G32_SINT,         DXGI_FORMAT_R32G32_SINT,         GL_RG32I,        GL_RG_INTEGER,   GL_INT)
X(rhi::image_format::rg_float32,   2*4, rhi::attachment_type::color, VK_FORMAT_R32G32_SFLOAT,       DXGI_FORMAT_R32G32_FLOAT,        GL_RG32F,        GL_RG,           GL_FLOAT)
X(rhi::image_format::r_unorm8,     1*1, rhi::attachment_type::color, VK_FORMAT_R8_UNORM,            DXGI_FORMAT_R8_UNORM,            GL_R8,           GL_RED,          GL_UNSIGNED_BYTE)
X(rhi::image_format::r_norm8,      1*1, rhi::attachment_type::color, VK_FORMAT_R8_SNORM,            DXGI_FORMAT_R8_SNORM,            GL_R8_SNORM,     GL_RED,          GL_BYTE)
X(rhi::image_format::r_uint8,      1*1, rhi::attachment_type::color, VK_FORMAT_R8_UINT,             DXGI_FORMAT_R8_UINT,             GL_R8UI,         GL_RED_INTEGER,  GL_UNSIGNED_BYTE)
X(rhi::image_format::r_int8,       1*1, rhi::attachment_type::color, VK_FORMAT_R8G8_SINT,           DXGI_FORMAT_R8_SINT,             GL_R8I,          GL_RED_INTEGER,  GL_BYTE)
X(rhi::image_format::r_unorm16,    1*2, rhi::attachment_type::color, VK_FORMAT_R16_UNORM,           DXGI_FORMAT_R16_UNORM,           GL_R16,          GL_RED,          GL_UNSIGNED_SHORT)
X(rhi::image_format::r_norm16,     1*2, rhi::attachment_type::color, VK_FORMAT_R16_SNORM,           DXGI_FORMAT_R16_SNORM,           GL_R16_SNORM,    GL_RED,          GL_SHORT)
X(rhi::image_format::r_uint16,     1*2, rhi::attachment_type::color, VK_FORMAT_R16_UINT,            DXGI_FORMAT_R16_UINT,            GL_R16UI,        GL_RED_INTEGER,  GL_UNSIGNED_SHORT)
X(rhi::image_format::r_int16,      1*2, rhi::attachment_type::color, VK_FORMAT_R16_SINT,            DXGI_FORMAT_R16_SINT,            GL_R16I,         GL_RED_INTEGER,  GL_SHORT)
X(rhi::image_format::r_float16,    1*2, rhi::attachment_type::color, VK_FORMAT_R16_SFLOAT,          DXGI_FORMAT_R16_FLOAT,           GL_R16F,         GL_RED,          GL_HALF_FLOAT)
X(rhi::image_format::r_uint32,     1*4, rhi::attachment_type::color, VK_FORMAT_R32_UINT,            DXGI_FORMAT_R32_UINT,            GL_R32UI,        GL_RED_INTEGER,  GL_UNSIGNED_INT)
X(rhi::image_format::r_int32,      1*4, rhi::attachment_type::color, VK_FORMAT_R32_SINT,            DXGI_FORMAT_R32_SINT,            GL_R32I,         GL_RED_INTEGER,  GL_INT)
X(rhi::image_format::r_float32,    1*4, rhi::attachment_type::color, VK_FORMAT_R32_SFLOAT,          DXGI_FORMAT_R32_FLOAT,           GL_R32F,         GL_RED,          GL_FLOAT)
X(rhi::image_format::depth_unorm16,          2, rhi::attachment_type::depth_stencil, VK_FORMAT_D16_UNORM,          DXGI_FORMAT_D16_UNORM,            GL_DEPTH_COMPONENT16,   GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT)
X(rhi::image_format::depth_unorm24_stencil8, 4, rhi::attachment_type::depth_stencil, VK_FORMAT_D24_UNORM_S8_UINT,  DXGI_FORMAT_D24_UNORM_S8_UINT,    GL_DEPTH24_STENCIL8,    GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8)
X(rhi::image_format::depth_float32,          4, rhi::attachment_type::depth_stencil, VK_FORMAT_D32_SFLOAT,         DXGI_FORMAT_D32_FLOAT,            GL_DEPTH_COMPONENT32F,  GL_DEPTH_COMPONENT, GL_FLOAT)
X(rhi::image_format::depth_float32_stencil8, 8, rhi::attachment_type::depth_stencil, VK_FORMAT_D32_SFLOAT_S8_UINT, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8,   GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
<commit_msg>Formatting changes to format table.<commit_after>// #define X(FORMAT, SIZE, TYPE, VK, DX, GLI, GLF, GLT)
X(rhi::image_format::rgba_unorm8,            4*1, rhi::attachment_type::color,       VK_FORMAT_R8G8B8A8_UNORM,      DXGI_FORMAT_R8G8B8A8_UNORM,       GL_RGBA8,               GL_RGBA,            GL_UNSIGNED_BYTE)
X(rhi::image_format::rgba_srgb8,             4*1, rhi::attachment_type::color,       VK_FORMAT_R8G8B8A8_SRGB,       DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,  GL_SRGB8_ALPHA8,        GL_RGBA,            GL_UNSIGNED_BYTE)
X(rhi::image_format::rgba_norm8,             4*1, rhi::attachment_type::color,       VK_FORMAT_R8G8B8A8_SNORM,      DXGI_FORMAT_R8G8B8A8_SNORM,       GL_RGBA8_SNORM,         GL_RGBA,            GL_BYTE)
X(rhi::image_format::rgba_uint8,             4*1, rhi::attachment_type::color,       VK_FORMAT_R8G8B8A8_UINT,       DXGI_FORMAT_R8G8B8A8_UINT,        GL_RGBA8UI,             GL_RGBA_INTEGER,    GL_UNSIGNED_BYTE)
X(rhi::image_format::rgba_int8,              4*1, rhi::attachment_type::color,       VK_FORMAT_R8G8B8A8_SINT,       DXGI_FORMAT_R8G8B8A8_SINT,        GL_RGBA8I,              GL_RGBA_INTEGER,    GL_BYTE)
X(rhi::image_format::rgba_unorm16,           4*2, rhi::attachment_type::color,       VK_FORMAT_R16G16B16A16_UNORM,  DXGI_FORMAT_R16G16B16A16_UNORM,   GL_RGBA16,              GL_RGBA,            GL_UNSIGNED_SHORT)
X(rhi::image_format::rgba_norm16,            4*2, rhi::attachment_type::color,       VK_FORMAT_R16G16B16A16_SNORM,  DXGI_FORMAT_R16G16B16A16_SNORM,   GL_RGBA16_SNORM,        GL_RGBA,            GL_SHORT)
X(rhi::image_format::rgba_uint16,            4*2, rhi::attachment_type::color,       VK_FORMAT_R16G16B16A16_UINT,   DXGI_FORMAT_R16G16B16A16_UINT,    GL_RGBA16UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_SHORT)
X(rhi::image_format::rgba_int16,             4*2, rhi::attachment_type::color,       VK_FORMAT_R16G16B16A16_SINT,   DXGI_FORMAT_R16G16B16A16_SINT,    GL_RGBA16I,             GL_RGBA_INTEGER,    GL_SHORT)
X(rhi::image_format::rgba_float16,           4*2, rhi::attachment_type::color,       VK_FORMAT_R16G16B16A16_SFLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,   GL_RGBA16F,             GL_RGBA,            GL_HALF_FLOAT)
X(rhi::image_format::rgba_uint32,            4*4, rhi::attachment_type::color,       VK_FORMAT_R32G32B32A32_UINT,   DXGI_FORMAT_R32G32B32A32_UINT,    GL_RGBA32UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_INT)
X(rhi::image_format::rgba_int32,             4*4, rhi::attachment_type::color,       VK_FORMAT_R32G32B32A32_SINT,   DXGI_FORMAT_R32G32B32A32_SINT,    GL_RGBA32I,             GL_RGBA_INTEGER,    GL_INT)
X(rhi::image_format::rgba_float32,           4*4, rhi::attachment_type::color,       VK_FORMAT_R32G32B32A32_SFLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,   GL_RGBA32F,             GL_RGBA,            GL_FLOAT)
X(rhi::image_format::rgb_uint32,             3*4, rhi::attachment_type::color,       VK_FORMAT_R32G32B32_UINT,      DXGI_FORMAT_R32G32B32_UINT,       GL_RGB32UI,             GL_RGB_INTEGER,     GL_UNSIGNED_INT)
X(rhi::image_format::rgb_int32,              3*4, rhi::attachment_type::color,       VK_FORMAT_R32G32B32_SINT,      DXGI_FORMAT_R32G32B32_SINT,       GL_RGB32I,              GL_RGB_INTEGER,     GL_INT)
X(rhi::image_format::rgb_float32,            3*4, rhi::attachment_type::color,       VK_FORMAT_R32G32B32_SFLOAT,    DXGI_FORMAT_R32G32B32_FLOAT,      GL_RGB32F,              GL_RGB,             GL_FLOAT)
X(rhi::image_format::rg_unorm8,              2*1, rhi::attachment_type::color,       VK_FORMAT_R8G8_UNORM,          DXGI_FORMAT_R8G8_UNORM,           GL_RG8,                 GL_RG,              GL_UNSIGNED_BYTE)
X(rhi::image_format::rg_norm8,               2*1, rhi::attachment_type::color,       VK_FORMAT_R8G8_SNORM,          DXGI_FORMAT_R8G8_SNORM,           GL_RG8_SNORM,           GL_RG,              GL_BYTE)
X(rhi::image_format::rg_uint8,               2*1, rhi::attachment_type::color,       VK_FORMAT_R8G8_UINT,           DXGI_FORMAT_R8G8_UINT,            GL_RG8UI,               GL_RG_INTEGER,      GL_UNSIGNED_BYTE)
X(rhi::image_format::rg_int8,                2*1, rhi::attachment_type::color,       VK_FORMAT_R8G8_SINT,           DXGI_FORMAT_R8G8_SINT,            GL_RG8I,                GL_RG_INTEGER,      GL_BYTE)
X(rhi::image_format::rg_unorm16,             2*2, rhi::attachment_type::color,       VK_FORMAT_R16G16_UNORM,        DXGI_FORMAT_R16G16_UNORM,         GL_RG16,                GL_RG,              GL_UNSIGNED_SHORT)
X(rhi::image_format::rg_norm16,              2*2, rhi::attachment_type::color,       VK_FORMAT_R16G16_SNORM,        DXGI_FORMAT_R16G16_SNORM,         GL_RG16_SNORM,          GL_RG,              GL_SHORT)
X(rhi::image_format::rg_uint16,              2*2, rhi::attachment_type::color,       VK_FORMAT_R16G16_UINT,         DXGI_FORMAT_R16G16_UINT,          GL_RG16UI,              GL_RG_INTEGER,      GL_UNSIGNED_SHORT)
X(rhi::image_format::rg_int16,               2*2, rhi::attachment_type::color,       VK_FORMAT_R16G16_SINT,         DXGI_FORMAT_R16G16_SINT,          GL_RG16I,               GL_RG_INTEGER,      GL_SHORT)
X(rhi::image_format::rg_float16,             2*2, rhi::attachment_type::color,       VK_FORMAT_R16G16_SFLOAT,       DXGI_FORMAT_R16G16_FLOAT,         GL_RG16F,               GL_RG,              GL_HALF_FLOAT)
X(rhi::image_format::rg_uint32,              2*4, rhi::attachment_type::color,       VK_FORMAT_R32G32_UINT,         DXGI_FORMAT_R32G32_UINT,          GL_RG32UI,              GL_RG_INTEGER,      GL_UNSIGNED_INT)
X(rhi::image_format::rg_int32,               2*4, rhi::attachment_type::color,       VK_FORMAT_R32G32_SINT,         DXGI_FORMAT_R32G32_SINT,          GL_RG32I,               GL_RG_INTEGER,      GL_INT)
X(rhi::image_format::rg_float32,             2*4, rhi::attachment_type::color,       VK_FORMAT_R32G32_SFLOAT,       DXGI_FORMAT_R32G32_FLOAT,         GL_RG32F,               GL_RG,              GL_FLOAT)
X(rhi::image_format::r_unorm8,               1*1, rhi::attachment_type::color,       VK_FORMAT_R8_UNORM,            DXGI_FORMAT_R8_UNORM,             GL_R8,                  GL_RED,             GL_UNSIGNED_BYTE)
X(rhi::image_format::r_norm8,                1*1, rhi::attachment_type::color,       VK_FORMAT_R8_SNORM,            DXGI_FORMAT_R8_SNORM,             GL_R8_SNORM,            GL_RED,             GL_BYTE)
X(rhi::image_format::r_uint8,                1*1, rhi::attachment_type::color,       VK_FORMAT_R8_UINT,             DXGI_FORMAT_R8_UINT,              GL_R8UI,                GL_RED_INTEGER,     GL_UNSIGNED_BYTE)
X(rhi::image_format::r_int8,                 1*1, rhi::attachment_type::color,       VK_FORMAT_R8G8_SINT,           DXGI_FORMAT_R8_SINT,              GL_R8I,                 GL_RED_INTEGER,     GL_BYTE)
X(rhi::image_format::r_unorm16,              1*2, rhi::attachment_type::color,       VK_FORMAT_R16_UNORM,           DXGI_FORMAT_R16_UNORM,            GL_R16,                 GL_RED,             GL_UNSIGNED_SHORT)
X(rhi::image_format::r_norm16,               1*2, rhi::attachment_type::color,       VK_FORMAT_R16_SNORM,           DXGI_FORMAT_R16_SNORM,            GL_R16_SNORM,           GL_RED,             GL_SHORT)
X(rhi::image_format::r_uint16,               1*2, rhi::attachment_type::color,       VK_FORMAT_R16_UINT,            DXGI_FORMAT_R16_UINT,             GL_R16UI,               GL_RED_INTEGER,     GL_UNSIGNED_SHORT)
X(rhi::image_format::r_int16,                1*2, rhi::attachment_type::color,       VK_FORMAT_R16_SINT,            DXGI_FORMAT_R16_SINT,             GL_R16I,                GL_RED_INTEGER,     GL_SHORT)
X(rhi::image_format::r_float16,              1*2, rhi::attachment_type::color,       VK_FORMAT_R16_SFLOAT,          DXGI_FORMAT_R16_FLOAT,            GL_R16F,                GL_RED,             GL_HALF_FLOAT)
X(rhi::image_format::r_uint32,               1*4, rhi::attachment_type::color,       VK_FORMAT_R32_UINT,            DXGI_FORMAT_R32_UINT,             GL_R32UI,               GL_RED_INTEGER,     GL_UNSIGNED_INT)
X(rhi::image_format::r_int32,                1*4, rhi::attachment_type::color,       VK_FORMAT_R32_SINT,            DXGI_FORMAT_R32_SINT,             GL_R32I,                GL_RED_INTEGER,     GL_INT)
X(rhi::image_format::r_float32,              1*4, rhi::attachment_type::color,       VK_FORMAT_R32_SFLOAT,          DXGI_FORMAT_R32_FLOAT,            GL_R32F,                GL_RED,             GL_FLOAT)
X(rhi::image_format::depth_unorm16,          2, rhi::attachment_type::depth_stencil, VK_FORMAT_D16_UNORM,           DXGI_FORMAT_D16_UNORM,            GL_DEPTH_COMPONENT16,   GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT)
X(rhi::image_format::depth_unorm24_stencil8, 4, rhi::attachment_type::depth_stencil, VK_FORMAT_D24_UNORM_S8_UINT,   DXGI_FORMAT_D24_UNORM_S8_UINT,    GL_DEPTH24_STENCIL8,    GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8)
X(rhi::image_format::depth_float32,          4, rhi::attachment_type::depth_stencil, VK_FORMAT_D32_SFLOAT,          DXGI_FORMAT_D32_FLOAT,            GL_DEPTH_COMPONENT32F,  GL_DEPTH_COMPONENT, GL_FLOAT)
X(rhi::image_format::depth_float32_stencil8, 8, rhi::attachment_type::depth_stencil, VK_FORMAT_D32_SFLOAT_S8_UINT,  DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8,   GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
<|endoftext|>


<commit_before>#include <sstream>
#include <algorithm>
#include <fstream>
#include <iterator>
#include "logger.hpp"
#include "oddlib/stream.hpp"
#include "oddlib/exceptions.hpp"

namespace Oddlib
{
    Stream::Stream(std::vector<Uint8>&& data)
    {
        mSize = data.size();
        auto s = std::make_unique<std::stringstream>();
        std::copy(data.begin(), data.end(), std::ostream_iterator<unsigned char>(*s));
        mStream = std::move(s);
        Seek(0);
        mName = "Memory buffer (" + std::to_string(mSize) + ") bytes";
    }

    Stream::Stream(const std::string& fileName)
        : mName(fileName)
    {
        auto s = std::make_unique<std::ifstream>();
        s->open(fileName, std::ios::in | std::ios::binary | std::ios::ate);
        if (!*s)
        {
            LOG_ERROR("Lvl file not found " << fileName);
            throw Exception("File not found");
        }

        mSize = static_cast<size_t>(s->tellg());
        s->seekg(std::ios::beg);

        mStream = std::move(s);
    }

    template<typename T>
    void DoRead(std::unique_ptr<std::istream>& stream, T& output)
    {
        if (!stream->read(reinterpret_cast<char*>(&output), sizeof(output)))
        {
            throw Exception("Read failure");
        }
    }

    void Stream::ReadUInt8(Uint8& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadUInt32(Uint32& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadUInt16(Uint16& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadSInt16(Sint16& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadBytes(Sint8* pDest, size_t destSize)
    {
        if (!mStream->read(reinterpret_cast<char*>(pDest), destSize))
        {
            throw Exception("ReadBytes failure");
        }
    }

    void Stream::ReadBytes(Uint8* pDest, size_t destSize)
    {
        if (!mStream->read(reinterpret_cast<char*>(pDest), destSize))
        {
            throw Exception("ReadBytes failure");
        }
    }

    void Stream::Seek(size_t pos)
    {
        if (!mStream->seekg(pos))
        {
            throw Exception("Seek failure");
        }
    }

    bool Stream::AtEnd() const
    {
        const int c = mStream->peek();
        return (c == EOF);
    }

    size_t Stream::Pos() const
    {
        const size_t pos = static_cast<size_t>(mStream->tellg());
        return pos;
    }

    size_t Stream::Size() const
    {
        return mSize;
    }
}
<commit_msg>fix incorrect error log message<commit_after>#include <sstream>
#include <algorithm>
#include <fstream>
#include <iterator>
#include "logger.hpp"
#include "oddlib/stream.hpp"
#include "oddlib/exceptions.hpp"

namespace Oddlib
{
    Stream::Stream(std::vector<Uint8>&& data)
    {
        mSize = data.size();
        auto s = std::make_unique<std::stringstream>();
        std::copy(data.begin(), data.end(), std::ostream_iterator<unsigned char>(*s));
        mStream = std::move(s);
        Seek(0);
        mName = "Memory buffer (" + std::to_string(mSize) + ") bytes";
    }

    Stream::Stream(const std::string& fileName)
        : mName(fileName)
    {
        auto s = std::make_unique<std::ifstream>();
        s->open(fileName, std::ios::in | std::ios::binary | std::ios::ate);
        if (!*s)
        {
            LOG_ERROR("File not found " << fileName);
            throw Exception("File not found");
        }

        mSize = static_cast<size_t>(s->tellg());
        s->seekg(std::ios::beg);

        mStream = std::move(s);
    }

    template<typename T>
    void DoRead(std::unique_ptr<std::istream>& stream, T& output)
    {
        if (!stream->read(reinterpret_cast<char*>(&output), sizeof(output)))
        {
            throw Exception("Read failure");
        }
    }

    void Stream::ReadUInt8(Uint8& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadUInt32(Uint32& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadUInt16(Uint16& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadSInt16(Sint16& output)
    {
        DoRead<decltype(output)>(mStream, output);
    }

    void Stream::ReadBytes(Sint8* pDest, size_t destSize)
    {
        if (!mStream->read(reinterpret_cast<char*>(pDest), destSize))
        {
            throw Exception("ReadBytes failure");
        }
    }

    void Stream::ReadBytes(Uint8* pDest, size_t destSize)
    {
        if (!mStream->read(reinterpret_cast<char*>(pDest), destSize))
        {
            throw Exception("ReadBytes failure");
        }
    }

    void Stream::Seek(size_t pos)
    {
        if (!mStream->seekg(pos))
        {
            throw Exception("Seek failure");
        }
    }

    bool Stream::AtEnd() const
    {
        const int c = mStream->peek();
        return (c == EOF);
    }

    size_t Stream::Pos() const
    {
        const size_t pos = static_cast<size_t>(mStream->tellg());
        return pos;
    }

    size_t Stream::Size() const
    {
        return mSize;
    }
}
<|endoftext|>


<commit_before>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/* $Id: AliTRDtrackingSector.cxx 23810 2008-02-08 09:00:27Z hristov $ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  Tracking data container for one sector                                   //
//                                                                           //
//  Authors:                                                                 //
//    Alex Bercuci <A.Bercuci@gsi.de>                                        //
//    Markus Fasel <M.Fasel@gsi.de>                                          //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliTRDcalibDB.h"
#include "AliTRDCommonParam.h"
#include "AliTRDpadPlane.h"
#include "AliTRDtrackingSector.h"
#include "AliTRDtrackingChamber.h"

ClassImp(AliTRDtrackingSector)

//_____________________________________________________________________________
AliTRDtrackingSector::AliTRDtrackingSector()
  :fSector(-1)
  ,fN(0)
  ,fGeom(0x0)
{
  // Default constructor

  memset(fChamber, 0, AliTRDgeometry::kNdets*sizeof(AliTRDtrackingChamber*));
  memset(fIndex, 1, AliTRDgeometry::kNdets*sizeof(Char_t));
  memset(fX0, 0, AliTRDgeometry::kNlayer*sizeof(Float_t));
}

//_____________________________________________________________________________
AliTRDtrackingSector::AliTRDtrackingSector(AliTRDgeometry *geo, Int_t gs)
  :fSector(gs)
  ,fN(0)
  ,fGeom(geo)
{
  //
  // AliTRDtrackingSector Constructor
  //

  memset(fChamber, 0, AliTRDgeometry::kNdets*sizeof(AliTRDtrackingChamber*));
  memset(fIndex, 1, AliTRDgeometry::kNdets*sizeof(Char_t));
  memset(fX0, 0, AliTRDgeometry::kNlayer*sizeof(Float_t));
}

//_____________________________________________________________________________
void AliTRDtrackingSector::Init(const AliTRDReconstructor *rec, const AliTRDCalDet *cal)
{
// 	Steer building of tracking chambers and build tracking sector.
// 	Propagate radial position information (calibration/alignment aware) from chambers to sector level
//

  AliTRDchamberTimeBin *tb = 0x0;
  AliTRDtrackingChamber **tc = &fChamber[0];
  for(Int_t ic = 0; (ic<AliTRDgeometry::kNdets) && (*tc); ic++, tc++){
    for(Int_t itb=0; itb<AliTRDseed::knTimebins; itb++){
      if(!(tb = (*tc)->GetTB(itb))) continue;
      tb->SetReconstructor(rec);
    }
    (*tc)->Build(fGeom, cal, rec->IsHLT());
  }

  Int_t nl;
  for(int il=0; il<AliTRDgeometry::kNlayer; il++){
    fX0[il] = 0.; nl = 0;
    for(int is=0; is<AliTRDgeometry::kNstack; is++){
      Int_t idx = is*AliTRDgeometry::kNlayer + il;
      if(fIndex[idx]<0) continue;
      fX0[il] += GetChamber(fIndex[idx])->GetX();
      nl++;
    }
    if(!nl){
      //printf("Could not estimate radial position  of plane %d in sector %d.\n", ip, fSector);
      continue;
    }
    fX0[il] /= Float_t(nl);
  }
}

//_____________________________________________________________________________
void AliTRDtrackingSector::Clear(const Option_t *opt)
{
// Reset counters and steer chamber clear

  AliTRDtrackingChamber **tc = &fChamber[0];
  for(Int_t ich=0; ich<fN; ich++, tc++){
    (*tc)->Clear(opt);
    delete (*tc); (*tc) = 0x0;   // I would avoid
  }
  memset(fIndex, 1, AliTRDgeometry::kNdets*sizeof(Char_t));
  fN = 0;
}

//_____________________________________________________________________________
AliTRDtrackingChamber* AliTRDtrackingSector::GetChamber(Int_t stack, Int_t layer, Bool_t build)
{
// Return chamber at position (stack, plane) in current
// sector or build a new one if it is not already created

  Int_t ch = stack*AliTRDgeometry::kNlayer + layer;
  if(fIndex[ch] >= 0) return fChamber[Int_t(fIndex[ch])];
  else if(!build) return 0x0;

  // CHAMBER HAS TO BE BUILD
  Int_t rch = ch;do rch--; while(rch>=0 && fIndex[rch]<0);
  fIndex[ch] = rch >=0 ? fIndex[rch]+1 : 0;
  fN++;

  memmove(&fChamber[Int_t(fIndex[ch])+1], &fChamber[Int_t(fIndex[ch])], (AliTRDgeometry::kNdets-fIndex[ch]-1)*sizeof(void*));
  for(Int_t ic = ch+1; ic<AliTRDgeometry::kNdets; ic++) fIndex[ic] += fIndex[ic] >= 0 ? 1 : 0;

  AliTRDtrackingChamber *chmb = fChamber[Int_t(fIndex[ch])] = new AliTRDtrackingChamber();
  chmb->SetDetector(AliTRDgeometry::GetDetector(layer, stack, fSector));
  return chmb;
}

//_____________________________________________________________________________
AliTRDtrackingChamber** AliTRDtrackingSector::GetStack(Int_t stack)
{
// Return chamber at position (stack, plane) in current
// sector or build a new one if it is not already created

  if(stack<0 || stack>=AliTRDgeometry::kNstack) return 0x0;

  Int_t ich, n = 0;
  for(int il=0; il<AliTRDgeometry::kNlayer; il++){
    ich = stack*AliTRDgeometry::kNlayer + il;
    if(fIndex[ich] < 0) fStack[il] = 0x0;
    else{
      fStack[il] = fChamber[Int_t(fIndex[ich])];
      n++;
    }
  }

  return n ? &fStack[0] : 0x0;
}

//_____________________________________________________________________________
void AliTRDtrackingSector::Print(Option_t *)
{
// Dump info about this tracking sector and the tracking chamber within
//

  printf("\tSector %2d\n", fSector);
  for(int il=0; il<AliTRDgeometry::kNlayer; il++){
    for(int is =0; is<AliTRDgeometry::kNstack; is++){
      Int_t ch = is*AliTRDgeometry::kNlayer + il;
      printf("%2d[%2d] ", fIndex[ch], fIndex[ch]>=0 ? fChamber[Int_t(fIndex[ch])]->GetNClusters() : 0);
    }
    printf("\n");
  }

}
<commit_msg>fix crash in TRD reconstruction<commit_after>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/* $Id: AliTRDtrackingSector.cxx 23810 2008-02-08 09:00:27Z hristov $ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  Tracking data container for one sector                                   //
//                                                                           //
//  Authors:                                                                 //
//    Alex Bercuci <A.Bercuci@gsi.de>                                        //
//    Markus Fasel <M.Fasel@gsi.de>                                          //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliTRDcalibDB.h"
#include "AliTRDCommonParam.h"
#include "AliTRDpadPlane.h"
#include "AliTRDtrackingSector.h"
#include "AliTRDtrackingChamber.h"

ClassImp(AliTRDtrackingSector)

//_____________________________________________________________________________
AliTRDtrackingSector::AliTRDtrackingSector()
  :fSector(-1)
  ,fN(0)
  ,fGeom(0x0)
{
  // Default constructor

  memset(fChamber, 0, AliTRDgeometry::kNdets*sizeof(AliTRDtrackingChamber*));
  memset(fIndex, -1, AliTRDgeometry::kNdets*sizeof(Char_t));
  memset(fX0, 0, AliTRDgeometry::kNlayer*sizeof(Float_t));
}

//_____________________________________________________________________________
AliTRDtrackingSector::AliTRDtrackingSector(AliTRDgeometry *geo, Int_t gs)
  :fSector(gs)
  ,fN(0)
  ,fGeom(geo)
{
  //
  // AliTRDtrackingSector Constructor
  //

  memset(fChamber, 0, AliTRDgeometry::kNdets*sizeof(AliTRDtrackingChamber*));
  memset(fIndex, -1, AliTRDgeometry::kNdets*sizeof(Char_t));
  memset(fX0, 0, AliTRDgeometry::kNlayer*sizeof(Float_t));
}

//_____________________________________________________________________________
void AliTRDtrackingSector::Init(const AliTRDReconstructor *rec, const AliTRDCalDet *cal)
{
// 	Steer building of tracking chambers and build tracking sector.
// 	Propagate radial position information (calibration/alignment aware) from chambers to sector level
//

  AliTRDchamberTimeBin *tb = 0x0;
  AliTRDtrackingChamber **tc = &fChamber[0];
  for(Int_t ic = 0; (ic<AliTRDgeometry::kNdets) && (*tc); ic++, tc++){
    for(Int_t itb=0; itb<AliTRDseed::knTimebins; itb++){
      if(!(tb = (*tc)->GetTB(itb))) continue;
      tb->SetReconstructor(rec);
    }
    (*tc)->Build(fGeom, cal, rec->IsHLT());
  }

  Int_t nl;
  for(int il=0; il<AliTRDgeometry::kNlayer; il++){
    fX0[il] = 0.; nl = 0;
    for(int is=0; is<AliTRDgeometry::kNstack; is++){
      Int_t idx = is*AliTRDgeometry::kNlayer + il;
      if(fIndex[idx]<0) continue;
      fX0[il] += GetChamber(fIndex[idx])->GetX();
      nl++;
    }
    if(!nl){
      //printf("Could not estimate radial position  of plane %d in sector %d.\n", ip, fSector);
      continue;
    }
    fX0[il] /= Float_t(nl);
  }
}

//_____________________________________________________________________________
void AliTRDtrackingSector::Clear(const Option_t *opt)
{
// Reset counters and steer chamber clear

  AliTRDtrackingChamber **tc = &fChamber[0];
  for(Int_t ich=0; ich<fN; ich++, tc++){
    (*tc)->Clear(opt);
    delete (*tc); (*tc) = 0x0;   // I would avoid
  }
  memset(fIndex, -1, AliTRDgeometry::kNdets*sizeof(Char_t));
  fN = 0;
}

//_____________________________________________________________________________
AliTRDtrackingChamber* AliTRDtrackingSector::GetChamber(Int_t stack, Int_t layer, Bool_t build)
{
// Return chamber at position (stack, plane) in current
// sector or build a new one if it is not already created

  Int_t ch = stack*AliTRDgeometry::kNlayer + layer;
  if(fIndex[ch] >= 0) return fChamber[Int_t(fIndex[ch])];
  else if(!build) return 0x0;

  // CHAMBER HAS TO BE BUILD
  Int_t rch = ch;do rch--; while(rch>=0 && fIndex[rch]<0);
  fIndex[ch] = rch >=0 ? fIndex[rch]+1 : 0;
  fN++;

  memmove(&fChamber[Int_t(fIndex[ch])+1], &fChamber[Int_t(fIndex[ch])], (AliTRDgeometry::kNdets-fIndex[ch]-1)*sizeof(void*));
  for(Int_t ic = ch+1; ic<AliTRDgeometry::kNdets; ic++) fIndex[ic] += fIndex[ic] >= 0 ? 1 : 0;

  AliTRDtrackingChamber *chmb = fChamber[Int_t(fIndex[ch])] = new AliTRDtrackingChamber();
  chmb->SetDetector(AliTRDgeometry::GetDetector(layer, stack, fSector));
  return chmb;
}

//_____________________________________________________________________________
AliTRDtrackingChamber** AliTRDtrackingSector::GetStack(Int_t stack)
{
// Return chamber at position (stack, plane) in current
// sector or build a new one if it is not already created

  if(stack<0 || stack>=AliTRDgeometry::kNstack) return 0x0;

  Int_t ich, n = 0;
  for(int il=0; il<AliTRDgeometry::kNlayer; il++){
    ich = stack*AliTRDgeometry::kNlayer + il;
    if(fIndex[ich] < 0) fStack[il] = 0x0;
    else{
      fStack[il] = fChamber[Int_t(fIndex[ich])];
      n++;
    }
  }

  return n ? &fStack[0] : 0x0;
}

//_____________________________________________________________________________
void AliTRDtrackingSector::Print(Option_t *)
{
// Dump info about this tracking sector and the tracking chamber within
//

  printf("\tSector %2d\n", fSector);
  for(int il=0; il<AliTRDgeometry::kNlayer; il++){
    for(int is =0; is<AliTRDgeometry::kNstack; is++){
      Int_t ch = is*AliTRDgeometry::kNlayer + il;
      printf("%2d[%2d] ", fIndex[ch], fIndex[ch]>=0 ? fChamber[Int_t(fIndex[ch])]->GetNClusters() : 0);
    }
    printf("\n");
  }

}
<|endoftext|>


<commit_before>
#include <gloperate-qtquick/viewer/QmlEngine.h>

#include <QVariant>
#include <QQmlContext>
#include <QJSValueIterator>

#include <cppexpose/reflection/Property.h>

#include <cppassist/io/FilePath.h>

#include <gloperate/gloperate.h>
#include <gloperate/viewer/ViewerContext.h>
#include <gloperate/scripting/ScriptEnvironment.h>

#include <gloperate-qtquick/controls/TextController.h>
#include <gloperate-qtquick/viewer/RenderItem.h>
#include <gloperate-qtquick/viewer/QmlScriptFunction.h>

namespace gloperate_qtquick
{

QmlEngine::QmlEngine(gloperate::ViewerContext * viewerContext)
: m_viewerContext(viewerContext)
{
    // Register QML types
    qmlRegisterType<RenderItem>    ("gloperate.rendering", 1, 0, "RenderItem");
    qmlRegisterType<TextController>("gloperate.ui",        1, 0, "TextController");

    // Add gloperate qml-libraries
    std::string importPath = gloperate::dataPath() + "/gloperate/qml/GLOperate/Ui";
    addImportPath(QString::fromStdString(importPath));

    // Register global functions and properties
    rootContext()->setContextObject(this);

    // Create global objects
    m_global    = newObject();
    m_gloperate = newObject();
}

QmlEngine::~QmlEngine()
{
}

gloperate::ViewerContext * QmlEngine::viewerContext() const
{
    return m_viewerContext;
}

QString QmlEngine::execute(const QString & code)
{
    return QString::fromStdString(
        m_viewerContext->scriptEnvironment()->execute(code.toStdString()).value<std::string>()
    );
}

cppexpose::Variant QmlEngine::fromScriptValue(const QJSValue & value)
{
    if (value.isBool()) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.isNumber()) {
        return cppexpose::Variant(value.toNumber());
    }

    else if (value.isString()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isRegExp()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isError()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isDate()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isCallable()) {
        // [TODO] This produces a memory leak, since the pointer to the function object will never be deleted.
        //        A solution would be to wrap a ref_ptr into the variant, but since there are also function objects
        //        which are not memory-managed (e.g., a C-function that has been passed to the scripting engine),
        //        it would be hard to determine the right use of function-variants.
        //        The script context could of course manage a list of created functions an delete them on destruction,
        //        but that would not solve the problem of "memory leak" while the program is running.
        QmlScriptFunction * function = new QmlScriptFunction(this, value);
        return cppexpose::Variant::fromValue<cppexpose::AbstractFunction *>(function);
    }

    else if (value.isArray()) {
        cppexpose::VariantArray array;

        QJSValueIterator it(value);
        while (it.next())
        {
            if (it.hasNext()) // Skip last item (length)
            {
                array.push_back(fromScriptValue(it.value()));
            }
        }

        return array;
    }

    else if (value.isObject()) {
        cppexpose::VariantMap obj;

        QJSValueIterator it(value);
        while (it.next())
        {
            obj[it.name().toStdString()] = fromScriptValue(it.value());
        }

        return obj;
    }

    else {
        return cppexpose::Variant();
    }
}

QJSValue QmlEngine::toScriptValue(const cppexpose::Variant & var)
{
    if (var.hasType<char>()) {
        return QJSValue(var.value<char>());
    }

    else if (var.hasType<unsigned char>()) {
        return QJSValue(var.value<unsigned char>());
    }

    else if (var.hasType<short>()) {
        return QJSValue(var.value<short>());
    }

    else if (var.hasType<unsigned short>()) {
        return QJSValue(var.value<unsigned short>());
    }

    else if (var.hasType<int>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned int>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<float>()) {
        return QJSValue(var.value<float>());
    }

    else if (var.hasType<double>()) {
        return QJSValue(var.value<double>());
    }

    else if (var.hasType<char*>()) {
        return QJSValue(var.value<char*>());
    }

    else if (var.hasType<std::string>()) {
        return QJSValue(var.value<std::string>().c_str());
    }

    else if (var.hasType<bool>()) {
        return QJSValue(var.value<bool>());
    }

    else if (var.hasType<cppassist::FilePath>()) {
        return QJSValue(var.value<cppassist::FilePath>().path().c_str());
    }

    else if (var.hasType<cppexpose::VariantArray>()) {
        QJSValue array = newArray();

        cppexpose::VariantArray variantArray = var.value<cppexpose::VariantArray>();
        for (unsigned int i=0; i<variantArray.size(); i++) {
            array.setProperty(i, toScriptValue(variantArray.at(i)));
        }

        return array;
    }

    else if (var.hasType<cppexpose::VariantMap>()) {
        QJSValue obj = newObject();

        cppexpose::VariantMap variantMap = var.value<cppexpose::VariantMap>();
        for (const std::pair<std::string, cppexpose::Variant> & pair : variantMap)
        {
            obj.setProperty(pair.first.c_str(), toScriptValue(pair.second));
        }

        return obj;
    }

    else {
        return QJSValue();
    }
}

cppexpose::Variant QmlEngine::fromQVariant(const QVariant & value)
{
    if (value.type() == QVariant::Bool) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.type() == QVariant::Char || value.type() == QVariant::Int) {
        return cppexpose::Variant(value.toInt());
    }

    else if (value.type() == QVariant::UInt) {
        return cppexpose::Variant(value.toUInt());
    }

    else if (value.type() == QVariant::LongLong) {
        return cppexpose::Variant(value.toLongLong());
    }

    else if (value.type() == QVariant::ULongLong) {
        return cppexpose::Variant(value.toULongLong());
    }

    else if (value.type() == QVariant::Double) {
        return cppexpose::Variant(value.toDouble());
    }

    else if (value.type() == QVariant::StringList)
    {
        cppexpose::VariantArray array;

        QStringList list = value.toStringList();
        for (QStringList::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back( cppexpose::Variant((*it).toStdString()) );
        }

        return array;
    }

    else if (value.type() == QVariant::List)
    {
        cppexpose::VariantArray array;

        QList<QVariant> list = value.toList();
        for (QList<QVariant>::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back(fromQVariant(*it));
        }

        return array;
    }

    else if (value.type() == QVariant::Map)
    {
        cppexpose::VariantMap obj;

        QMap<QString, QVariant> map = value.toMap();
        for (QMap<QString, QVariant>::iterator it = map.begin(); it != map.end(); ++it)
        {
            std::string key = it.key().toStdString();
            obj[key] = fromQVariant(it.value());
        }

        return obj;
    }

    else if (value.type() == QVariant::String || value.canConvert(QVariant::String))
    {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else {
        return cppexpose::Variant();
    }
}

const QJSValue & QmlEngine::global() const
{
    return m_global;
}

void QmlEngine::setGlobal(const QJSValue & obj)
{
    m_global = obj;
}

const QJSValue & QmlEngine::gloperate() const
{
    return m_gloperate;
}

void QmlEngine::setGloperate(const QJSValue & obj)
{
    m_gloperate = obj;
}

} // namespace gloperate_qtquick
<commit_msg>Add DirectValue.h include in QmlEngine.cpp.<commit_after>
#include <gloperate-qtquick/viewer/QmlEngine.h>

#include <QVariant>
#include <QQmlContext>
#include <QJSValueIterator>

#include <cppexpose/reflection/Property.h>
#include <cppexpose/typed/DirectValue.h>

#include <cppassist/io/FilePath.h>

#include <gloperate/gloperate.h>
#include <gloperate/viewer/ViewerContext.h>
#include <gloperate/scripting/ScriptEnvironment.h>

#include <gloperate-qtquick/controls/TextController.h>
#include <gloperate-qtquick/viewer/RenderItem.h>
#include <gloperate-qtquick/viewer/QmlScriptFunction.h>

namespace gloperate_qtquick
{

QmlEngine::QmlEngine(gloperate::ViewerContext * viewerContext)
: m_viewerContext(viewerContext)
{
    // Register QML types
    qmlRegisterType<RenderItem>    ("gloperate.rendering", 1, 0, "RenderItem");
    qmlRegisterType<TextController>("gloperate.ui",        1, 0, "TextController");

    // Add gloperate qml-libraries
    std::string importPath = gloperate::dataPath() + "/gloperate/qml/GLOperate/Ui";
    addImportPath(QString::fromStdString(importPath));

    // Register global functions and properties
    rootContext()->setContextObject(this);

    // Create global objects
    m_global    = newObject();
    m_gloperate = newObject();
}

QmlEngine::~QmlEngine()
{
}

gloperate::ViewerContext * QmlEngine::viewerContext() const
{
    return m_viewerContext;
}

QString QmlEngine::execute(const QString & code)
{
    return QString::fromStdString(
        m_viewerContext->scriptEnvironment()->execute(code.toStdString()).value<std::string>()
    );
}

cppexpose::Variant QmlEngine::fromScriptValue(const QJSValue & value)
{
    if (value.isBool()) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.isNumber()) {
        return cppexpose::Variant(value.toNumber());
    }

    else if (value.isString()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isRegExp()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isError()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isDate()) {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else if (value.isCallable()) {
        // [TODO] This produces a memory leak, since the pointer to the function object will never be deleted.
        //        A solution would be to wrap a ref_ptr into the variant, but since there are also function objects
        //        which are not memory-managed (e.g., a C-function that has been passed to the scripting engine),
        //        it would be hard to determine the right use of function-variants.
        //        The script context could of course manage a list of created functions an delete them on destruction,
        //        but that would not solve the problem of "memory leak" while the program is running.
        QmlScriptFunction * function = new QmlScriptFunction(this, value);
        return cppexpose::Variant::fromValue<cppexpose::AbstractFunction *>(function);
    }

    else if (value.isArray()) {
        cppexpose::VariantArray array;

        QJSValueIterator it(value);
        while (it.next())
        {
            if (it.hasNext()) // Skip last item (length)
            {
                array.push_back(fromScriptValue(it.value()));
            }
        }

        return array;
    }

    else if (value.isObject()) {
        cppexpose::VariantMap obj;

        QJSValueIterator it(value);
        while (it.next())
        {
            obj[it.name().toStdString()] = fromScriptValue(it.value());
        }

        return obj;
    }

    else {
        return cppexpose::Variant();
    }
}

QJSValue QmlEngine::toScriptValue(const cppexpose::Variant & var)
{
    if (var.hasType<char>()) {
        return QJSValue(var.value<char>());
    }

    else if (var.hasType<unsigned char>()) {
        return QJSValue(var.value<unsigned char>());
    }

    else if (var.hasType<short>()) {
        return QJSValue(var.value<short>());
    }

    else if (var.hasType<unsigned short>()) {
        return QJSValue(var.value<unsigned short>());
    }

    else if (var.hasType<int>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned int>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<long long>()) {
        return QJSValue(var.value<int>());
    }

    else if (var.hasType<unsigned long long>()) {
        return QJSValue(var.value<unsigned int>());
    }

    else if (var.hasType<float>()) {
        return QJSValue(var.value<float>());
    }

    else if (var.hasType<double>()) {
        return QJSValue(var.value<double>());
    }

    else if (var.hasType<char*>()) {
        return QJSValue(var.value<char*>());
    }

    else if (var.hasType<std::string>()) {
        return QJSValue(var.value<std::string>().c_str());
    }

    else if (var.hasType<bool>()) {
        return QJSValue(var.value<bool>());
    }

    else if (var.hasType<cppassist::FilePath>()) {
        return QJSValue(var.value<cppassist::FilePath>().path().c_str());
    }

    else if (var.hasType<cppexpose::VariantArray>()) {
        QJSValue array = newArray();

        cppexpose::VariantArray variantArray = var.value<cppexpose::VariantArray>();
        for (unsigned int i=0; i<variantArray.size(); i++) {
            array.setProperty(i, toScriptValue(variantArray.at(i)));
        }

        return array;
    }

    else if (var.hasType<cppexpose::VariantMap>()) {
        QJSValue obj = newObject();

        cppexpose::VariantMap variantMap = var.value<cppexpose::VariantMap>();
        for (const std::pair<std::string, cppexpose::Variant> & pair : variantMap)
        {
            obj.setProperty(pair.first.c_str(), toScriptValue(pair.second));
        }

        return obj;
    }

    else {
        return QJSValue();
    }
}

cppexpose::Variant QmlEngine::fromQVariant(const QVariant & value)
{
    if (value.type() == QVariant::Bool) {
        return cppexpose::Variant(value.toBool());
    }

    else if (value.type() == QVariant::Char || value.type() == QVariant::Int) {
        return cppexpose::Variant(value.toInt());
    }

    else if (value.type() == QVariant::UInt) {
        return cppexpose::Variant(value.toUInt());
    }

    else if (value.type() == QVariant::LongLong) {
        return cppexpose::Variant(value.toLongLong());
    }

    else if (value.type() == QVariant::ULongLong) {
        return cppexpose::Variant(value.toULongLong());
    }

    else if (value.type() == QVariant::Double) {
        return cppexpose::Variant(value.toDouble());
    }

    else if (value.type() == QVariant::StringList)
    {
        cppexpose::VariantArray array;

        QStringList list = value.toStringList();
        for (QStringList::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back( cppexpose::Variant((*it).toStdString()) );
        }

        return array;
    }

    else if (value.type() == QVariant::List)
    {
        cppexpose::VariantArray array;

        QList<QVariant> list = value.toList();
        for (QList<QVariant>::iterator it = list.begin(); it != list.end(); ++it)
        {
            array.push_back(fromQVariant(*it));
        }

        return array;
    }

    else if (value.type() == QVariant::Map)
    {
        cppexpose::VariantMap obj;

        QMap<QString, QVariant> map = value.toMap();
        for (QMap<QString, QVariant>::iterator it = map.begin(); it != map.end(); ++it)
        {
            std::string key = it.key().toStdString();
            obj[key] = fromQVariant(it.value());
        }

        return obj;
    }

    else if (value.type() == QVariant::String || value.canConvert(QVariant::String))
    {
        return cppexpose::Variant(value.toString().toStdString());
    }

    else {
        return cppexpose::Variant();
    }
}

const QJSValue & QmlEngine::global() const
{
    return m_global;
}

void QmlEngine::setGlobal(const QJSValue & obj)
{
    m_global = obj;
}

const QJSValue & QmlEngine::gloperate() const
{
    return m_gloperate;
}

void QmlEngine::setGloperate(const QJSValue & obj)
{
    m_gloperate = obj;
}

} // namespace gloperate_qtquick
<|endoftext|>


<commit_before>/// \file uparser.cc

//#define ENABLE_DEBUG_TRACES
#include "libport/compiler.hh"

#include <cstdlib>
#include <cassert>

#include <sstream>
#include <strstream>
#include <fstream>
#include <algorithm>
#include <string>

#include "uparser.hh"

/*----------.
| UParser.  |
`----------*/

UParser::UParser(UConnection& cn)
  : command_tree_ (0),
    binaryCommand (false),
    connection (cn),
    hasError_(false),
    error_ (),
    hasWarning_(false),
    warning_ (),
    scanner_ (),
    loc_()
{
  // The first column for locations is 1.
  loc_.begin.column = loc_.end.column = 1;
}

int
UParser::parse_ ()
{
  command_tree_ = 0;
  binaryCommand = false;
  hasError_ = false;
  hasWarning_ = false;

  parser_type p(*this);
#ifdef ENABLE_DEBUG_TRACES
  p.set_debug_level(true);
#else
  p.set_debug_level (!!getenv ("YYDEBUG"));
#endif
  ECHO("====================== Parse begin");
  int res = p.parse();
  ECHO("====================== Parse end: " << res);
  return res;
}

int
UParser::process (const std::string& command)
{
  // It has been said Flex scanners cannot work with istrstream.
  std::istrstream mem_buff (command.c_str ());
  std::istream mem_input (mem_buff.rdbuf());
  scanner_.switch_streams(&mem_input, 0);
  ECHO("Parsing string: ==================\n"
       << loc_ << ":\n" << command
       << "\n==================================");
  return parse_ ();
}

ast::Ast*
UParser::command_tree_get ()
{
  if (hasError ())
    return 0;
  return command_tree_;
}

const ast::Ast*
UParser::command_tree_get () const
{
  if (hasError ())
    return 0;
  return command_tree_;
}

void
UParser::command_tree_set (ast::Ast* ast)
{
  command_tree_ = ast;
}

int
UParser::process_file (const std::string& fn)
{
  // A location pointing to it.
  location_type loc;
  loc.initialize (new libport::Symbol(fn));
  // The convention for the first column changed: make sure the first
  // column is column 1.
  loc.begin.column = loc.end.column = 1;

  // Exchange with the current location so that we can restore it
  // afterwards (when reading the input flow, we want to be able to
  // restore the cursor after having handled a load command).
  std::swap(loc, loc_);
  std::ifstream f (fn.c_str());
  scanner_.switch_streams(&f, 0);
  ECHO("Parsing file: " << fn);
  int res = parse_();
  std::swap(loc, loc_);
  return res;
}

namespace
{
  /// Helper to format error and warning messages.
  std::string errorFormat(const yy::parser::location_type& l,
                          const std::string& msg)
  {
    std::ostringstream o;
    o << "!!! " << l << ": " << msg << '\n' << std::ends;
    return o.str();
  }
}

void
UParser::error (const yy::parser::location_type& l, const std::string& msg)
{
  hasError_ = true;
  error_ = errorFormat(l, msg);
}

void
UParser::warn (const yy::parser::location_type& l, const std::string& msg)
{
  hasWarning_ = true;
  warning_ = errorFormat(l, msg);
}

bool
UParser::hasError () const
{
  return hasError_;
}

std::string
UParser::error_get () const
{
  // precondition
  assert(hasError());

  return error_;
}

bool
UParser::hasWarning () const
{
  return hasWarning_;
}

std::string
UParser::warning_get () const
{
  // precondition
  assert(hasWarning());
  return warning_;
}
<commit_msg>Space changes.<commit_after>/// \file uparser.cc

//#define ENABLE_DEBUG_TRACES
#include "libport/compiler.hh"

#include <cstdlib>
#include <cassert>

#include <sstream>
#include <strstream>
#include <fstream>
#include <algorithm>
#include <string>

#include "uparser.hh"

/*----------.
| UParser.  |
`----------*/

UParser::UParser(UConnection& cn)
  : command_tree_ (0),
    binaryCommand (false),
    connection (cn),
    hasError_(false),
    error_ (),
    hasWarning_(false),
    warning_ (),
    scanner_ (),
    loc_()
{
  // The first column for locations is 1.
  loc_.begin.column = loc_.end.column = 1;
}

int
UParser::parse_ ()
{
  command_tree_ = 0;
  binaryCommand = false;
  hasError_ = false;
  hasWarning_ = false;

  parser_type p(*this);
#ifdef ENABLE_DEBUG_TRACES
  p.set_debug_level(true);
#else
  p.set_debug_level (!!getenv ("YYDEBUG"));
#endif
  ECHO("====================== Parse begin");
  int res = p.parse();
  ECHO("====================== Parse end: " << res);
  return res;
}

int
UParser::process (const std::string& command)
{
  // It has been said Flex scanners cannot work with istrstream.
  std::istrstream mem_buff (command.c_str ());
  std::istream mem_input (mem_buff.rdbuf());
  scanner_.switch_streams(&mem_input, 0);
  ECHO("Parsing string: ==================\n"
       << loc_ << ":\n" << command
       << "\n==================================");
  return parse_ ();
}

ast::Ast*
UParser::command_tree_get ()
{
  if (hasError ())
    return 0;
  return command_tree_;
}

const ast::Ast*
UParser::command_tree_get () const
{
  if (hasError ())
    return 0;
  return command_tree_;
}

void
UParser::command_tree_set (ast::Ast* ast)
{
  command_tree_ = ast;
}

int
UParser::process_file (const std::string& fn)
{
  // A location pointing to it.
  location_type loc;
  loc.initialize (new libport::Symbol(fn));
  // The convention for the first column changed: make sure the first
  // column is column 1.
  loc.begin.column = loc.end.column = 1;

  // Exchange with the current location so that we can restore it
  // afterwards (when reading the input flow, we want to be able to
  // restore the cursor after having handled a load command).
  std::swap(loc, loc_);
  std::ifstream f (fn.c_str());
  scanner_.switch_streams(&f, 0);
  ECHO("Parsing file: " << fn);
  int res = parse_();
  std::swap(loc, loc_);
  return res;
}

namespace
{
  /// Helper to format error and warning messages.
  std::string errorFormat(const yy::parser::location_type& l,
			  const std::string& msg)
  {
    std::ostringstream o;
    o << "!!! " << l << ": " << msg << '\n' << std::ends;
    return o.str();
  }
}

void
UParser::error (const yy::parser::location_type& l, const std::string& msg)
{
  hasError_ = true;
  error_ = errorFormat(l, msg);
}

void
UParser::warn (const yy::parser::location_type& l, const std::string& msg)
{
  hasWarning_ = true;
  warning_ = errorFormat(l, msg);
}

bool
UParser::hasError () const
{
  return hasError_;
}

std::string
UParser::error_get () const
{
  // precondition
  assert(hasError());

  return error_;
}

bool
UParser::hasWarning () const
{
  return hasWarning_;
}

std::string
UParser::warning_get () const
{
  // precondition
  assert(hasWarning());
  return warning_;
}
<|endoftext|>


<commit_before>#include "SubDocPropValueRenderer.h"
#include <rapidjson/document.h>
#include <glog/logging.h>

namespace sf1r
{
void SubDocPropValueRenderer::renderSubDocPropValue(
    const std::string& propName,
    const std::string& origText,
    izenelib::driver::Value& resourceValue)
{
    if (origText.empty())
        return;
    rapidjson::Document doc;
    if (doc.Parse<0>(origText.c_str()).HasParseError());
    {
        return;
    }
    const rapidjson::Value& subDocs = doc;
    assert(subDocs.IsArray());
    for (rapidjson::Value::ConstValueIterator vit = subDocs.Begin();
            vit != subDocs.End(); vit++)
    {
        izenelib::driver::Value& subDoc = resourceValue();
        for (rapidjson::Value::ConstMemberIterator mit = vit->MemberBegin();
             mit != vit->MemberEnd(); mit++)
        {
            subDoc[mit->name.GetString()]=mit->value.GetString();
        }
    }
}
}
<commit_msg>rapidjson always have json parse error given subdoc property using JsonReader instead<commit_after>#include "SubDocPropValueRenderer.h"
#include <rapidjson/document.h>
#include <glog/logging.h>
#include <util/driver/readers/JsonReader.h>

namespace sf1r
{
void SubDocPropValueRenderer::renderSubDocPropValue(
    const std::string& propName,
    const std::string& origText,
    izenelib::driver::Value& resourceValue)
{
    if (origText.empty())
        return;
    izenelib::driver::JsonReader reader;
    reader.read(origText, resourceValue);
    /*
    rapidjson::Document doc;
    if (doc.Parse<0>(origText.c_str()).HasParseError())
    {
        //return;
    }
    const rapidjson::Value& subDocs = doc;
    assert(subDocs.IsArray());
    for (rapidjson::Value::ConstValueIterator vit = subDocs.Begin();
            vit != subDocs.End(); vit++)
    {
        izenelib::driver::Value& subDoc = resourceValue();
        for (rapidjson::Value::ConstMemberIterator mit = vit->MemberBegin();
             mit != vit->MemberEnd(); mit++)
        {
            subDoc[mit->name.GetString()]=mit->value.GetString();
        }
    }*/
}
}
<|endoftext|>


<commit_before><commit_msg>Fix pool allocator memory persistence across allocs<commit_after><|endoftext|>


<commit_before>//
// Copyright (c) 2012 Kim Walisch, <kim.walisch@gmail.com>.
// All rights reserved.
//
// This file is part of primesieve.
// Homepage: http://primesieve.googlecode.com
//
// 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 "EratMedium.h"
#include "SieveOfEratosthenes.h"
#include "SieveOfEratosthenes-inline.h"
#include "WheelFactorization.h"
#include "config.h"

#include <stdint.h>
#include <stdexcept>
#include <algorithm>
#include <list>

namespace soe {

EratMedium::EratMedium(const SieveOfEratosthenes& soe) :
  Modulo210Wheel_t(soe), buckets_(1, Bucket())
{
  // assert multipleIndex < 2^23 in crossOff()
  static_assert(config::FACTOR_ERATMEDIUM <= 6, "config::FACTOR_ERATMEDIUM must not be > 6");
  if (soe.getSieveSize() > (1u << 22))
    throw std::overflow_error("EratMedium: sieveSize must be <= 2^22, 4096 kilobytes.");
  uint_t sqrtStop = soe.getSqrtStop();
  uint_t max      = soe.getSieveSize() * config::FACTOR_ERATMEDIUM;
  limit_          = std::min(sqrtStop, max);
}

/// Add a new sieving prime
/// @see addSievingPrime() in WheelFactorization.h
///
void EratMedium::storeSievingPrime(uint_t prime, uint_t multipleIndex, uint_t wheelIndex)
{
  if (!buckets_.back().store(prime, multipleIndex, wheelIndex))
    buckets_.push_back(Bucket());
}

/// This is an implementation of the segmented sieve of Eratosthenes
/// with wheel factorization optimized for medium sieving primes that
/// have a few multiples per segment. EratMedium uses a modulo 210
/// wheel that skips multiples of 2, 3, 5 and 7.
/// @see crossOffMultiples() in SieveOfEratosthenes.cpp
///
void EratMedium::crossOff(uint8_t* sieve, uint_t sieveSize)
{
  for (BucketList_t::iterator bucket = buckets_.begin(); bucket != buckets_.end(); ++bucket) {
    WheelPrime* wPrime = bucket->begin();
    WheelPrime* end    = bucket->end();
    // 2 sieving primes are processed per loop iteration to break the
    // dependency chain and reduce pipeline stalls
    for (; wPrime + 2 <= end; wPrime += 2) {
      uint_t multipleIndex0 = wPrime[0].getMultipleIndex();
      uint_t wheelIndex0    = wPrime[0].getWheelIndex();
      uint_t sievingPrime0  = wPrime[0].getSievingPrime();
      uint_t multipleIndex1 = wPrime[1].getMultipleIndex();
      uint_t wheelIndex1    = wPrime[1].getWheelIndex();
      uint_t sievingPrime1  = wPrime[1].getSievingPrime();
      // cross-off the multiples (unset bits) of sievingPrime(0|1)
      // @see unsetBit() in WheelFactorization.h
      for (;;) {
         if (multipleIndex0 < sieveSize) unsetBit(sieve, sievingPrime0, &multipleIndex0, &wheelIndex0); else break;
         if (multipleIndex1 < sieveSize) unsetBit(sieve, sievingPrime1, &multipleIndex1, &wheelIndex1); else break;
      }
      while (multipleIndex0 < sieveSize) unsetBit(sieve, sievingPrime0, &multipleIndex0, &wheelIndex0);
      while (multipleIndex1 < sieveSize) unsetBit(sieve, sievingPrime1, &multipleIndex1, &wheelIndex1);
      multipleIndex0 -= sieveSize;
      multipleIndex1 -= sieveSize;
      wPrime[0].set(multipleIndex0, wheelIndex0);
      wPrime[1].set(multipleIndex1, wheelIndex1);
    }
    if (wPrime != end) {
      uint_t multipleIndex = wPrime->getMultipleIndex();
      uint_t wheelIndex    = wPrime->getWheelIndex();
      uint_t sievingPrime  = wPrime->getSievingPrime();
      while (multipleIndex < sieveSize)
        unsetBit(sieve, sievingPrime, &multipleIndex, &wheelIndex);
      multipleIndex -= sieveSize;
      wPrime->set(multipleIndex, wheelIndex);
    }
  }
}

} // namespace soe
<commit_msg>improved code readability<commit_after>//
// Copyright (c) 2012 Kim Walisch, <kim.walisch@gmail.com>.
// All rights reserved.
//
// This file is part of primesieve.
// Homepage: http://primesieve.googlecode.com
//
// 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 "EratMedium.h"
#include "SieveOfEratosthenes.h"
#include "SieveOfEratosthenes-inline.h"
#include "WheelFactorization.h"
#include "config.h"

#include <stdint.h>
#include <stdexcept>
#include <algorithm>
#include <list>

namespace soe {

EratMedium::EratMedium(const SieveOfEratosthenes& soe) :
  Modulo210Wheel_t(soe), buckets_(1, Bucket())
{
  // assert multipleIndex < 2^23 in crossOff()
  static_assert(config::FACTOR_ERATMEDIUM <= 6, "config::FACTOR_ERATMEDIUM must not be > 6");
  if (soe.getSieveSize() > (1u << 22))
    throw std::overflow_error("EratMedium: sieveSize must be <= 2^22, 4096 kilobytes.");
  uint_t max = soe.getSieveSize() * config::FACTOR_ERATMEDIUM;
  limit_     = std::min(soe.getSqrtStop(), max);
}

/// Add a new sieving prime
/// @see addSievingPrime() in WheelFactorization.h
///
void EratMedium::storeSievingPrime(uint_t prime, uint_t multipleIndex, uint_t wheelIndex)
{
  if (!buckets_.back().store(prime, multipleIndex, wheelIndex))
    buckets_.push_back(Bucket());
}

/// This is an implementation of the segmented sieve of Eratosthenes
/// with wheel factorization optimized for medium sieving primes that
/// have a few multiples per segment. EratMedium uses a modulo 210
/// wheel that skips multiples of 2, 3, 5 and 7.
/// @see crossOffMultiples() in SieveOfEratosthenes.cpp
///
void EratMedium::crossOff(uint8_t* sieve, uint_t sieveSize)
{
  for (BucketList_t::iterator bucket = buckets_.begin(); bucket != buckets_.end(); ++bucket) {
    WheelPrime* wPrime = bucket->begin();
    WheelPrime* end    = bucket->end();
    // 2 sieving primes are processed per loop iteration to break the
    // dependency chain and reduce pipeline stalls
    for (; wPrime + 2 <= end; wPrime += 2) {
      uint_t multipleIndex0 = wPrime[0].getMultipleIndex();
      uint_t wheelIndex0    = wPrime[0].getWheelIndex();
      uint_t sievingPrime0  = wPrime[0].getSievingPrime();
      uint_t multipleIndex1 = wPrime[1].getMultipleIndex();
      uint_t wheelIndex1    = wPrime[1].getWheelIndex();
      uint_t sievingPrime1  = wPrime[1].getSievingPrime();
      // cross-off the multiples (unset bits) of sievingPrime(0|1)
      // @see unsetBit() in WheelFactorization.h
      for (;;) {
         if (multipleIndex0 < sieveSize) unsetBit(sieve, sievingPrime0, &multipleIndex0, &wheelIndex0); else break;
         if (multipleIndex1 < sieveSize) unsetBit(sieve, sievingPrime1, &multipleIndex1, &wheelIndex1); else break;
      }
      while (multipleIndex0 < sieveSize) unsetBit(sieve, sievingPrime0, &multipleIndex0, &wheelIndex0);
      while (multipleIndex1 < sieveSize) unsetBit(sieve, sievingPrime1, &multipleIndex1, &wheelIndex1);
      multipleIndex0 -= sieveSize;
      multipleIndex1 -= sieveSize;
      wPrime[0].set(multipleIndex0, wheelIndex0);
      wPrime[1].set(multipleIndex1, wheelIndex1);
    }
    if (wPrime != end) {
      uint_t multipleIndex = wPrime->getMultipleIndex();
      uint_t wheelIndex    = wPrime->getWheelIndex();
      uint_t sievingPrime  = wPrime->getSievingPrime();
      while (multipleIndex < sieveSize)
        unsetBit(sieve, sievingPrime, &multipleIndex, &wheelIndex);
      multipleIndex -= sieveSize;
      wPrime->set(multipleIndex, wheelIndex);
    }
  }
}

} // namespace soe
<|endoftext|>


<commit_before>#include "plugin/Plugin.hpp"
#include "plugin/Model.hpp"

namespace rack {
namespace plugin {

Plugin::~Plugin() {
	for (Model *model : models) {
		delete model;
	}
}

void Plugin::addModel(Model *model) {
	assert(!model->plugin);
	model->plugin = this;
	models.push_back(model);
}

Model *Plugin::getModel(std::string slug) {
	for (Model *model : models) {
		if (model->slug == slug) {
			return model;
		}
	}
	return NULL;
}

void Plugin::fromJson(json_t *rootJ) {
	json_t *slugJ = json_object_get(rootJ, "slug");
	if (slugJ)
		slug = json_string_value(slugJ);

	json_t *versionJ = json_object_get(rootJ, "version");
	if (versionJ)
		version = json_string_value(versionJ);

	json_t *nameJ = json_object_get(rootJ, "name");
	if (nameJ)
		name = json_string_value(nameJ);

	json_t *authorJ = json_object_get(rootJ, "author");
	if (authorJ)
		author = json_string_value(authorJ);

	json_t *licenseJ = json_object_get(rootJ, "license");
	if (licenseJ)
		license = json_string_value(licenseJ);

	json_t *authorEmailJ = json_object_get(rootJ, "authorEmail");
	if (authorEmailJ)
		authorEmail = json_string_value(authorEmailJ);

	json_t *pluginUrlJ = json_object_get(rootJ, "pluginUrl");
	if (pluginUrlJ)
		pluginUrl = json_string_value(pluginUrlJ);

	json_t *authorUrlJ = json_object_get(rootJ, "authorUrl");
	if (authorUrlJ)
		authorUrl = json_string_value(authorUrlJ);

	json_t *manualUrlJ = json_object_get(rootJ, "manualUrl");
	if (manualUrlJ)
		manualUrl = json_string_value(manualUrlJ);

	json_t *sourceUrlJ = json_object_get(rootJ, "sourceUrl");
	if (sourceUrlJ)
		sourceUrl = json_string_value(sourceUrlJ);

	json_t *donateUrlJ = json_object_get(rootJ, "donateUrl");
	if (donateUrlJ)
		donateUrl = json_string_value(donateUrlJ);

	json_t *modulesJ = json_object_get(rootJ, "modules");
	if (modulesJ) {
		const char *slug;
		json_t *moduleJ;
		json_object_foreach(modulesJ, slug, moduleJ) {
			Model *model = getModel(slug);
			if (!model) {
				WARN("plugin.json contains module \"%s\" but it is not defined in the plugin", slug);
				continue;
			}

			model->fromJson(moduleJ);
		}
	}
}

} // namespace plugin
} // namespace rack
<commit_msg>Make module property in manifest an array instead of object<commit_after>#include "plugin/Plugin.hpp"
#include "plugin/Model.hpp"

namespace rack {
namespace plugin {

Plugin::~Plugin() {
	for (Model *model : models) {
		delete model;
	}
}

void Plugin::addModel(Model *model) {
	assert(!model->plugin);
	model->plugin = this;
	models.push_back(model);
}

Model *Plugin::getModel(std::string slug) {
	for (Model *model : models) {
		if (model->slug == slug) {
			return model;
		}
	}
	return NULL;
}

void Plugin::fromJson(json_t *rootJ) {
	json_t *slugJ = json_object_get(rootJ, "slug");
	if (slugJ)
		slug = json_string_value(slugJ);

	json_t *versionJ = json_object_get(rootJ, "version");
	if (versionJ)
		version = json_string_value(versionJ);

	json_t *nameJ = json_object_get(rootJ, "name");
	if (nameJ)
		name = json_string_value(nameJ);

	json_t *authorJ = json_object_get(rootJ, "author");
	if (authorJ)
		author = json_string_value(authorJ);

	json_t *licenseJ = json_object_get(rootJ, "license");
	if (licenseJ)
		license = json_string_value(licenseJ);

	json_t *authorEmailJ = json_object_get(rootJ, "authorEmail");
	if (authorEmailJ)
		authorEmail = json_string_value(authorEmailJ);

	json_t *pluginUrlJ = json_object_get(rootJ, "pluginUrl");
	if (pluginUrlJ)
		pluginUrl = json_string_value(pluginUrlJ);

	json_t *authorUrlJ = json_object_get(rootJ, "authorUrl");
	if (authorUrlJ)
		authorUrl = json_string_value(authorUrlJ);

	json_t *manualUrlJ = json_object_get(rootJ, "manualUrl");
	if (manualUrlJ)
		manualUrl = json_string_value(manualUrlJ);

	json_t *sourceUrlJ = json_object_get(rootJ, "sourceUrl");
	if (sourceUrlJ)
		sourceUrl = json_string_value(sourceUrlJ);

	json_t *donateUrlJ = json_object_get(rootJ, "donateUrl");
	if (donateUrlJ)
		donateUrl = json_string_value(donateUrlJ);

	json_t *modulesJ = json_object_get(rootJ, "modules");
	if (modulesJ) {
		size_t moduleId;
		json_t *moduleJ;
		json_array_foreach(modulesJ, moduleId, moduleJ) {
			json_t *slugJ = json_object_get(rootJ, "slug");
			if (!slugJ)
				continue;
			std::string slug = json_string_value(slugJ);

			Model *model = getModel(slug);
			if (!model) {
				WARN("plugin.json contains module \"%s\" but it is not defined in the plugin", slug);
				continue;
			}

			model->fromJson(moduleJ);
		}
	}
}

} // namespace plugin
} // namespace rack
<|endoftext|>


<commit_before>#include "dreal/solver/context.h"

#include <cmath>
#include <ostream>
#include <set>
#include <sstream>
#include <unordered_set>

#include "dreal/solver/assertion_filter.h"
#include "dreal/solver/sat_solver.h"
#include "dreal/solver/theory_solver.h"
#include "dreal/util/cnfizer.h"
#include "dreal/util/exception.h"
#include "dreal/util/logging.h"
#include "dreal/util/predicate_abstractor.h"
#include "dreal/util/scoped_vector.h"

using std::experimental::optional;
using std::isfinite;
using std::move;
using std::ostringstream;
using std::set;
using std::stod;
using std::string;
using std::unordered_set;
using std::vector;

namespace dreal {

// The actual implementation.
class Context::Impl {
 public:
  Impl();
  explicit Impl(Config config);
  void Assert(const Formula& f);
  std::experimental::optional<Box> CheckSat();
  void DeclareVariable(const Variable& v);
  void DeclareVariable(const Variable& v, const Expression& lb,
                       const Expression& ub);
  void Minimize(const Expression& f);
  void Pop();
  void Push();
  void SetInfo(const std::string& key, const std::string& val);
  void SetInterval(const Variable& v, double lb, double ub);
  void SetLogic(const Logic& logic);
  void SetOption(const std::string& key, const std::string& val);
  const Variable& lookup_variable(const std::string& name);
  const Config& config() const { return config_; }
  Config& mutable_config() { return config_; }

 private:
  Box& box() { return boxes_.last(); }

  Config config_;
  std::experimental::optional<Logic> logic_{};
  std::unordered_map<std::string, Variable> name_to_var_map_;
  std::unordered_map<std::string, std::string> info_;
  std::unordered_map<std::string, std::string> option_;

  ScopedVector<Box> boxes_;
  ScopedVector<Formula> stack_;
  PredicateAbstractor predicate_abstractor_;
  Cnfizer cnfizer_;
  SatSolver sat_solver_;
};

Context::Impl::Impl() : sat_solver_{&cnfizer_, &predicate_abstractor_} {
  boxes_.push_back(Box{});
}

Context::Impl::Impl(Config config)
    : config_{move(config)}, sat_solver_{&cnfizer_, &predicate_abstractor_} {
  boxes_.push_back(Box{});
}

void Context::Impl::Assert(const Formula& f) {
  if (FilterAssertion(f, &box())) {
    DREAL_LOG_DEBUG("Context::Assert: {} is not added.", f);
    DREAL_LOG_DEBUG("Box=\n{}", box());
    return;
  }

  // Predicate abstract & CNFize.
  const vector<Formula> clauses{
      cnfizer_.Convert(predicate_abstractor_.Convert(f))};
  for (const Formula& f_i : clauses) {
    DREAL_LOG_DEBUG("Context::Assert: {} is added.", f_i);
    stack_.push_back(f_i);
  }
}

optional<Box> Context::Impl::CheckSat() {
  DREAL_LOG_DEBUG("Context::CheckSat()");
  DREAL_LOG_TRACE("Context::CheckSat: Box =\n{}", box());
  if (box().empty()) {
    return {};
  }
  // If false ∈ stack_, it's UNSAT.
  for (const auto& f : stack_.get_vector()) {
    if (is_false(f)) {
      return {};
    }
  }
  // If {} = stack_ ∨ {true} = stack_, it's trivially SAT.
  if (stack_.empty() || (stack_.size() == 1 && is_true(stack_.first()))) {
    return box();
  }

  sat_solver_.AddClauses(stack_.get_vector());
  TheorySolver theory_solver{config_, box()};
  while (true) {
    if (sat_solver_.CheckSat()) {
      // SAT from SATSolver.
      DREAL_LOG_DEBUG("Context::CheckSat() - Sat Check = SAT");
      if (theory_solver.CheckSat(sat_solver_.model())) {
        // SAT from TheorySolver.
        DREAL_LOG_DEBUG("Context::CheckSat() - Theroy Check = delta-SAT");
        const Box model{theory_solver.GetModel()};
        return model;
      } else {
        // UNSAT from TheorySolver.
        DREAL_LOG_DEBUG("Context::CheckSat() - Theroy Check = UNSAT");
        const unordered_set<Formula, hash_value<Formula>> explanation{
            theory_solver.GetExplanation()};
        if (explanation.empty()) {
          return {};
        } else {
          DREAL_LOG_DEBUG(
              "Context::CheckSat() - size of explanation = {} - stack "
              "size = {}",
              explanation.size(), stack_.get_vector().size());
          sat_solver_.AddLearnedClause(explanation);
        }
      }
    } else {
      // UNSAT from SATSolver. Escape the loop.
      DREAL_LOG_DEBUG("Context::CheckSat() - Sat Check = UNSAT");
      return {};
    }
  }
}

void Context::Impl::DeclareVariable(const Variable& v) {
  DREAL_LOG_DEBUG("Context::DeclareVariable({})", v);
  name_to_var_map_.emplace(v.get_name(), v);
  box().Add(v);
}

void Context::Impl::DeclareVariable(const Variable& v, const Expression& lb,
                                    const Expression& ub) {
  DeclareVariable(v);
  SetInterval(v, lb.Evaluate(), ub.Evaluate());
}

void Context::Impl::Minimize(const Expression& f) {
  DREAL_LOG_DEBUG("Context::Minimize: {} is called.", f);

  // Given e = f(x) and the current constraints ϕᵢ which
  // involves x. it constructs a universally quantified formula ψ:
  //
  //    ψ = ∀y. (⋀ⱼ ϕᵢ(y)) → f(x) ≤ f(y).
  //

  // To construct ϕᵢ(y), we need to traverse both `box()` and
  // `stack_` because some of the asserted formulas are translated
  // and applied into `box()`.
  set<Formula> phi_set;
  ExpressionSubstitution subst;  // Maps xᵢ ↦ yᵢ to build f(y₁, ..., yₙ).
  Variables quantified_variables;  // {y₁, ... yₙ}
  const Variables x_vars{f.GetVariables()};
  for (const Variable& x_i : x_vars) {
    // We add postfix '_' to name y_i
    const Variable y_i{x_i.get_name() + "_", x_i.get_type()};
    quantified_variables.insert(y_i);
    subst.emplace(x_i, y_i);
    // If `box()[x_i]` has a finite bound, let's add that information in phi_set
    // as a constraint on y_i.
    const Box::Interval& bound_on_x_i{box()[x_i]};
    const double lb_x_i{bound_on_x_i.lb()};
    const double ub_x_i{bound_on_x_i.ub()};
    if (isfinite(lb_x_i)) {
      phi_set.insert(lb_x_i <= y_i);
    }
    if (isfinite(ub_x_i)) {
      phi_set.insert(y_i <= ub_x_i);
    }
  }
  for (const Formula& constraint : stack_) {
    if (!intersect(x_vars, constraint.GetFreeVariables()).empty()) {
      // Case : xᵢ ∈ vars(constraint)
      // We need to collect constraint[xᵢ ↦ yᵢ].
      phi_set.insert(constraint.Substitute(subst));
    }
  }
  const Formula phi{make_conjunction(phi_set)};  // ⋀ⱼ ϕ(y)
  const Formula psi{
      forall(quantified_variables, imply(phi, f <= f.Substitute(subst)))};
  return Assert(psi);
}

void Context::Impl::Pop() {
  DREAL_LOG_DEBUG("Context::Pop()");
  stack_.pop();
  boxes_.pop();
  sat_solver_.Pop();
  // TODO(soonho): Pop cnfizer/predicate_abstractor_.
}

void Context::Impl::Push() {
  DREAL_LOG_DEBUG("Context::Push()");
  sat_solver_.Push();
  boxes_.push();
  boxes_.push_back(boxes_.last());
  stack_.push();
  // TODO(soonho): Push cnfizer/predicate_abstractor_.
}

void Context::Impl::SetInfo(const string& key, const string& val) {
  DREAL_LOG_DEBUG("Context::SetInfo({} ↦ {})", key, val);
  info_[key] = val;
  if (key == ":precision") {
    config_.mutable_precision().set_from_file(stod(val));
  }
}

void Context::Impl::SetInterval(const Variable& v, const double lb,
                                const double ub) {
  DREAL_LOG_DEBUG("Context::SetInterval({} = [{}, {}])", v, lb, ub);
  box()[v] = Box::Interval{lb, ub};
}

void Context::Impl::SetLogic(const Logic& logic) {
  DREAL_LOG_DEBUG("Context::SetLogic({})", logic);
  logic_ = logic;
}

void Context::Impl::SetOption(const string& key, const string& val) {
  DREAL_LOG_DEBUG("Context::SetOption({} ↦ {})", key, val);
  option_[key] = val;
  if (key == ":polytope") {
    if (val == "true") {
      config_.mutable_use_polytope().set_from_file(true);
    } else if (val == "false") {
      config_.mutable_use_polytope().set_from_file(false);
    } else {
      throw DREAL_RUNTIME_ERROR("Fail to interpret the option: " + key + " = " +
                                val);
    }
  }
  if (key == ":forall-polytope") {
    if (val == "true") {
      config_.mutable_use_polytope_in_forall().set_from_file(true);
    } else if (val == "false") {
      config_.mutable_use_polytope_in_forall().set_from_file(false);
    } else {
      throw DREAL_RUNTIME_ERROR("Fail to interpret the option: " + key + " = " +
                                val);
    }
  }
}

const Variable& Context::Impl::lookup_variable(const string& name) {
  const auto it = name_to_var_map_.find(name);
  if (it == name_to_var_map_.cend()) {
    throw DREAL_RUNTIME_ERROR(name + " is not found in the context.");
  }
  return it->second;
}

Context::Context() : impl_{new Impl{}} {}

Context::Context(Config config) : impl_{new Impl{move(config)}} {}

void Context::Assert(const Formula& f) { impl_->Assert(f); }

optional<Box> Context::CheckSat() { return impl_->CheckSat(); }

void Context::DeclareVariable(const Variable& v) { impl_->DeclareVariable(v); }

void Context::DeclareVariable(const Variable& v, const Expression& lb,
                              const Expression& ub) {
  impl_->DeclareVariable(v, lb, ub);
}

void Context::Exit() { DREAL_LOG_DEBUG("Context::Exit()"); }

void Context::Minimize(const Expression& f) { impl_->Minimize(f); }

void Context::Maximize(const Expression& f) { impl_->Minimize(-f); }

void Context::Pop(int n) {
  DREAL_LOG_DEBUG("Context::Pop({})", n);
  if (n <= 0) {
    ostringstream oss;
    oss << "Context::Pop(n) called with n = " << n << " which is not positive.";
    throw DREAL_RUNTIME_ERROR(oss.str());
  }
  while (n-- > 0) {
    impl_->Pop();
  }
}

void Context::Push(int n) {
  DREAL_LOG_DEBUG("Context::Push({})", n);
  if (n <= 0) {
    ostringstream oss;
    oss << "Context::Push(n) called with n = " << n
        << " which is not positive.";
    throw DREAL_RUNTIME_ERROR(oss.str());
  }
  while (n-- > 0) {
    impl_->Push();
  }
}

void Context::SetInfo(const string& key, const string& val) {
  impl_->SetInfo(key, val);
}

void Context::SetInterval(const Variable& v, const double lb, const double ub) {
  impl_->SetInterval(v, lb, ub);
}

void Context::SetLogic(const Logic& logic) { impl_->SetLogic(logic); }

void Context::SetOption(const string& key, const string& val) {
  impl_->SetOption(key, val);
}

const Variable& Context::lookup_variable(const string& name) {
  return impl_->lookup_variable(name);
}

const Config& Context::config() const { return impl_->config(); }
Config& Context::mutable_config() { return impl_->mutable_config(); }

string Context::version() { return DREAL_VERSION_STRING; }

}  // namespace dreal
<commit_msg>feat(solver/context.cc): Optimize Minimize function<commit_after>#include "dreal/solver/context.h"

#include <cmath>
#include <ostream>
#include <set>
#include <sstream>
#include <unordered_set>

#include "dreal/solver/assertion_filter.h"
#include "dreal/solver/sat_solver.h"
#include "dreal/solver/theory_solver.h"
#include "dreal/util/cnfizer.h"
#include "dreal/util/exception.h"
#include "dreal/util/logging.h"
#include "dreal/util/predicate_abstractor.h"
#include "dreal/util/scoped_vector.h"

using std::experimental::optional;
using std::isfinite;
using std::move;
using std::ostringstream;
using std::set;
using std::stod;
using std::string;
using std::unordered_set;
using std::vector;

namespace dreal {

// The actual implementation.
class Context::Impl {
 public:
  Impl();
  explicit Impl(Config config);
  void Assert(const Formula& f);
  std::experimental::optional<Box> CheckSat();
  void DeclareVariable(const Variable& v);
  void DeclareVariable(const Variable& v, const Expression& lb,
                       const Expression& ub);
  void Minimize(const Expression& f);
  void Pop();
  void Push();
  void SetInfo(const std::string& key, const std::string& val);
  void SetInterval(const Variable& v, double lb, double ub);
  void SetLogic(const Logic& logic);
  void SetOption(const std::string& key, const std::string& val);
  const Variable& lookup_variable(const std::string& name);
  const Config& config() const { return config_; }
  Config& mutable_config() { return config_; }

 private:
  Box& box() { return boxes_.last(); }

  Config config_;
  std::experimental::optional<Logic> logic_{};
  std::unordered_map<std::string, Variable> name_to_var_map_;
  std::unordered_map<std::string, std::string> info_;
  std::unordered_map<std::string, std::string> option_;

  ScopedVector<Box> boxes_;
  ScopedVector<Formula> stack_;
  PredicateAbstractor predicate_abstractor_;
  Cnfizer cnfizer_;
  SatSolver sat_solver_;
};

Context::Impl::Impl() : sat_solver_{&cnfizer_, &predicate_abstractor_} {
  boxes_.push_back(Box{});
}

Context::Impl::Impl(Config config)
    : config_{move(config)}, sat_solver_{&cnfizer_, &predicate_abstractor_} {
  boxes_.push_back(Box{});
}

void Context::Impl::Assert(const Formula& f) {
  if (FilterAssertion(f, &box())) {
    DREAL_LOG_DEBUG("Context::Assert: {} is not added.", f);
    DREAL_LOG_DEBUG("Box=\n{}", box());
    return;
  }

  // Predicate abstract & CNFize.
  const vector<Formula> clauses{
      cnfizer_.Convert(predicate_abstractor_.Convert(f))};
  for (const Formula& f_i : clauses) {
    DREAL_LOG_DEBUG("Context::Assert: {} is added.", f_i);
    stack_.push_back(f_i);
  }
}

optional<Box> Context::Impl::CheckSat() {
  DREAL_LOG_DEBUG("Context::CheckSat()");
  DREAL_LOG_TRACE("Context::CheckSat: Box =\n{}", box());
  if (box().empty()) {
    return {};
  }
  // If false ∈ stack_, it's UNSAT.
  for (const auto& f : stack_.get_vector()) {
    if (is_false(f)) {
      return {};
    }
  }
  // If {} = stack_ ∨ {true} = stack_, it's trivially SAT.
  if (stack_.empty() || (stack_.size() == 1 && is_true(stack_.first()))) {
    return box();
  }

  sat_solver_.AddClauses(stack_.get_vector());
  TheorySolver theory_solver{config_, box()};
  while (true) {
    if (sat_solver_.CheckSat()) {
      // SAT from SATSolver.
      DREAL_LOG_DEBUG("Context::CheckSat() - Sat Check = SAT");
      if (theory_solver.CheckSat(sat_solver_.model())) {
        // SAT from TheorySolver.
        DREAL_LOG_DEBUG("Context::CheckSat() - Theroy Check = delta-SAT");
        const Box model{theory_solver.GetModel()};
        return model;
      } else {
        // UNSAT from TheorySolver.
        DREAL_LOG_DEBUG("Context::CheckSat() - Theroy Check = UNSAT");
        const unordered_set<Formula, hash_value<Formula>> explanation{
            theory_solver.GetExplanation()};
        if (explanation.empty()) {
          return {};
        } else {
          DREAL_LOG_DEBUG(
              "Context::CheckSat() - size of explanation = {} - stack "
              "size = {}",
              explanation.size(), stack_.get_vector().size());
          sat_solver_.AddLearnedClause(explanation);
        }
      }
    } else {
      // UNSAT from SATSolver. Escape the loop.
      DREAL_LOG_DEBUG("Context::CheckSat() - Sat Check = UNSAT");
      return {};
    }
  }
}

void Context::Impl::DeclareVariable(const Variable& v) {
  DREAL_LOG_DEBUG("Context::DeclareVariable({})", v);
  name_to_var_map_.emplace(v.get_name(), v);
  box().Add(v);
}

void Context::Impl::DeclareVariable(const Variable& v, const Expression& lb,
                                    const Expression& ub) {
  DeclareVariable(v);
  SetInterval(v, lb.Evaluate(), ub.Evaluate());
}

void Context::Impl::Minimize(const Expression& f) {
  DREAL_LOG_DEBUG("Context::Minimize: {} is called.", f);

  // Given e = f(x) and the current constraints ϕᵢ which
  // involves x. it constructs a universally quantified formula ψ:
  //
  //    ψ = ∀y. (⋀ᵢ ϕᵢ(y)) → (f(x) ≤ f(y))
  //      = ∀y. ¬(⋀ᵢ ϕᵢ(y)) ∨ (f(x) ≤ f(y))
  //      = ∀y. (∨ᵢ ¬ϕᵢ(y)) ∨ (f(x) ≤ f(y)).
  //
  // To construct ϕᵢ(y), we need to traverse both `box()` and
  // `stack_` because some of the asserted formulas are translated
  // and applied into `box()`.
  set<Formula> set_of_negated_phi;  // Collects ¬ϕᵢ(y).
  ExpressionSubstitution subst;  // Maps xᵢ ↦ yᵢ to build f(y₁, ..., yₙ).
  Variables quantified_variables;  // {y₁, ... yₙ}
  const Variables x_vars{f.GetVariables()};
  for (const Variable& x_i : x_vars) {
    // We add postfix '_' to name y_i
    const Variable y_i{x_i.get_name() + "_", x_i.get_type()};
    quantified_variables.insert(y_i);
    subst.emplace(x_i, y_i);
    // If `box()[x_i]` has a finite bound, let's add that information in
    // set_of_negated_phi as a constraint on y_i.
    const Box::Interval& bound_on_x_i{box()[x_i]};
    const double lb_x_i{bound_on_x_i.lb()};
    const double ub_x_i{bound_on_x_i.ub()};
    if (isfinite(lb_x_i)) {
      set_of_negated_phi.insert(!(lb_x_i <= y_i));
    }
    if (isfinite(ub_x_i)) {
      set_of_negated_phi.insert(!(y_i <= ub_x_i));
    }
  }
  for (const Formula& constraint : stack_) {
    if (!intersect(x_vars, constraint.GetFreeVariables()).empty()) {
      // Case : xᵢ ∈ vars(constraint)
      // We need to collect constraint[xᵢ ↦ yᵢ].
      set_of_negated_phi.insert(!constraint.Substitute(subst));
    }
  }
  const Formula phi{make_disjunction(set_of_negated_phi)};  // ∨ᵢ ¬ϕᵢ(y)
  const Formula psi{
      forall(quantified_variables, phi || (f <= f.Substitute(subst)))};
  return Assert(psi);
}

void Context::Impl::Pop() {
  DREAL_LOG_DEBUG("Context::Pop()");
  stack_.pop();
  boxes_.pop();
  sat_solver_.Pop();
  // TODO(soonho): Pop cnfizer/predicate_abstractor_.
}

void Context::Impl::Push() {
  DREAL_LOG_DEBUG("Context::Push()");
  sat_solver_.Push();
  boxes_.push();
  boxes_.push_back(boxes_.last());
  stack_.push();
  // TODO(soonho): Push cnfizer/predicate_abstractor_.
}

void Context::Impl::SetInfo(const string& key, const string& val) {
  DREAL_LOG_DEBUG("Context::SetInfo({} ↦ {})", key, val);
  info_[key] = val;
  if (key == ":precision") {
    config_.mutable_precision().set_from_file(stod(val));
  }
}

void Context::Impl::SetInterval(const Variable& v, const double lb,
                                const double ub) {
  DREAL_LOG_DEBUG("Context::SetInterval({} = [{}, {}])", v, lb, ub);
  box()[v] = Box::Interval{lb, ub};
}

void Context::Impl::SetLogic(const Logic& logic) {
  DREAL_LOG_DEBUG("Context::SetLogic({})", logic);
  logic_ = logic;
}

void Context::Impl::SetOption(const string& key, const string& val) {
  DREAL_LOG_DEBUG("Context::SetOption({} ↦ {})", key, val);
  option_[key] = val;
  if (key == ":polytope") {
    if (val == "true") {
      config_.mutable_use_polytope().set_from_file(true);
    } else if (val == "false") {
      config_.mutable_use_polytope().set_from_file(false);
    } else {
      throw DREAL_RUNTIME_ERROR("Fail to interpret the option: " + key + " = " +
                                val);
    }
  }
  if (key == ":forall-polytope") {
    if (val == "true") {
      config_.mutable_use_polytope_in_forall().set_from_file(true);
    } else if (val == "false") {
      config_.mutable_use_polytope_in_forall().set_from_file(false);
    } else {
      throw DREAL_RUNTIME_ERROR("Fail to interpret the option: " + key + " = " +
                                val);
    }
  }
}

const Variable& Context::Impl::lookup_variable(const string& name) {
  const auto it = name_to_var_map_.find(name);
  if (it == name_to_var_map_.cend()) {
    throw DREAL_RUNTIME_ERROR(name + " is not found in the context.");
  }
  return it->second;
}

Context::Context() : impl_{new Impl{}} {}

Context::Context(Config config) : impl_{new Impl{move(config)}} {}

void Context::Assert(const Formula& f) { impl_->Assert(f); }

optional<Box> Context::CheckSat() { return impl_->CheckSat(); }

void Context::DeclareVariable(const Variable& v) { impl_->DeclareVariable(v); }

void Context::DeclareVariable(const Variable& v, const Expression& lb,
                              const Expression& ub) {
  impl_->DeclareVariable(v, lb, ub);
}

void Context::Exit() { DREAL_LOG_DEBUG("Context::Exit()"); }

void Context::Minimize(const Expression& f) { impl_->Minimize(f); }

void Context::Maximize(const Expression& f) { impl_->Minimize(-f); }

void Context::Pop(int n) {
  DREAL_LOG_DEBUG("Context::Pop({})", n);
  if (n <= 0) {
    ostringstream oss;
    oss << "Context::Pop(n) called with n = " << n << " which is not positive.";
    throw DREAL_RUNTIME_ERROR(oss.str());
  }
  while (n-- > 0) {
    impl_->Pop();
  }
}

void Context::Push(int n) {
  DREAL_LOG_DEBUG("Context::Push({})", n);
  if (n <= 0) {
    ostringstream oss;
    oss << "Context::Push(n) called with n = " << n
        << " which is not positive.";
    throw DREAL_RUNTIME_ERROR(oss.str());
  }
  while (n-- > 0) {
    impl_->Push();
  }
}

void Context::SetInfo(const string& key, const string& val) {
  impl_->SetInfo(key, val);
}

void Context::SetInterval(const Variable& v, const double lb, const double ub) {
  impl_->SetInterval(v, lb, ub);
}

void Context::SetLogic(const Logic& logic) { impl_->SetLogic(logic); }

void Context::SetOption(const string& key, const string& val) {
  impl_->SetOption(key, val);
}

const Variable& Context::lookup_variable(const string& name) {
  return impl_->lookup_variable(name);
}

const Config& Context::config() const { return impl_->config(); }
Config& Context::mutable_config() { return impl_->mutable_config(); }

string Context::version() { return DREAL_VERSION_STRING; }

}  // namespace dreal
<|endoftext|>