<commit_before>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TRD/AliTRDgeometry.h>
#include <TRD/AliTRDcalibDB.h>
#include <TRD/AliTRDcluster.h>
#include <TRD/AliTRDseedV1.h>
#include <TRD/AliTRDtrackV1.h>
#include <TProfile.h>
#endif

TH1* PH(const AliTRDtrackV1* track)
{
  if (!track)  return 0x0;

  AliTRDcluster* cls = 0;
  AliTRDseedV1 *tracklet = 0x0;

  Int_t ntb = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
  TProfile* ph = new TProfile("", "Average PH", ntb, -.5, ntb-.5);
  ph->GetXaxis()->SetTitle("drift time [1/100ns]");
  ph->GetYaxis()->SetTitle("<PH> [a.u.]");

  for (Int_t ily = 0; ily < AliTRDgeometry::kNlayer; ily++) {
    if(!(tracklet = track->GetTracklet(ily))) continue;
    if(!tracklet->IsOK()) continue;

    for (Int_t icl = 0; icl < AliTRDseed::knTimebins; icl++) {
      if(!(cls = tracklet->GetClusters(icl))) continue;

	    ph->Fill(cls->GetLocalTimeBin(), cls->GetQ());
	  }
  }

  return ph;
}

<commit_msg>reduce memory consumption in the histo process. Update for getting right the QA histograms<commit_after>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TROOT.h>
#include <TProfile.h>

#include <TRD/AliTRDgeometry.h>
#include <TRD/AliTRDcalibDB.h>
#include <TRD/AliTRDcluster.h>
#include <TRD/AliTRDseedV1.h>
#include <TRD/AliTRDtrackV1.h>
#endif

TH1* PH(const AliTRDtrackV1* track)
{
  if (!track)  return 0x0;

  AliTRDcluster* cls = 0;
  AliTRDseedV1 *tracklet = 0x0;

  TProfile* ph = 0x0;
  if(!(ph = (TProfile*)gROOT->FindObject("PH"))){
    Int_t ntb = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
    ph = new TProfile("PH", "Average PH", ntb, -.5, ntb-.5);
    ph->GetXaxis()->SetTitle("drift time [1/100ns]");
    ph->GetYaxis()->SetTitle("<PH> [a.u.]");
  } else ph->Reset();

  for (Int_t ily = 0; ily < AliTRDgeometry::kNlayer; ily++) {
    if(!(tracklet = track->GetTracklet(ily))) continue;
    if(!tracklet->IsOK()) continue;

    for (Int_t icl = 0; icl < AliTRDseed::knTimebins; icl++) {
      if(!(cls = tracklet->GetClusters(icl))) continue;

	    ph->Fill(cls->GetLocalTimeBin(), cls->GetQ());
	  }
  }

  return ph;
}

<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2015-2019, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

// Parts of this code sourced from SnopyDogy
// https://gist.github.com/SnopyDogy/a9a22497a893ec86aa3e

#include <common.hpp>
#include <err_opengl.hpp>
#include <window_impl.hpp>

#include <algorithm>
#include <memory>
#include <mutex>

#include <FreeImage.h>

using namespace fg;

static GLEWContext* current = nullptr;

GLEWContext* glewGetContext()
{
    return current;
}

/* following function is thread safe */
int getNextUniqueId()
{
    static int wndUnqIdTracker = 0;
    static std::mutex wndUnqIdMutex;

    std::lock_guard<std::mutex> lock(wndUnqIdMutex);
    return wndUnqIdTracker++;
}

class FI_Manager
{
    public:
    static bool initialized;
    FI_Manager()
    {
#ifdef FREEIMAGE_LIB
        FreeImage_Initialise();
#endif
        initialized = true;
    }

    ~FI_Manager()
    {
#ifdef FREEIMAGE_LIB
        FreeImage_DeInitialise();
#endif
    }
};

bool FI_Manager::initialized = false;

static void FI_Init()
{
    static FI_Manager manager = FI_Manager();
}

class FI_BitmapResource
{
public:
    explicit FI_BitmapResource(FIBITMAP * p) :
        pBitmap(p)
    {
    }

    ~FI_BitmapResource()
    {
        FreeImage_Unload(pBitmap);
    }
private:
    FIBITMAP * pBitmap;
};

namespace opengl
{

void MakeContextCurrent(const window_impl* pWindow)
{
    CheckGL("Begin MakeContextCurrent");
    if (pWindow != NULL) {
        pWindow->get()->makeContextCurrent();
        current = pWindow->glewContext();
    }
    CheckGL("End MakeContextCurrent");
}

window_impl::window_impl(int pWidth, int pHeight, const char* pTitle,
                        std::weak_ptr<window_impl> pWindow, const bool invisible)
    : mID(getNextUniqueId())
{
    if (auto observe = pWindow.lock()) {
        mWindow = new wtk::Widget(pWidth, pHeight, pTitle, observe->get(), invisible);
    } else {
        /* when windows are not sharing any context, just create
         * a dummy wtk::Widget object and pass it on */
        mWindow = new wtk::Widget(pWidth, pHeight, pTitle, nullptr, invisible);
    }

    /* create glew context so that it will bind itself to windows */
    if (auto observe = pWindow.lock()) {
        mGLEWContext = observe->glewContext();
    } else {
        mGLEWContext = new GLEWContext();
        if (mGLEWContext == NULL) {
            std::cerr<<"Error: Could not create GLEW Context!\n";
            throw fg::Error("window_impl constructor", __LINE__,
                    "GLEW context creation failed", FG_ERR_GL_ERROR);
        }
    }

    /* Set context (before glewInit()) */
    MakeContextCurrent(this);

    /* GLEW Initialization - Must be done */
    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (err != GLEW_OK) {
        char buffer[128];
        sprintf(buffer, "GLEW init failed: Error: %s\n", glewGetErrorString(err));
        throw fg::Error("window_impl constructor", __LINE__, buffer, FG_ERR_GL_ERROR);
    }
    err = glGetError();
    if (err!=GL_NO_ERROR && err!=GL_INVALID_ENUM) {
        /* ignore this error, as GLEW is known to
         * have this issue with 3.2+ core profiles
         * they are yet to fix this in GLEW
         */
        ForceCheckGL("GLEW initilization failed");
        throw fg::Error("window_impl constructor", __LINE__,
                "GLEW initilization failed", FG_ERR_GL_ERROR);
    }

    mCxt = mWindow->getGLContextHandle();
    mDsp = mWindow->getDisplayHandle();
    /* copy colormap shared pointer if
     * this window shares context with another window
     * */
    if (auto observe = pWindow.lock()) {
        mCMap = observe->colorMapPtr();
    } else {
        mCMap = std::make_shared<colormap_impl>();
    }

    mWindow->resizePixelBuffers();

    /* set the colormap to default */
    mColorMapUBO = mCMap->defaultMap();
    mUBOSize = mCMap->defaultLen();
    glEnable(GL_MULTISAMPLE);

    std::vector<glm::mat4>& mats = mWindow->mMVPs;
    mats.resize(mWindow->mRows*mWindow->mCols);
    std::fill(mats.begin(), mats.end(), glm::mat4(1));

    /* setup default window font */
    mFont = std::make_shared<font_impl>();
#ifdef OS_WIN
    mFont->loadSystemFont("Calibri");
#else
    mFont->loadSystemFont("Vera");
#endif
    glEnable(GL_DEPTH_TEST);

    CheckGL("End Window::Window");
}

window_impl::~window_impl()
{
    delete mWindow;
}

void window_impl::setFont(const std::shared_ptr<font_impl>& pFont)
{
    mFont = pFont;
}

void window_impl::setTitle(const char* pTitle)
{
    mWindow->setTitle(pTitle);
}

void window_impl::setPos(int pX, int pY)
{
    mWindow->setPos(pX, pY);
}

void window_impl::setSize(unsigned pW, unsigned pH)
{
    mWindow->setSize(pW, pH);
}

void window_impl::setColorMap(fg::ColorMap cmap)
{
    switch(cmap) {
        case FG_COLOR_MAP_DEFAULT:
            mColorMapUBO = mCMap->defaultMap();
            mUBOSize     = mCMap->defaultLen();
            break;
        case FG_COLOR_MAP_SPECTRUM:
            mColorMapUBO = mCMap->spectrum();
            mUBOSize     = mCMap->spectrumLen();
            break;
        case FG_COLOR_MAP_COLORS:
            mColorMapUBO = mCMap->colors();
            mUBOSize     = mCMap->colorsLen();
            break;
        case FG_COLOR_MAP_RED:
            mColorMapUBO = mCMap->red();
            mUBOSize     = mCMap->redLen();
            break;
        case FG_COLOR_MAP_MOOD:
            mColorMapUBO = mCMap->mood();
            mUBOSize     = mCMap->moodLen();
            break;
        case FG_COLOR_MAP_HEAT:
            mColorMapUBO = mCMap->heat();
            mUBOSize     = mCMap->heatLen();
            break;
        case FG_COLOR_MAP_BLUE:
            mColorMapUBO = mCMap->blue();
            mUBOSize     = mCMap->blueLen();
            break;
    }
}

int window_impl::getID() const
{
    return mID;
}

long long  window_impl::context() const
{
    return mCxt;
}

long long  window_impl::display() const
{
    return mDsp;
}

int window_impl::width() const
{
    return mWindow->mWidth;
}

int window_impl::height() const
{
    return mWindow->mHeight;
}

GLEWContext* window_impl::glewContext() const
{
    return mGLEWContext;
}

const wtk::Widget* window_impl::get() const
{
    return mWindow;
}

const std::shared_ptr<colormap_impl>& window_impl::colorMapPtr() const
{
    return mCMap;
}

void window_impl::hide()
{
    mWindow->hide();
}

void window_impl::show()
{
    mWindow->show();
}

bool window_impl::close()
{
    return mWindow->close();
}

void window_impl::draw(const std::shared_ptr<AbstractRenderable>& pRenderable)
{
    CheckGL("Begin window_impl::draw");
    MakeContextCurrent(this);
    mWindow->resetCloseFlag();
    glViewport(0, 0, mWindow->mWidth, mWindow->mHeight);

    const glm::mat4& mvp = mWindow->mMVPs[0];
    // clear color and depth buffers
    glClearColor(WHITE[0], WHITE[1], WHITE[2], WHITE[3]);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // set colormap call is equivalent to noop for non-image renderables
    pRenderable->setColorMapUBOParams(mColorMapUBO, mUBOSize);
    pRenderable->render(mID, 0, 0, mWindow->mWidth, mWindow->mHeight, mvp);

    mWindow->swapBuffers();
    mWindow->pollEvents();
    CheckGL("End window_impl::draw");
}

void window_impl::grid(int pRows, int pCols)
{
    glViewport(0, 0, mWindow->mWidth, mWindow->mHeight);
    glClearColor(WHITE[0], WHITE[1], WHITE[2], WHITE[3]);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    mWindow->mRows       = pRows;
    mWindow->mCols       = pCols;
    mWindow->mCellWidth  = mWindow->mWidth  / mWindow->mCols;
    mWindow->mCellHeight = mWindow->mHeight / mWindow->mRows;

    // resize mvp array for views to appropriate size
    std::vector<glm::mat4>& mats = mWindow->mMVPs;
    mats.resize(mWindow->mRows*mWindow->mCols);
    std::fill(mats.begin(), mats.end(), glm::mat4(1));
}

void window_impl::draw(int pColId, int pRowId,
                       const std::shared_ptr<AbstractRenderable>& pRenderable,
                       const char* pTitle)
{
    CheckGL("Begin draw(column, row)");
    MakeContextCurrent(this);
    mWindow->resetCloseFlag();

    float pos[2] = {0.0, 0.0};
    int c     = pColId;
    int r     = pRowId;
    int x_off = c * mWindow->mCellWidth;
    int y_off = (mWindow->mRows - 1 - r) * mWindow->mCellHeight;

    const glm::mat4& mvp = mWindow->mMVPs[r+c*mWindow->mRows];
    /* following margins are tested out for various
     * aspect ratios and are working fine. DO NOT CHANGE.
     * */
    int top_margin = int(0.06f*mWindow->mCellHeight);
    int bot_margin = int(0.02f*mWindow->mCellHeight);
    int lef_margin = int(0.02f*mWindow->mCellWidth);
    int rig_margin = int(0.02f*mWindow->mCellWidth);
    // set viewport to render sub image
    glViewport(x_off + lef_margin, y_off + bot_margin,
            mWindow->mCellWidth - 2 * rig_margin, mWindow->mCellHeight - 2 * top_margin);
    glScissor(x_off + lef_margin, y_off + bot_margin,
            mWindow->mCellWidth - 2 * rig_margin, mWindow->mCellHeight - 2 * top_margin);
    glEnable(GL_SCISSOR_TEST);

    // set colormap call is equivalent to noop for non-image renderables
    pRenderable->setColorMapUBOParams(mColorMapUBO, mUBOSize);
    pRenderable->render(mID, x_off, y_off, mWindow->mCellWidth, mWindow->mCellHeight, mvp);

    glDisable(GL_SCISSOR_TEST);
    glViewport(x_off, y_off, mWindow->mCellWidth, mWindow->mCellHeight);

    if (pTitle!=NULL) {
        mFont->setOthro2D(mWindow->mCellWidth, mWindow->mCellHeight);
        pos[0] = mWindow->mCellWidth / 3.0f;
        pos[1] = mWindow->mCellHeight*0.92f;
        mFont->render(mID, pos, AF_BLUE, pTitle, 16);
    }

    CheckGL("End draw(column, row)");
}

void window_impl::swapBuffers()
{
    mWindow->swapBuffers();
    mWindow->pollEvents();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void window_impl::saveFrameBuffer(const char* pFullPath)
{
    if (!pFullPath) {
        throw fg::ArgumentError("window_impl::saveFrameBuffer", __LINE__, 1,
                                "Empty path string");
    }

    FI_Init();

    auto FIErrorHandler = [](FREE_IMAGE_FORMAT pOutputFIFormat, const char* pMessage) {
        printf("FreeImage Error Handler: %s\n", pMessage);
    };

    FreeImage_SetOutputMessage(FIErrorHandler);

    FREE_IMAGE_FORMAT format = FreeImage_GetFileType(pFullPath);
    if (format == FIF_UNKNOWN) {
        format = FreeImage_GetFIFFromFilename(pFullPath);
    }
    if (format == FIF_UNKNOWN) {
        throw fg::Error("window_impl::saveFrameBuffer", __LINE__,
                        "Freeimage: unrecognized image format", FG_ERR_FREEIMAGE_UNKNOWN_FORMAT);
    }

    if (!(format==FIF_BMP || format==FIF_PNG)) {
        throw fg::ArgumentError("window_impl::saveFrameBuffer", __LINE__, 1,
                                "Supports only bmp and png as of now");
    }

    uint w = mWindow->mWidth;
    uint h = mWindow->mHeight;
    uint c = 4;
    uint d = c * 8;

    FIBITMAP* bmp = FreeImage_Allocate(w, h, d);
    if (!bmp) {
        throw fg::Error("window_impl::saveFrameBuffer", __LINE__,
                        "Freeimage: allocation failed", FG_ERR_FREEIMAGE_BAD_ALLOC);
    }

    FI_BitmapResource bmpUnloader(bmp);

    uint pitch = FreeImage_GetPitch(bmp);
    uchar* dst = FreeImage_GetBits(bmp);

    /* as glReadPixels was called using PBO earlier, hopefully
     * it was async call(which it should be unless vendor driver
     * is doing something fishy) and the transfer is over by now
     * */
    glBindBuffer(GL_PIXEL_PACK_BUFFER, mWindow->mFramePBO);

    uchar* src = (uchar*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);

    if (src) {
        // copy data from mapped memory location
        uint w = mWindow->mWidth;
        uint h = mWindow->mHeight;
        uint i = 0;

        for (uint y = 0; y < h; ++y) {
            for (uint x = 0; x < w; ++x) {
                *(dst + x * c + FI_RGBA_RED  ) = (uchar) src[4*i+0]; // r
                *(dst + x * c + FI_RGBA_GREEN) = (uchar) src[4*i+1]; // g
                *(dst + x * c + FI_RGBA_BLUE ) = (uchar) src[4*i+2]; // b
                *(dst + x * c + FI_RGBA_ALPHA) = (uchar) src[4*i+3]; // a
                ++i;
            }
            dst += pitch;
        }

        glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
    }

    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

    int flags = 0;
    if (format == FIF_JPEG)
        flags = flags | JPEG_QUALITYSUPERB;

    if (!(FreeImage_Save(format,bmp, pFullPath, flags) == TRUE)) {
    }
}

}
<commit_msg>BUGFIX: AMD APU - examples are working fine.<commit_after>/*******************************************************
 * Copyright (c) 2015-2019, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

// Parts of this code sourced from SnopyDogy
// https://gist.github.com/SnopyDogy/a9a22497a893ec86aa3e

#include <common.hpp>
#include <err_opengl.hpp>
#include <window_impl.hpp>

#include <algorithm>
#include <memory>
#include <mutex>

#include <FreeImage.h>

using namespace fg;

static GLEWContext* current = nullptr;

GLEWContext* glewGetContext()
{
    return current;
}

/* following function is thread safe */
int getNextUniqueId()
{
    static int wndUnqIdTracker = 0;
    static std::mutex wndUnqIdMutex;

    std::lock_guard<std::mutex> lock(wndUnqIdMutex);
    return wndUnqIdTracker++;
}

class FI_Manager
{
    public:
    static bool initialized;
    FI_Manager()
    {
#ifdef FREEIMAGE_LIB
        FreeImage_Initialise();
#endif
        initialized = true;
    }

    ~FI_Manager()
    {
#ifdef FREEIMAGE_LIB
        FreeImage_DeInitialise();
#endif
    }
};

bool FI_Manager::initialized = false;

static void FI_Init()
{
    static FI_Manager manager = FI_Manager();
}

class FI_BitmapResource
{
public:
    explicit FI_BitmapResource(FIBITMAP * p) :
        pBitmap(p)
    {
    }

    ~FI_BitmapResource()
    {
        FreeImage_Unload(pBitmap);
    }
private:
    FIBITMAP * pBitmap;
};

namespace opengl
{

void MakeContextCurrent(const window_impl* pWindow)
{
    if (pWindow != NULL) {
        pWindow->get()->makeContextCurrent();
        current = pWindow->glewContext();
    }
}

window_impl::window_impl(int pWidth, int pHeight, const char* pTitle,
                        std::weak_ptr<window_impl> pWindow, const bool invisible)
    : mID(getNextUniqueId())
{
    if (auto observe = pWindow.lock()) {
        mWindow = new wtk::Widget(pWidth, pHeight, pTitle, observe->get(), invisible);
		/* create glew context so that it will bind itself to windows */
		mGLEWContext = observe->glewContext();
    } else {
        /* when windows are not sharing any context, just create
         * a dummy wtk::Widget object and pass it on */
        mWindow = new wtk::Widget(pWidth, pHeight, pTitle, nullptr, invisible);
		/* create glew context so that it will bind itself to windows */
		mGLEWContext = new GLEWContext();
		if (mGLEWContext == NULL) {
			std::cerr << "Error: Could not create GLEW Context!\n";
			throw fg::Error("window_impl constructor", __LINE__,
				"GLEW context creation failed", FG_ERR_GL_ERROR);
		}
	}
	/* Set context (before glewInit()) */
	MakeContextCurrent(this);

    /* GLEW Initialization - Must be done */
    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (err != GLEW_OK) {
        char buffer[128];
        sprintf(buffer, "GLEW init failed: Error: %s\n", glewGetErrorString(err));
        throw fg::Error("window_impl constructor", __LINE__, buffer, FG_ERR_GL_ERROR);
    }
    err = glGetError();
    if (err!=GL_NO_ERROR && err!=GL_INVALID_ENUM) {
        /* ignore this error, as GLEW is known to
         * have this issue with 3.2+ core profiles
         * they are yet to fix this in GLEW
         */
        ForceCheckGL("GLEW initilization failed");
        throw fg::Error("window_impl constructor", __LINE__,
                "GLEW initilization failed", FG_ERR_GL_ERROR);
    }

    mCxt = mWindow->getGLContextHandle();
    mDsp = mWindow->getDisplayHandle();
    /* copy colormap shared pointer if
     * this window shares context with another window
     * */
    if (auto observe = pWindow.lock()) {
        mCMap = observe->colorMapPtr();
    } else {
        mCMap = std::make_shared<colormap_impl>();
    }

    mWindow->resizePixelBuffers();

    /* set the colormap to default */
    mColorMapUBO = mCMap->defaultMap();
    mUBOSize = mCMap->defaultLen();
    glEnable(GL_MULTISAMPLE);

    std::vector<glm::mat4>& mats = mWindow->mMVPs;
    mats.resize(mWindow->mRows*mWindow->mCols);
    std::fill(mats.begin(), mats.end(), glm::mat4(1));

    /* setup default window font */
    mFont = std::make_shared<font_impl>();
#ifdef OS_WIN
    mFont->loadSystemFont("Calibri");
#else
    mFont->loadSystemFont("Vera");
#endif
    glEnable(GL_DEPTH_TEST);

    CheckGL("End Window::Window");
}

window_impl::~window_impl()
{
    delete mWindow;
}

void window_impl::setFont(const std::shared_ptr<font_impl>& pFont)
{
    mFont = pFont;
}

void window_impl::setTitle(const char* pTitle)
{
    mWindow->setTitle(pTitle);
}

void window_impl::setPos(int pX, int pY)
{
    mWindow->setPos(pX, pY);
}

void window_impl::setSize(unsigned pW, unsigned pH)
{
    mWindow->setSize(pW, pH);
}

void window_impl::setColorMap(fg::ColorMap cmap)
{
    switch(cmap) {
        case FG_COLOR_MAP_DEFAULT:
            mColorMapUBO = mCMap->defaultMap();
            mUBOSize     = mCMap->defaultLen();
            break;
        case FG_COLOR_MAP_SPECTRUM:
            mColorMapUBO = mCMap->spectrum();
            mUBOSize     = mCMap->spectrumLen();
            break;
        case FG_COLOR_MAP_COLORS:
            mColorMapUBO = mCMap->colors();
            mUBOSize     = mCMap->colorsLen();
            break;
        case FG_COLOR_MAP_RED:
            mColorMapUBO = mCMap->red();
            mUBOSize     = mCMap->redLen();
            break;
        case FG_COLOR_MAP_MOOD:
            mColorMapUBO = mCMap->mood();
            mUBOSize     = mCMap->moodLen();
            break;
        case FG_COLOR_MAP_HEAT:
            mColorMapUBO = mCMap->heat();
            mUBOSize     = mCMap->heatLen();
            break;
        case FG_COLOR_MAP_BLUE:
            mColorMapUBO = mCMap->blue();
            mUBOSize     = mCMap->blueLen();
            break;
    }
}

int window_impl::getID() const
{
    return mID;
}

long long  window_impl::context() const
{
    return mCxt;
}

long long  window_impl::display() const
{
    return mDsp;
}

int window_impl::width() const
{
    return mWindow->mWidth;
}

int window_impl::height() const
{
    return mWindow->mHeight;
}

GLEWContext* window_impl::glewContext() const
{
    return mGLEWContext;
}

const wtk::Widget* window_impl::get() const
{
    return mWindow;
}

const std::shared_ptr<colormap_impl>& window_impl::colorMapPtr() const
{
    return mCMap;
}

void window_impl::hide()
{
    mWindow->hide();
}

void window_impl::show()
{
    mWindow->show();
}

bool window_impl::close()
{
    return mWindow->close();
}

void window_impl::draw(const std::shared_ptr<AbstractRenderable>& pRenderable)
{
    CheckGL("Begin window_impl::draw");
    MakeContextCurrent(this);
    mWindow->resetCloseFlag();
    glViewport(0, 0, mWindow->mWidth, mWindow->mHeight);

    const glm::mat4& mvp = mWindow->mMVPs[0];
    // clear color and depth buffers
    glClearColor(WHITE[0], WHITE[1], WHITE[2], WHITE[3]);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // set colormap call is equivalent to noop for non-image renderables
    pRenderable->setColorMapUBOParams(mColorMapUBO, mUBOSize);
    pRenderable->render(mID, 0, 0, mWindow->mWidth, mWindow->mHeight, mvp);

    mWindow->swapBuffers();
    mWindow->pollEvents();
    CheckGL("End window_impl::draw");
}

void window_impl::grid(int pRows, int pCols)
{
    glViewport(0, 0, mWindow->mWidth, mWindow->mHeight);
    glClearColor(WHITE[0], WHITE[1], WHITE[2], WHITE[3]);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    mWindow->mRows       = pRows;
    mWindow->mCols       = pCols;
    mWindow->mCellWidth  = mWindow->mWidth  / mWindow->mCols;
    mWindow->mCellHeight = mWindow->mHeight / mWindow->mRows;

    // resize mvp array for views to appropriate size
    std::vector<glm::mat4>& mats = mWindow->mMVPs;
    mats.resize(mWindow->mRows*mWindow->mCols);
    std::fill(mats.begin(), mats.end(), glm::mat4(1));
}

void window_impl::draw(int pColId, int pRowId,
                       const std::shared_ptr<AbstractRenderable>& pRenderable,
                       const char* pTitle)
{
    CheckGL("Begin draw(column, row)");
    MakeContextCurrent(this);
    mWindow->resetCloseFlag();

    float pos[2] = {0.0, 0.0};
    int c     = pColId;
    int r     = pRowId;
    int x_off = c * mWindow->mCellWidth;
    int y_off = (mWindow->mRows - 1 - r) * mWindow->mCellHeight;

    const glm::mat4& mvp = mWindow->mMVPs[r+c*mWindow->mRows];
    /* following margins are tested out for various
     * aspect ratios and are working fine. DO NOT CHANGE.
     * */
    int top_margin = int(0.06f*mWindow->mCellHeight);
    int bot_margin = int(0.02f*mWindow->mCellHeight);
    int lef_margin = int(0.02f*mWindow->mCellWidth);
    int rig_margin = int(0.02f*mWindow->mCellWidth);
    // set viewport to render sub image
    glViewport(x_off + lef_margin, y_off + bot_margin,
            mWindow->mCellWidth - 2 * rig_margin, mWindow->mCellHeight - 2 * top_margin);
    glScissor(x_off + lef_margin, y_off + bot_margin,
            mWindow->mCellWidth - 2 * rig_margin, mWindow->mCellHeight - 2 * top_margin);
    glEnable(GL_SCISSOR_TEST);

    // set colormap call is equivalent to noop for non-image renderables
    pRenderable->setColorMapUBOParams(mColorMapUBO, mUBOSize);
    pRenderable->render(mID, x_off, y_off, mWindow->mCellWidth, mWindow->mCellHeight, mvp);

    glDisable(GL_SCISSOR_TEST);
    glViewport(x_off, y_off, mWindow->mCellWidth, mWindow->mCellHeight);

    if (pTitle!=NULL) {
        mFont->setOthro2D(mWindow->mCellWidth, mWindow->mCellHeight);
        pos[0] = mWindow->mCellWidth / 3.0f;
        pos[1] = mWindow->mCellHeight*0.92f;
        mFont->render(mID, pos, AF_BLUE, pTitle, 16);
    }

    CheckGL("End draw(column, row)");
}

void window_impl::swapBuffers()
{
    mWindow->swapBuffers();
    mWindow->pollEvents();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void window_impl::saveFrameBuffer(const char* pFullPath)
{
    if (!pFullPath) {
        throw fg::ArgumentError("window_impl::saveFrameBuffer", __LINE__, 1,
                                "Empty path string");
    }

    FI_Init();

    auto FIErrorHandler = [](FREE_IMAGE_FORMAT pOutputFIFormat, const char* pMessage) {
        printf("FreeImage Error Handler: %s\n", pMessage);
    };

    FreeImage_SetOutputMessage(FIErrorHandler);

    FREE_IMAGE_FORMAT format = FreeImage_GetFileType(pFullPath);
    if (format == FIF_UNKNOWN) {
        format = FreeImage_GetFIFFromFilename(pFullPath);
    }
    if (format == FIF_UNKNOWN) {
        throw fg::Error("window_impl::saveFrameBuffer", __LINE__,
                        "Freeimage: unrecognized image format", FG_ERR_FREEIMAGE_UNKNOWN_FORMAT);
    }

    if (!(format==FIF_BMP || format==FIF_PNG)) {
        throw fg::ArgumentError("window_impl::saveFrameBuffer", __LINE__, 1,
                                "Supports only bmp and png as of now");
    }

    uint w = mWindow->mWidth;
    uint h = mWindow->mHeight;
    uint c = 4;
    uint d = c * 8;

    FIBITMAP* bmp = FreeImage_Allocate(w, h, d);
    if (!bmp) {
        throw fg::Error("window_impl::saveFrameBuffer", __LINE__,
                        "Freeimage: allocation failed", FG_ERR_FREEIMAGE_BAD_ALLOC);
    }

    FI_BitmapResource bmpUnloader(bmp);

    uint pitch = FreeImage_GetPitch(bmp);
    uchar* dst = FreeImage_GetBits(bmp);

    /* as glReadPixels was called using PBO earlier, hopefully
     * it was async call(which it should be unless vendor driver
     * is doing something fishy) and the transfer is over by now
     * */
    glBindBuffer(GL_PIXEL_PACK_BUFFER, mWindow->mFramePBO);

    uchar* src = (uchar*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);

    if (src) {
        // copy data from mapped memory location
        uint w = mWindow->mWidth;
        uint h = mWindow->mHeight;
        uint i = 0;

        for (uint y = 0; y < h; ++y) {
            for (uint x = 0; x < w; ++x) {
                *(dst + x * c + FI_RGBA_RED  ) = (uchar) src[4*i+0]; // r
                *(dst + x * c + FI_RGBA_GREEN) = (uchar) src[4*i+1]; // g
                *(dst + x * c + FI_RGBA_BLUE ) = (uchar) src[4*i+2]; // b
                *(dst + x * c + FI_RGBA_ALPHA) = (uchar) src[4*i+3]; // a
                ++i;
            }
            dst += pitch;
        }

        glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
    }

    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

    int flags = 0;
    if (format == FIF_JPEG)
        flags = flags | JPEG_QUALITYSUPERB;

    if (!(FreeImage_Save(format,bmp, pFullPath, flags) == TRUE)) {
    }
}

}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ inlcludes

// Local includes
#include "fe.h"
#include "elem.h"

// FIXME: 3D C1 finite elements are still a work in progress

// Anonymous namespace for persistant variables.
// This allows us to cache the global-to-local mapping transformation
// This should also screw up multithreading royally
namespace
{
  using namespace libMesh;

  static unsigned int old_elem_id = libMesh::invalid_uint;
  // Coefficient naming: d(1)d(2n) is the coefficient of the
  // global shape function corresponding to value 1 in terms of the
  // local shape function corresponding to normal derivative 2

Real clough_raw_shape_second_deriv(const unsigned int basis_num,
                                   const unsigned int deriv_type,
                                   const Point& p);
Real clough_raw_shape_deriv(const unsigned int basis_num,
                            const unsigned int deriv_type,
                            const Point& p);
Real clough_raw_shape(const unsigned int basis_num,
                      const Point& p);

// Compute the static coefficients for an element
void clough_compute_coefs(const Elem* elem)
{
  // Using static globals for old_elem_id, etc. will fail
  // horribly with more than one thread.
  libmesh_assert(libMesh::n_threads() == 1);

  // Coefficients are cached from old elements
  if (elem->id() == old_elem_id)
    return;

  old_elem_id = elem->id();

#if 0
  const Order mapping_order        (elem->default_order());
  const ElemType mapping_elem_type (elem->type());
  const int n_mapping_shape_functions =
    FE<3,LAGRANGE>::n_shape_functions(mapping_elem_type,
				      mapping_order);

  // Degrees of freedom are at vertices and edge midpoints
  std::vector<Point> dofpt;
#endif

}

unsigned char subtriangle_lookup(const Point&)
{
  return 0;
}

  // Return shape function second derivatives on the unit right
  // triangle
Real clough_raw_shape_second_deriv(const unsigned int basis_num,
                            const unsigned int deriv_type,
                            const Point& p)
{
  Real xi = p(0), eta = p(1), zeta = p(2);

  switch (deriv_type)
  {

  // second derivative in xi-xi direction
  case 0:
  switch (basis_num)
    {
      case 0:
        switch (subtriangle_lookup(p))
          {
            case 0:
              break;
          }
    }
  }

  libmesh_error();
  return xi + eta + zeta;
}

Real clough_raw_shape_deriv(const unsigned int basis_num,
                            const unsigned int deriv_type,
                            const Point& p)
{
  Real xi = p(0), eta = p(1), zeta = p(2);

  switch (deriv_type)
  {
  case 0:
  switch (basis_num)
    {
      case 0:
        switch (subtriangle_lookup(p))
          {
            case 0:
              break;
          }
    }
  }

  libmesh_error();
  return xi + eta + zeta;
}

Real clough_raw_shape(const unsigned int basis_num,
                      const Point& p)
{
  Real xi = p(0), eta = p(1), zeta = p(2);

  switch (basis_num)
    {
      case 0:
        switch (subtriangle_lookup(p))
          {
            case 0:
              break;
          }
    }

  libmesh_error();
  return xi + eta + zeta;
}

} // end anonymous namespace

namespace libMesh
{

template <>
Real FE<3,CLOUGH>::shape(const ElemType,
			     const Order,
			     const unsigned int,
			     const Point&)
{
  libMesh::err << "Clough-Tocher elements require the real element\n"
	        << "to construct gradient-based degrees of freedom."
	        << std::endl;

  libmesh_error();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape(const Elem* elem,
			     const Order order,
			     const unsigned int,
			     const Point&)
{
  libmesh_assert (elem != NULL);

  libMesh::err << "3D Clough elements not yet implemented."
	        << std::endl;

  libmesh_error();

  clough_compute_coefs(elem);

  const ElemType type = elem->type();

  switch (order+elem->p_level())
    {
      // 3rd-order Clough-Tocher element
    case THIRD:
      {
	switch (type)
	  {
	  default:
            libMesh::err << "ERROR: Unsupported element type!" << std::endl;
	    libmesh_error();
	  }
      }
      // by default throw an error
    default:
      libMesh::err << "ERROR: Unsupported polynomial order!" << std::endl;
      libmesh_error();
    }

  libmesh_error();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape_deriv(const ElemType,
				   const Order,
				   const unsigned int,
				   const unsigned int,
				   const Point&)
{
  libMesh::err << "Clough-Tocher elements require the real element\n"
	        << "to construct gradient-based degrees of freedom."
	        << std::endl;

  libmesh_error();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape_deriv(const Elem* elem,
				   const Order order,
				   const unsigned int,
				   const unsigned int,
				   const Point&)
{
  libmesh_assert (elem != NULL);

  libMesh::err << "3D Clough elements not yet implemented."
	        << std::endl;

  libmesh_error();

  clough_compute_coefs(elem);

  const ElemType type = elem->type();

  switch (order+elem->p_level())
    {
      // 3rd-order Clough-Tocher element
    case THIRD:
      {
	switch (type)
	  {
	  default:
            libMesh::err << "ERROR: Unsupported element type!" << std::endl;
	    libmesh_error();
	  }
      }
      // by default throw an error
    default:
      libMesh::err << "ERROR: Unsupported polynomial order!" << std::endl;
      libmesh_error();
    }

  libmesh_error();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape_second_deriv(const Elem* elem,
                                      const Order order,
                                      const unsigned int,
                                      const unsigned int,
                                      const Point&)
{
  libmesh_assert (elem != NULL);

  libMesh::err << "3D Clough elements not yet implemented."
	    << std::endl;

  libmesh_error();

  clough_compute_coefs(elem);

  const ElemType type = elem->type();

  switch (order+elem->p_level())
    {
      // 3rd-order Clough-Tocher element
    case THIRD:
      {
	switch (type)
	  {
	  default:
            libMesh::err << "ERROR: Unsupported element type!" << std::endl;
	    libmesh_error();
	  }
      }
      // by default throw an error
    default:
      libMesh::err << "ERROR: Unsupported polynomial order!" << std::endl;
      libmesh_error();
    }

  libmesh_error();
  return 0.;
}

} // namespace libMesh
<commit_msg>We don't need more than stubs for the unimplemented 3D Clough-Tocher case, and the cut-n-pasted code was triggering clang warnings<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

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

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes

// Local includes
#include "fe.h"
#include "elem.h"

// FIXME: 3D C1 finite elements are still a work in progress

namespace libMesh
{

template <>
Real FE<3,CLOUGH>::shape(const ElemType,
			     const Order,
			     const unsigned int,
			     const Point&)
{
  libMesh::err << "Clough-Tocher elements require the real element\n"
	        << "to construct gradient-based degrees of freedom."
	        << std::endl;

  libmesh_error();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape(const Elem* elem,
			     const Order,
			     const unsigned int,
			     const Point&)
{
  libmesh_assert (elem != NULL);

  libmesh_not_implemented();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape_deriv(const ElemType,
				   const Order,
				   const unsigned int,
				   const unsigned int,
				   const Point&)
{
  libMesh::err << "Clough-Tocher elements require the real element\n"
	        << "to construct gradient-based degrees of freedom."
	        << std::endl;

  libmesh_error();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape_deriv(const Elem* elem,
				   const Order,
				   const unsigned int,
				   const unsigned int,
				   const Point&)
{
  libmesh_assert (elem != NULL);
  libmesh_not_implemented();
  return 0.;
}

template <>
Real FE<3,CLOUGH>::shape_second_deriv(const Elem* elem,
                                      const Order,
                                      const unsigned int,
                                      const unsigned int,
                                      const Point&)
{
  libmesh_assert (elem != NULL);
  libmesh_not_implemented();
  return 0.;
}

} // namespace libMesh
<|endoftext|>


<commit_before>#ifndef _QIMESSAGING_TYPE_HPP_
#define _QIMESSAGING_TYPE_HPP_

#include <typeinfo>
#include <boost/preprocessor.hpp>
#include <qimessaging/datastream.hpp>
#include <qimessaging/details/dynamic_value.hpp>

namespace qi{

/** Interface for all the operations we need on any type:
 *
 *  - cloning/destruction in clone() and destroy()
 *  - type conversion is made by going through the generic container
 *    Value, using the toValue() and fromValue() functions,
 *  - Serialization through serialize() and deserialize() to transmit
 *    the value through some kind of pipe.
 *
 * Our aim is to transport arbitrary values through:
 *  - synchronous calls: Nothing to do, values are just transported and
      converted.
 *  - asynchronous call/thread change: Values are copied.
 *  - process change: Values are serialized.
 *
 */
class QIMESSAGING_API Type
{
public:
  virtual const std::type_info& info() =0;
  const char* infoString() { return info().name();} // for easy gdb access
  /// @return the serialization signature used by this type.
  virtual std::string signature()=0;

  virtual void* clone(void*)=0;
  virtual void destroy(void*)=0;

  virtual bool  toValue(const void*, qi::detail::DynamicValue&)=0;
  virtual void* fromValue(const qi::detail::DynamicValue&)=0;

  // Default impl does toValue.serialize()
  virtual void  serialize(ODataStream& s, const void*)=0;
  // Default impl does deserialize(Value&) then fromValue
  virtual void* deserialize(IDataStream& s)=0;

  /* When someone makes a call with arguments that do not match the
   * target signature (ex: int vs float), we want to handle it.
   * For this, given the known correct signature S and known incorrect
   * Value v, we want to be able to obtain a new Type T that
   * serializes with type S, and then try to convert o into type T.
   *
   * For this we need a map<Signature, Type> that we will feed with
   * known types.
   *
   */
  typedef std::map<std::string, Type*> TypeSignatureMap;
  static TypeSignatureMap& typeSignatureMap()
  {
    static TypeSignatureMap res;
    return res;
  }

  static Type* getCompatibleTypeWithSignature(const std::string& sig)
  {
    TypeSignatureMap::iterator i = typeSignatureMap().find(sig);
    if (i == typeSignatureMap().end())
      return 0;
    else
      return i->second;
  }

  static bool registerCompatibleType(const std::string& sig,
    Type* mt)
  {
    typeSignatureMap()[sig] = mt;
    return true;
  }

  #define QI_REGISTER_MAPPING(sig, type) \
  static bool BOOST_PP_CAT(_qireg_map_ , __LINE__) = ::qi::Type::registerCompatibleType(sig, \
    ::qi::typeOf<type>());
};

/** Meta-type specialization.
 *  Use the aspect pattern, make a class per feature group
 *  (Clone, Value, Serialize)
 *
 */

template<typename T> class TypeDefaultClone
{
public:
  void* clone(void* src)
  {
    return new T(*(T*)src);
  }

  void destroy(void* ptr)
  {
    delete (T*)ptr;
  }
};

template<typename T> class TypeNoClone
{
public:
  void* clone(void* src)
  {
    return src;
  }

  void destroy(void* ptr)
  {
    delete (T*)ptr;
  }
};

template<typename T>class TypeDefaultValue
{
public:
  bool toValue(const void* ptr, qi::detail::DynamicValue& val)
  {
    detail::DynamicValueConverter<T>::writeDynamicValue(*(T*)ptr, val);
    return true;
  }

  void* fromValue(const qi::detail::DynamicValue& val)
  {
    T* res = new T();
    detail::DynamicValueConverter<T>::readDynamicValue(val, *res);
    return res;
  }
};

template<typename T>class TypeNoValue
{
public:
  bool toValue(const void* ptr, qi::detail::DynamicValue& val)
  {
    qiLogWarning("qi.type") << "toValue not implemented for type ";
    return false;
  }

  void* fromValue(const qi::detail::DynamicValue& val)
  {
    qiLogWarning("qi.type") << "fromValue not implemented for type ";
    T* res = new T();
    return res;
  }
};

template<typename T> class TypeDefaultSerialize
{
public:
  void  serialize(ODataStream& s, const void* ptr)
  {
    s << *(T*)ptr;
  }

  void* deserialize(IDataStream& s)
  {
    T* val = new T();
    s >> *val;
    return val;
  }
  std::string signature()
  {
    return signatureFromType<T>::value();
  }
};

template<typename T> class TypeNoSerialize
{
public:
  void serialize(ODataStream& s, const void* ptr)
  {
    qiLogWarning("qi.meta") << "type not serializable";
  }

  void* deserialize(IDataStream& s)
  {
    qiLogWarning("qi.meta") << "type not serializable";
    T* val = new T();
    return val;
  }
  std::string signature()
  {
    std::string res;
    res += (char)Signature::Type_Unknown;
    return res;
  }
};

/* TypeImpl implementation that bounces to the various aspect
 * subclasses.
 *
 * That way we can split the various aspects in different classes
 * for better reuse, without the cost of a second virtual call.
 */
template<typename T, typename Cloner    = TypeDefaultClone<T>
                   , typename Value     = TypeNoValue<T>
                   , typename Serialize = TypeNoSerialize<T>
         > class DefaultTypeImpl
: public Cloner
, public Value
, public Serialize
, public virtual Type
{
  virtual const std::type_info& info()
  {
    static T v; return typeid(v);
  }

  virtual void* clone(void* src)
  {
    return Cloner::clone(src);
  }

  virtual void destroy(void* ptr)
  {
    Cloner::destroy(ptr);
  }

  virtual bool toValue(const void* ptr, qi::detail::DynamicValue& val)
  {
    return Value::toValue(ptr, val);
  }

  virtual void* fromValue(const qi::detail::DynamicValue& val)
  {
    return Value::fromValue(val);
  }

  virtual std::string signature()
  {
    return Serialize::signature();
  }

  virtual void  serialize(ODataStream& s, const void* ptr)
  {
    Serialize::serialize(s, ptr);
  }

  virtual void* deserialize(IDataStream& s)
  {
    return Serialize::deserialize(s);
  }
};

/* Type "factory". Specialize this class to provide a custom
 * Type for a given type.
 */
template<typename T> class TypeImpl: public virtual DefaultTypeImpl<T>
{
};

/// Declare a type that is convertible to Value, and serializable
#define QI_TYPE_CONVERTIBLE_SERIALIZABLE(T)  \
namespace qi {                                   \
template<> class TypeImpl<T>:                \
  public DefaultTypeImpl<T,                  \
    TypeDefaultClone<T>,                     \
    TypeDefaultValue<T>,                     \
    TypeDefaultSerialize<T>                  \
  >{}; }

/** Declare that a type is not convertible to Value.
 *  Must be called outside any namespace.
 */
#define QI_TYPE_SERIALIZABLE(T)              \
namespace qi {                                   \
template<> class TypeImpl<T>:                \
  public DefaultTypeImpl<T,                  \
    TypeDefaultClone<T>,                     \
    TypeNoValue<T>,                          \
    TypeDefaultSerialize<T>                  \
  >{}; }

/// Declare that a type has no metatype and cannot be used in a Value
#define QI_NO_TYPE(T) namespace qi {template<> class TypeImpl<T> {};}

/// Get type from a type. No need to delete the result
template<typename T> Type* typeOf()
{
  static TypeImpl<typename boost::remove_const<T>::type> res;
  return &res;
}

/// Get type from a value. No need to delete the result
template<typename T> Type* typeOf(const T& v)
{
  return typeOf<T>();
}

}

QI_TYPE_SERIALIZABLE(Buffer);

#include <qimessaging/details/type.hxx>

#endif
<commit_msg>TypeNoClone: do not delete.<commit_after>#ifndef _QIMESSAGING_TYPE_HPP_
#define _QIMESSAGING_TYPE_HPP_

#include <typeinfo>
#include <boost/preprocessor.hpp>
#include <qimessaging/datastream.hpp>
#include <qimessaging/details/dynamic_value.hpp>

namespace qi{

/** Interface for all the operations we need on any type:
 *
 *  - cloning/destruction in clone() and destroy()
 *  - type conversion is made by going through the generic container
 *    Value, using the toValue() and fromValue() functions,
 *  - Serialization through serialize() and deserialize() to transmit
 *    the value through some kind of pipe.
 *
 * Our aim is to transport arbitrary values through:
 *  - synchronous calls: Nothing to do, values are just transported and
      converted.
 *  - asynchronous call/thread change: Values are copied.
 *  - process change: Values are serialized.
 *
 */
class QIMESSAGING_API Type
{
public:
  virtual const std::type_info& info() =0;
  const char* infoString() { return info().name();} // for easy gdb access
  /// @return the serialization signature used by this type.
  virtual std::string signature()=0;

  virtual void* clone(void*)=0;
  virtual void destroy(void*)=0;

  virtual bool  toValue(const void*, qi::detail::DynamicValue&)=0;
  virtual void* fromValue(const qi::detail::DynamicValue&)=0;

  // Default impl does toValue.serialize()
  virtual void  serialize(ODataStream& s, const void*)=0;
  // Default impl does deserialize(Value&) then fromValue
  virtual void* deserialize(IDataStream& s)=0;

  /* When someone makes a call with arguments that do not match the
   * target signature (ex: int vs float), we want to handle it.
   * For this, given the known correct signature S and known incorrect
   * Value v, we want to be able to obtain a new Type T that
   * serializes with type S, and then try to convert o into type T.
   *
   * For this we need a map<Signature, Type> that we will feed with
   * known types.
   *
   */
  typedef std::map<std::string, Type*> TypeSignatureMap;
  static TypeSignatureMap& typeSignatureMap()
  {
    static TypeSignatureMap res;
    return res;
  }

  static Type* getCompatibleTypeWithSignature(const std::string& sig)
  {
    TypeSignatureMap::iterator i = typeSignatureMap().find(sig);
    if (i == typeSignatureMap().end())
      return 0;
    else
      return i->second;
  }

  static bool registerCompatibleType(const std::string& sig,
    Type* mt)
  {
    typeSignatureMap()[sig] = mt;
    return true;
  }

  #define QI_REGISTER_MAPPING(sig, type) \
  static bool BOOST_PP_CAT(_qireg_map_ , __LINE__) = ::qi::Type::registerCompatibleType(sig, \
    ::qi::typeOf<type>());
};

/** Meta-type specialization.
 *  Use the aspect pattern, make a class per feature group
 *  (Clone, Value, Serialize)
 *
 */

template<typename T> class TypeDefaultClone
{
public:
  void* clone(void* src)
  {
    return new T(*(T*)src);
  }

  void destroy(void* ptr)
  {
    delete (T*)ptr;
  }
};

template<typename T> class TypeNoClone
{
public:
  void* clone(void* src)
  {
    return src;
  }

  void destroy(void* ptr)
  {
    /* Assume a TypeNoClone is not serializable
     * So it cannot have been allocated by us.
     * So the destroy comes after a clone->ignore it
     */
  }
};

template<typename T>class TypeDefaultValue
{
public:
  bool toValue(const void* ptr, qi::detail::DynamicValue& val)
  {
    detail::DynamicValueConverter<T>::writeDynamicValue(*(T*)ptr, val);
    return true;
  }

  void* fromValue(const qi::detail::DynamicValue& val)
  {
    T* res = new T();
    detail::DynamicValueConverter<T>::readDynamicValue(val, *res);
    return res;
  }
};

template<typename T>class TypeNoValue
{
public:
  bool toValue(const void* ptr, qi::detail::DynamicValue& val)
  {
    qiLogWarning("qi.type") << "toValue not implemented for type ";
    return false;
  }

  void* fromValue(const qi::detail::DynamicValue& val)
  {
    qiLogWarning("qi.type") << "fromValue not implemented for type ";
    T* res = new T();
    return res;
  }
};

template<typename T> class TypeDefaultSerialize
{
public:
  void  serialize(ODataStream& s, const void* ptr)
  {
    s << *(T*)ptr;
  }

  void* deserialize(IDataStream& s)
  {
    T* val = new T();
    s >> *val;
    return val;
  }
  std::string signature()
  {
    return signatureFromType<T>::value();
  }
};

template<typename T> class TypeNoSerialize
{
public:
  void serialize(ODataStream& s, const void* ptr)
  {
    qiLogWarning("qi.meta") << "type not serializable";
  }

  void* deserialize(IDataStream& s)
  {
    qiLogWarning("qi.meta") << "type not serializable";
    T* val = new T();
    return val;
  }
  std::string signature()
  {
    std::string res;
    res += (char)Signature::Type_Unknown;
    return res;
  }
};

/* TypeImpl implementation that bounces to the various aspect
 * subclasses.
 *
 * That way we can split the various aspects in different classes
 * for better reuse, without the cost of a second virtual call.
 */
template<typename T, typename Cloner    = TypeDefaultClone<T>
                   , typename Value     = TypeNoValue<T>
                   , typename Serialize = TypeNoSerialize<T>
         > class DefaultTypeImpl
: public Cloner
, public Value
, public Serialize
, public virtual Type
{
  virtual const std::type_info& info()
  {
    static T v; return typeid(v);
  }

  virtual void* clone(void* src)
  {
    return Cloner::clone(src);
  }

  virtual void destroy(void* ptr)
  {
    Cloner::destroy(ptr);
  }

  virtual bool toValue(const void* ptr, qi::detail::DynamicValue& val)
  {
    return Value::toValue(ptr, val);
  }

  virtual void* fromValue(const qi::detail::DynamicValue& val)
  {
    return Value::fromValue(val);
  }

  virtual std::string signature()
  {
    return Serialize::signature();
  }

  virtual void  serialize(ODataStream& s, const void* ptr)
  {
    Serialize::serialize(s, ptr);
  }

  virtual void* deserialize(IDataStream& s)
  {
    return Serialize::deserialize(s);
  }
};

/* Type "factory". Specialize this class to provide a custom
 * Type for a given type.
 */
template<typename T> class TypeImpl: public virtual DefaultTypeImpl<T>
{
};

/// Declare a type that is convertible to Value, and serializable
#define QI_TYPE_CONVERTIBLE_SERIALIZABLE(T)  \
namespace qi {                                   \
template<> class TypeImpl<T>:                \
  public DefaultTypeImpl<T,                  \
    TypeDefaultClone<T>,                     \
    TypeDefaultValue<T>,                     \
    TypeDefaultSerialize<T>                  \
  >{}; }

/** Declare that a type is not convertible to Value.
 *  Must be called outside any namespace.
 */
#define QI_TYPE_SERIALIZABLE(T)              \
namespace qi {                                   \
template<> class TypeImpl<T>:                \
  public DefaultTypeImpl<T,                  \
    TypeDefaultClone<T>,                     \
    TypeNoValue<T>,                          \
    TypeDefaultSerialize<T>                  \
  >{}; }

/// Declare that a type has no metatype and cannot be used in a Value
#define QI_NO_TYPE(T) namespace qi {template<> class TypeImpl<T> {};}

/// Get type from a type. No need to delete the result
template<typename T> Type* typeOf()
{
  static TypeImpl<typename boost::remove_const<T>::type> res;
  return &res;
}

/// Get type from a value. No need to delete the result
template<typename T> Type* typeOf(const T& v)
{
  return typeOf<T>();
}

}

QI_TYPE_SERIALIZABLE(Buffer);

#include <qimessaging/details/type.hxx>

#endif
<|endoftext|>


<commit_before>/*****************************************************************************/
/* RootHandler.cpp                        Copyright (c) Ladislav Zezula 2015 */
/*---------------------------------------------------------------------------*/
/* Implementation of root handler                                            */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 09.03.15  1.00  Lad  Created                                              */
/*****************************************************************************/

#define __CASCLIB_SELF__
#include "../CascLib.h"
#include "../CascCommon.h"

//-----------------------------------------------------------------------------
// Common support

int RootHandler_Insert(TRootHandler * pRootHandler, const char * szFileName, LPBYTE pbEncodingKey)
{
    if(pRootHandler == NULL || pRootHandler->Insert == NULL)
        return ERROR_NOT_SUPPORTED;

    return pRootHandler->Insert(pRootHandler, szFileName, pbEncodingKey);
}

LPBYTE RootHandler_Search(TRootHandler * pRootHandler, struct _TCascSearch * pSearch, PDWORD PtrFileSize, PDWORD PtrLocaleFlags, PDWORD PtrFileDataId)
{
    // Check if the root structure is valid at all
    if(pRootHandler == NULL)
        return NULL;

    return pRootHandler->Search(pRootHandler, pSearch, PtrFileSize, PtrLocaleFlags, PtrFileDataId);
}

void RootHandler_EndSearch(TRootHandler * pRootHandler, struct _TCascSearch * pSearch)
{
    // Check if the root structure is valid at all
    if(pRootHandler != NULL)
    {
        pRootHandler->EndSearch(pRootHandler, pSearch);
    }
}

LPBYTE RootHandler_GetKey(TRootHandler * pRootHandler, const char * szFileName)
{
    // Check if the root structure is valid at all
    if(pRootHandler == NULL)
        return NULL;

    return pRootHandler->GetKey(pRootHandler, szFileName);
}

void RootHandler_Dump(TCascStorage * hs, LPBYTE pbRootHandler, DWORD cbRootHandler, const TCHAR * szNameFormat, const TCHAR * szListFile, int nDumpLevel)
{
    TDumpContext * dc;

    // Only if the ROOT provider suports the dump option
    if(hs->pRootHandler != NULL && hs->pRootHandler->Dump != NULL)
    {
        // Create the dump file
        dc = CreateDumpContext(hs, szNameFormat);
        if(dc != NULL)
        {
            // Dump the content and close the file
            hs->pRootHandler->Dump(hs, dc, pbRootHandler, cbRootHandler, szListFile, nDumpLevel);
            dump_close(dc);
        }
    }
}

void RootHandler_Close(TRootHandler * pRootHandler)
{
    // Check if the root structure is allocated at all
    if(pRootHandler != NULL)
    {
        pRootHandler->Close(pRootHandler);
    }
}

DWORD RootHandler_GetFileId(TRootHandler * pRootHandler, const char * szFileName)
{
    // Check if the root structure is valid at all
    if(pRootHandler == NULL)
        return 0;

    return pRootHandler->GetFileId(pRootHandler, szFileName);
}

<commit_msg>+ Fixed for WoW 7.3<commit_after>/*****************************************************************************/
/* RootHandler.cpp                        Copyright (c) Ladislav Zezula 2015 */
/*---------------------------------------------------------------------------*/
/* Implementation of root handler                                            */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 09.03.15  1.00  Lad  Created                                              */
/*****************************************************************************/

#define __CASCLIB_SELF__
#include "../CascLib.h"
#include "../CascCommon.h"

//-----------------------------------------------------------------------------
// Common support

int RootHandler_Insert(TRootHandler * pRootHandler, const char * szFileName, LPBYTE pbEncodingKey)
{
    if(pRootHandler == NULL || pRootHandler->Insert == NULL || pbEncodingKey == NULL)
        return ERROR_NOT_SUPPORTED;

    return pRootHandler->Insert(pRootHandler, szFileName, pbEncodingKey);
}

LPBYTE RootHandler_Search(TRootHandler * pRootHandler, struct _TCascSearch * pSearch, PDWORD PtrFileSize, PDWORD PtrLocaleFlags, PDWORD PtrFileDataId)
{
    // Check if the root structure is valid at all
    if(pRootHandler == NULL)
        return NULL;

    return pRootHandler->Search(pRootHandler, pSearch, PtrFileSize, PtrLocaleFlags, PtrFileDataId);
}

void RootHandler_EndSearch(TRootHandler * pRootHandler, struct _TCascSearch * pSearch)
{
    // Check if the root structure is valid at all
    if(pRootHandler != NULL)
    {
        pRootHandler->EndSearch(pRootHandler, pSearch);
    }
}

LPBYTE RootHandler_GetKey(TRootHandler * pRootHandler, const char * szFileName)
{
    // Check if the root structure is valid at all
    if(pRootHandler == NULL)
        return NULL;

    return pRootHandler->GetKey(pRootHandler, szFileName);
}

void RootHandler_Dump(TCascStorage * hs, LPBYTE pbRootHandler, DWORD cbRootHandler, const TCHAR * szNameFormat, const TCHAR * szListFile, int nDumpLevel)
{
    TDumpContext * dc;

    // Only if the ROOT provider suports the dump option
    if(hs->pRootHandler != NULL && hs->pRootHandler->Dump != NULL)
    {
        // Create the dump file
        dc = CreateDumpContext(hs, szNameFormat);
        if(dc != NULL)
        {
            // Dump the content and close the file
            hs->pRootHandler->Dump(hs, dc, pbRootHandler, cbRootHandler, szListFile, nDumpLevel);
            dump_close(dc);
        }
    }
}

void RootHandler_Close(TRootHandler * pRootHandler)
{
    // Check if the root structure is allocated at all
    if(pRootHandler != NULL)
    {
        pRootHandler->Close(pRootHandler);
    }
}

DWORD RootHandler_GetFileId(TRootHandler * pRootHandler, const char * szFileName)
{
    // Check if the root structure is valid at all
    if(pRootHandler == NULL)
        return 0;

    return pRootHandler->GetFileId(pRootHandler, szFileName);
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions Inc. 1990-2013.  All rights reserved
 */
//      TEST    Foundation::Containers::Mapping
//      STATUS  Alpha-Late
#include    "Stroika/Foundation/StroikaPreComp.h"

#include    <iostream>
#include    <sstream>

#include    "Stroika/Foundation/Containers/Mapping.h"
#include    "Stroika/Foundation/Containers/Concrete/Mapping_Array.h"
#include    "Stroika/Foundation/Containers/Concrete/Mapping_LinkedList.h"
#include    "Stroika/Foundation/Containers/Concrete/Mapping_stdmap.h"
#include    "Stroika/Foundation/Debug/Assertions.h"
#include    "Stroika/Foundation/Debug/Trace.h"

#include    "../TestCommon/CommonTests_Mapping.h"
#include    "../TestHarness/SimpleClass.h"
#include    "../TestHarness/TestHarness.h"

#include    "Stroika/Foundation/Containers/Concrete/SortedMapping_stdmap.h"

using   namespace   Stroika;
using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;

using   Concrete::Mapping_Array;
using   Concrete::Mapping_LinkedList;
using   Concrete::Mapping_stdmap;

namespace {
    template    <typename   CONCRETE_CONTAINER>
    void    DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_ ()
    {
        typedef typename CONCRETE_CONTAINER::KeyType                        KeyType;
        typedef typename CONCRETE_CONTAINER::ValueType                      ValueType;
        typedef typename CONCRETE_CONTAINER::TraitsType::MappingTraitsType  MappingTraitsType;
        auto extraChecksFunction = [](const Mapping<KeyType, ValueType, MappingTraitsType>& m) {
            // only work todo on sorted mappings
        };
        CommonTests::MappingTests::SimpleMappingTest_AllTestsWhichDontRequireComparer_For_Type_<CONCRETE_CONTAINER> (extraChecksFunction);
    }
    template    <typename   CONCRETE_CONTAINER>
    void    DoTestForConcreteContainer_ ()
    {
        typedef typename CONCRETE_CONTAINER::KeyType                        KeyType;
        typedef typename CONCRETE_CONTAINER::ValueType                      ValueType;
        typedef typename CONCRETE_CONTAINER::TraitsType::MappingTraitsType  MappingTraitsType;
        auto extraChecksFunction = [](const Mapping<KeyType, ValueType, MappingTraitsType>& m) {
            // only work todo on sorted mappings
        };
        CommonTests::MappingTests::SimpleMappingTest_All_For_Type<CONCRETE_CONTAINER> (extraChecksFunction);
    }
}

namespace {
    void    Test2_SimpleBaseClassConversionTraitsConfusion_ ()
    {
#if 1
        /// SERIOUS BUG - WITH HOW I DID BASE CLASS FOR Mapping_stdmap<> -.... second line needs to work!!!
        SortedMapping<int, float> xxxyy = Concrete::SortedMapping_stdmap<int, float> ();
        Mapping<int, float> xxxyy1 = Concrete::Mapping_stdmap<int, float> ();
#endif
    }
}

namespace   {
    void    DoRegressionTests_ ()
    {
        struct  MySimpleClassWithoutComparisonOperators_ComparerWithEquals_ {
            typedef SimpleClassWithoutComparisonOperators ElementType;
            static  bool    Equals (ElementType v1, ElementType v2) {
                return v1.GetValue () == v2.GetValue ();
            }
        };
        typedef Mapping_DefaultTraits <
        SimpleClassWithoutComparisonOperators,
        SimpleClassWithoutComparisonOperators,
        MySimpleClassWithoutComparisonOperators_ComparerWithEquals_,
        MySimpleClassWithoutComparisonOperators_ComparerWithEquals_
        >   SimpleClassWithoutComparisonOperators_MappingTRAITS;

        DoTestForConcreteContainer_<Mapping<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_MappingTRAITS>> ();

        DoTestForConcreteContainer_<Mapping_Array<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping_Array<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping_Array<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_MappingTRAITS>> ();

        DoTestForConcreteContainer_<Mapping_LinkedList<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping_LinkedList<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping_LinkedList<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_MappingTRAITS>> ();

        DoTestForConcreteContainer_<Mapping_stdmap<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping_stdmap<SimpleClass, SimpleClass>> ();
        {
            struct  MySimpleClassWithoutComparisonOperators_ComparerWithCompare_ : MySimpleClassWithoutComparisonOperators_ComparerWithEquals_ {
                typedef SimpleClassWithoutComparisonOperators ElementType;
                static  int    Compare (ElementType v1, ElementType v2) {
                    return v1.GetValue () - v2.GetValue ();
                }
            };
            typedef Concrete::Mapping_stdmap_DefaultTraits <
            SimpleClassWithoutComparisonOperators,
            SimpleClassWithoutComparisonOperators,
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_,
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_,
            MySimpleClassWithoutComparisonOperators_ComparerWithCompare_
            >   SimpleClassWithoutComparisonOperators_Mapping_stdmap_TRAITS;
            DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping_stdmap<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_Mapping_stdmap_TRAITS>> ();
        }

        Test2_SimpleBaseClassConversionTraitsConfusion_ ();
    }
}

int     main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
    return EXIT_SUCCESS;
}
<commit_msg>minor cleanup of mapping regtest - Test2_SimpleBaseClassConversionTraitsConfusion_ - since this now works<commit_after>/*
 * Copyright(c) Sophist Solutions Inc. 1990-2013.  All rights reserved
 */
//      TEST    Foundation::Containers::Mapping
//      STATUS  Alpha-Late
#include    "Stroika/Foundation/StroikaPreComp.h"

#include    <iostream>
#include    <sstream>

#include    "Stroika/Foundation/Containers/Mapping.h"
#include    "Stroika/Foundation/Containers/Concrete/Mapping_Array.h"
#include    "Stroika/Foundation/Containers/Concrete/Mapping_LinkedList.h"
#include    "Stroika/Foundation/Containers/Concrete/Mapping_stdmap.h"
#include    "Stroika/Foundation/Debug/Assertions.h"
#include    "Stroika/Foundation/Debug/Trace.h"

#include    "../TestCommon/CommonTests_Mapping.h"
#include    "../TestHarness/SimpleClass.h"
#include    "../TestHarness/TestHarness.h"

#include    "Stroika/Foundation/Containers/Concrete/SortedMapping_stdmap.h"

using   namespace   Stroika;
using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;

using   Concrete::Mapping_Array;
using   Concrete::Mapping_LinkedList;
using   Concrete::Mapping_stdmap;

namespace {
    template    <typename   CONCRETE_CONTAINER>
    void    DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_ ()
    {
        typedef typename CONCRETE_CONTAINER::KeyType                        KeyType;
        typedef typename CONCRETE_CONTAINER::ValueType                      ValueType;
        typedef typename CONCRETE_CONTAINER::TraitsType::MappingTraitsType  MappingTraitsType;
        auto extraChecksFunction = [](const Mapping<KeyType, ValueType, MappingTraitsType>& m) {
            // only work todo on sorted mappings
        };
        CommonTests::MappingTests::SimpleMappingTest_AllTestsWhichDontRequireComparer_For_Type_<CONCRETE_CONTAINER> (extraChecksFunction);
    }
    template    <typename   CONCRETE_CONTAINER>
    void    DoTestForConcreteContainer_ ()
    {
        typedef typename CONCRETE_CONTAINER::KeyType                        KeyType;
        typedef typename CONCRETE_CONTAINER::ValueType                      ValueType;
        typedef typename CONCRETE_CONTAINER::TraitsType::MappingTraitsType  MappingTraitsType;
        auto extraChecksFunction = [](const Mapping<KeyType, ValueType, MappingTraitsType>& m) {
            // only work todo on sorted mappings
        };
        CommonTests::MappingTests::SimpleMappingTest_All_For_Type<CONCRETE_CONTAINER> (extraChecksFunction);
    }
}

namespace {
    void    Test2_SimpleBaseClassConversionTraitsConfusion_ ()
    {
        SortedMapping<int, float> xxxyy = Concrete::SortedMapping_stdmap<int, float> ();
        Mapping<int, float> xxxyy1 = Concrete::Mapping_stdmap<int, float> ();
    }
}

namespace   {
    void    DoRegressionTests_ ()
    {
        struct  MySimpleClassWithoutComparisonOperators_ComparerWithEquals_ {
            typedef SimpleClassWithoutComparisonOperators ElementType;
            static  bool    Equals (ElementType v1, ElementType v2) {
                return v1.GetValue () == v2.GetValue ();
            }
        };
        typedef Mapping_DefaultTraits <
        SimpleClassWithoutComparisonOperators,
        SimpleClassWithoutComparisonOperators,
        MySimpleClassWithoutComparisonOperators_ComparerWithEquals_,
        MySimpleClassWithoutComparisonOperators_ComparerWithEquals_
        >   SimpleClassWithoutComparisonOperators_MappingTRAITS;

        DoTestForConcreteContainer_<Mapping<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_MappingTRAITS>> ();

        DoTestForConcreteContainer_<Mapping_Array<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping_Array<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping_Array<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_MappingTRAITS>> ();

        DoTestForConcreteContainer_<Mapping_LinkedList<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping_LinkedList<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping_LinkedList<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_MappingTRAITS>> ();

        DoTestForConcreteContainer_<Mapping_stdmap<size_t, size_t>> ();
        DoTestForConcreteContainer_<Mapping_stdmap<SimpleClass, SimpleClass>> ();
        {
            struct  MySimpleClassWithoutComparisonOperators_ComparerWithCompare_ : MySimpleClassWithoutComparisonOperators_ComparerWithEquals_ {
                typedef SimpleClassWithoutComparisonOperators ElementType;
                static  int    Compare (ElementType v1, ElementType v2) {
                    return v1.GetValue () - v2.GetValue ();
                }
            };
            typedef Concrete::Mapping_stdmap_DefaultTraits <
            SimpleClassWithoutComparisonOperators,
            SimpleClassWithoutComparisonOperators,
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_,
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_,
            MySimpleClassWithoutComparisonOperators_ComparerWithCompare_
            >   SimpleClassWithoutComparisonOperators_Mapping_stdmap_TRAITS;
            DoTestForConcreteContainer_AllTestsWhichDontRequireComparer_For_Type_<Mapping_stdmap<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators_Mapping_stdmap_TRAITS>> ();
        }

        Test2_SimpleBaseClassConversionTraitsConfusion_ ();
    }
}

int     main (int argc, const char* argv[])
{
    Stroika::TestHarness::Setup ();
    Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2020.  All rights reserved
 */
//  TEST    Foundation::Containers::SortedMapping
//      STATUS  Alpha-Late
#include "Stroika/Foundation/StroikaPreComp.h"

#include <iostream>
#include <sstream>

#include "Stroika/Foundation/Containers/Concrete/SortedMapping_stdmap.h"
#include "Stroika/Foundation/Containers/SortedMapping.h"
#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Memory/Optional.h"

#include "../TestCommon/CommonTests_Mapping.h"
#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;

using Concrete::SortedMapping_stdmap;

namespace {
    template <typename CONCRETE_CONTAINER>
    void DoTestForConcreteContainer_ ()
    {
        using namespace CommonTests::MappingTests;
        auto testSchema                      = DEFAULT_TESTING_SCHEMA<CONCRETE_CONTAINER>{};
        testSchema.ApplyToContainerExtraTest = [] (const typename CONCRETE_CONTAINER::ArchetypeContainerType& m) {
            // verify in sorted order
            using value_type = typename CONCRETE_CONTAINER::value_type;
            optional<value_type> last;
            for (value_type i : m) {
                if (last.has_value ()) {
                    VerifyTestResult (Common::ThreeWayComparerAdapter (m.GetInOrderKeyComparer ()) (last->fKey, i.fKey) <= 0);
                }
                last = i;
            }
        };
        SimpleMappingTest_All_ (testSchema);
        SimpleMappingTest_WithDefaultEqCompaerer_ (testSchema);
    }
    template <typename CONCRETE_CONTAINER, typename FACTORY, typename VALUE_EQUALS_COMPARER_TYPE>
    void DoTestForConcreteContainer_ (FACTORY factory, VALUE_EQUALS_COMPARER_TYPE valueEqualsComparer)
    {
        using namespace CommonTests::MappingTests;
        auto testSchema                      = DEFAULT_TESTING_SCHEMA<CONCRETE_CONTAINER, FACTORY, VALUE_EQUALS_COMPARER_TYPE>{factory, valueEqualsComparer};
        testSchema.ApplyToContainerExtraTest = [] (const typename CONCRETE_CONTAINER::ArchetypeContainerType& m) {
            // verify in sorted order
            using value_type = typename CONCRETE_CONTAINER::value_type;
            optional<value_type> last;
            for (value_type i : m) {
                if (last.has_value ()) {
                    VerifyTestResult (Common::ThreeWayComparerAdapter (m.GetInOrderKeyComparer ()) (last->fKey, i.fKey) <= 0);
                }
                last = i;
            }
        };
        SimpleMappingTest_All_ (testSchema);
    }
}

namespace {
    namespace Test3_ConvertMapping2SortedMapping {
        void TestAll ()
        {
            Mapping<int, int>       m{pair<int, int>{1, 2}, pair<int, int>{2, 4}};
            SortedMapping<int, int> ms{m};
            VerifyTestResult (ms.size () == 2);
            VerifyTestResult ((*ms.begin () == pair<int, int>{1, 2}));
        }
    }
}

namespace {
    void DoRegressionTests_ ()
    {
        struct MySimpleClassWithoutComparisonOperators_ComparerWithEquals_ : Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eEquals> {
            using value_type = SimpleClassWithoutComparisonOperators;
            bool operator() (const value_type& v1, const value_type& v2) const
            {
                return v1.GetValue () == v2.GetValue ();
            }
        };
        struct MySimpleClassWithoutComparisonOperators_ComparerWithLess_ : Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eStrictInOrder> {
            using value_type = SimpleClassWithoutComparisonOperators;
            bool operator() (const value_type& v1, const value_type& v2) const
            {
                return v1.GetValue () < v2.GetValue ();
            }
        };

        DoTestForConcreteContainer_<SortedMapping<size_t, size_t>> ();
        DoTestForConcreteContainer_<SortedMapping<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_<SortedMapping<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators>> (
            [] () { return SortedMapping<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators> (MySimpleClassWithoutComparisonOperators_ComparerWithLess_{}); },
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_{});

        DoTestForConcreteContainer_<SortedMapping_stdmap<size_t, size_t>> ();
        DoTestForConcreteContainer_<SortedMapping_stdmap<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_<SortedMapping_stdmap<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators>> (
            [] () { return SortedMapping_stdmap<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators> (MySimpleClassWithoutComparisonOperators_ComparerWithLess_{}); },
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_{});

        Test3_ConvertMapping2SortedMapping::TestAll ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<commit_msg>tweak new regression test added<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2020.  All rights reserved
 */
//  TEST    Foundation::Containers::SortedMapping
//      STATUS  Alpha-Late
#include "Stroika/Foundation/StroikaPreComp.h"

#include <iostream>
#include <sstream>

#include "Stroika/Foundation/Containers/Concrete/SortedMapping_stdmap.h"
#include "Stroika/Foundation/Containers/SortedMapping.h"
#include "Stroika/Foundation/Debug/Assertions.h"
#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Memory/Optional.h"

#include "../TestCommon/CommonTests_Mapping.h"
#include "../TestHarness/SimpleClass.h"
#include "../TestHarness/TestHarness.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Containers;

using Concrete::SortedMapping_stdmap;

namespace {
    template <typename CONCRETE_CONTAINER>
    void DoTestForConcreteContainer_ ()
    {
        using namespace CommonTests::MappingTests;
        auto testSchema                      = DEFAULT_TESTING_SCHEMA<CONCRETE_CONTAINER>{};
        testSchema.ApplyToContainerExtraTest = [] (const typename CONCRETE_CONTAINER::ArchetypeContainerType& m) {
            // verify in sorted order
            using value_type = typename CONCRETE_CONTAINER::value_type;
            optional<value_type> last;
            for (value_type i : m) {
                if (last.has_value ()) {
                    VerifyTestResult (Common::ThreeWayComparerAdapter (m.GetInOrderKeyComparer ()) (last->fKey, i.fKey) <= 0);
                }
                last = i;
            }
        };
        SimpleMappingTest_All_ (testSchema);
        SimpleMappingTest_WithDefaultEqCompaerer_ (testSchema);
    }
    template <typename CONCRETE_CONTAINER, typename FACTORY, typename VALUE_EQUALS_COMPARER_TYPE>
    void DoTestForConcreteContainer_ (FACTORY factory, VALUE_EQUALS_COMPARER_TYPE valueEqualsComparer)
    {
        using namespace CommonTests::MappingTests;
        auto testSchema                      = DEFAULT_TESTING_SCHEMA<CONCRETE_CONTAINER, FACTORY, VALUE_EQUALS_COMPARER_TYPE>{factory, valueEqualsComparer};
        testSchema.ApplyToContainerExtraTest = [] (const typename CONCRETE_CONTAINER::ArchetypeContainerType& m) {
            // verify in sorted order
            using value_type = typename CONCRETE_CONTAINER::value_type;
            optional<value_type> last;
            for (value_type i : m) {
                if (last.has_value ()) {
                    VerifyTestResult (Common::ThreeWayComparerAdapter (m.GetInOrderKeyComparer ()) (last->fKey, i.fKey) <= 0);
                }
                last = i;
            }
        };
        SimpleMappingTest_All_ (testSchema);
    }
}

namespace {
    namespace Test3_ConvertMapping2SortedMapping {
        void TestAll ()
        {
            Mapping<int, int>       m{pair<int, int>{1, 2}, pair<int, int>{2, 4}};
            SortedMapping<int, int> ms{m};
            VerifyTestResult (ms.size () == 2);
#if __cpp_impl_three_way_comparison >= 201907
            VerifyTestResult ((*ms.begin () == pair<int, int>{1, 2}));
#endif
        }
    }
}

namespace {
    void DoRegressionTests_ ()
    {
        struct MySimpleClassWithoutComparisonOperators_ComparerWithEquals_ : Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eEquals> {
            using value_type = SimpleClassWithoutComparisonOperators;
            bool operator() (const value_type& v1, const value_type& v2) const
            {
                return v1.GetValue () == v2.GetValue ();
            }
        };
        struct MySimpleClassWithoutComparisonOperators_ComparerWithLess_ : Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eStrictInOrder> {
            using value_type = SimpleClassWithoutComparisonOperators;
            bool operator() (const value_type& v1, const value_type& v2) const
            {
                return v1.GetValue () < v2.GetValue ();
            }
        };

        DoTestForConcreteContainer_<SortedMapping<size_t, size_t>> ();
        DoTestForConcreteContainer_<SortedMapping<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_<SortedMapping<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators>> (
            [] () { return SortedMapping<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators> (MySimpleClassWithoutComparisonOperators_ComparerWithLess_{}); },
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_{});

        DoTestForConcreteContainer_<SortedMapping_stdmap<size_t, size_t>> ();
        DoTestForConcreteContainer_<SortedMapping_stdmap<SimpleClass, SimpleClass>> ();
        DoTestForConcreteContainer_<SortedMapping_stdmap<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators>> (
            [] () { return SortedMapping_stdmap<SimpleClassWithoutComparisonOperators, SimpleClassWithoutComparisonOperators> (MySimpleClassWithoutComparisonOperators_ComparerWithLess_{}); },
            MySimpleClassWithoutComparisonOperators_ComparerWithEquals_{});

        Test3_ConvertMapping2SortedMapping::TestAll ();
    }
}

int main ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
{
    Stroika::TestHarness::Setup ();
    return Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
}
<|endoftext|>


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

#include <fstream>
#include "itkGrayscaleMorphologicalOpeningImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkTextOutput.h"
#include "itkSimpleFilterWatcher.h"
#include "itkFlatStructuringElement.h"

int
itkGrayscaleMorphologicalOpeningImageFilterTest2(int ac, char * av[])
{
  // Comment the following if you want to use the itk text output window
  itk::OutputWindow::SetInstance(itk::TextOutput::New());

  if (ac < 7)
  {
    std::cerr << "Usage: " << av[0] << " InputImage BASIC HISTO ANCHOR VHGW SafeBorder" << std::endl;
    return -1;
  }

  unsigned int const dim = 2;
  using ImageType = itk::Image<unsigned char, dim>;

  using ReaderType = itk::ImageFileReader<ImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(av[1]);

  // Create a filter
  using SRType = itk::FlatStructuringElement<dim>;
  using FilterType = itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, SRType>;
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(reader->GetOutput());

  itk::SimpleFilterWatcher watcher(filter, "filter");

  using RadiusType = FilterType::RadiusType;

  // test default values
  RadiusType r1;
  r1.Fill(1);
  if (filter->GetRadius() != r1)
  {
    std::cerr << "Wrong default Radius: " << filter->GetRadius() << std::endl;
    return EXIT_FAILURE;
  }

  if (filter->GetAlgorithm() != FilterType::HISTO)
  {
    std::cerr << "Wrong default algorithm." << std::endl;
    return EXIT_FAILURE;
  }

  if (filter->GetSafeBorder() != true)
  {
    std::cerr << "Wrong default safe border." << std::endl;
    return EXIT_FAILURE;
  }

  try
  {
    filter->SetRadius(20);
    filter->SetSafeBorder(std::stoi(av[6]));

    using WriterType = itk::ImageFileWriter<ImageType>;
    WriterType::Pointer writer = WriterType::New();
    writer->SetInput(filter->GetOutput());

    filter->SetAlgorithm(FilterType::BASIC);
    writer->SetFileName(av[2]);
    writer->Update();

    filter->SetAlgorithm(FilterType::HISTO);
    writer->SetFileName(av[3]);
    writer->Update();

    filter->SetAlgorithm(FilterType::ANCHOR);
    writer->SetFileName(av[4]);
    writer->Update();

    filter->SetAlgorithm(FilterType::VHGW);
    writer->SetFileName(av[5]);
    writer->Update();
  }
  catch (const itk::ExceptionObject & e)
  {
    std::cerr << "Exception detected: " << e.GetDescription();
    return EXIT_FAILURE;
  }

  // Generate test image
  using WriterType = itk::ImageFileWriter<ImageType>;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput(filter->GetOutput());
  writer->SetFileName(av[2]);
  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>BUG: Fix math morphology strongly typed `enum` scope-resolution<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <fstream>
#include "itkGrayscaleMorphologicalOpeningImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkTextOutput.h"
#include "itkSimpleFilterWatcher.h"
#include "itkFlatStructuringElement.h"

int
itkGrayscaleMorphologicalOpeningImageFilterTest2(int ac, char * av[])
{
  // Comment the following if you want to use the itk text output window
  itk::OutputWindow::SetInstance(itk::TextOutput::New());

  if (ac < 7)
  {
    std::cerr << "Usage: " << av[0] << " InputImage BASIC HISTO ANCHOR VHGW SafeBorder" << std::endl;
    return -1;
  }

  unsigned int const dim = 2;
  using ImageType = itk::Image<unsigned char, dim>;

  using ReaderType = itk::ImageFileReader<ImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(av[1]);

  // Create a filter
  using SRType = itk::FlatStructuringElement<dim>;
  using FilterType = itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, SRType>;
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(reader->GetOutput());

  itk::SimpleFilterWatcher watcher(filter, "filter");

  using RadiusType = FilterType::RadiusType;

  // test default values
  RadiusType r1;
  r1.Fill(1);
  if (filter->GetRadius() != r1)
  {
    std::cerr << "Wrong default Radius: " << filter->GetRadius() << std::endl;
    return EXIT_FAILURE;
  }

  if (filter->GetAlgorithm() != FilterType::AlgorithmEnum::HISTO)
  {
    std::cerr << "Wrong default algorithm." << std::endl;
    return EXIT_FAILURE;
  }

  if (filter->GetSafeBorder() != true)
  {
    std::cerr << "Wrong default safe border." << std::endl;
    return EXIT_FAILURE;
  }

  try
  {
    filter->SetRadius(20);
    filter->SetSafeBorder(std::stoi(av[6]));

    using WriterType = itk::ImageFileWriter<ImageType>;
    WriterType::Pointer writer = WriterType::New();
    writer->SetInput(filter->GetOutput());

    filter->SetAlgorithm(FilterType::AlgorithmEnum::BASIC);
    writer->SetFileName(av[2]);
    writer->Update();

    filter->SetAlgorithm(FilterType::AlgorithmEnum::HISTO);
    writer->SetFileName(av[3]);
    writer->Update();

    filter->SetAlgorithm(FilterType::AlgorithmEnum::ANCHOR);
    writer->SetFileName(av[4]);
    writer->Update();

    filter->SetAlgorithm(FilterType::AlgorithmEnum::VHGW);
    writer->SetFileName(av[5]);
    writer->Update();
  }
  catch (const itk::ExceptionObject & e)
  {
    std::cerr << "Exception detected: " << e.GetDescription();
    return EXIT_FAILURE;
  }

  // Generate test image
  using WriterType = itk::ImageFileWriter<ImageType>;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput(filter->GetOutput());
  writer->SetFileName(av[2]);
  writer->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>