<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkString.h"
#include "SkShader.h"

class RectBench : public SkBenchmark {
public:
    int fShift, fStroke;
    enum {
        W = 640,
        H = 480,
        N = SkBENCHLOOP(300)
    };
    SkRect  fRects[N];
    SkColor fColors[N];

    RectBench(void* param, int shift, int stroke = 0)
        : INHERITED(param)
        , fShift(shift)
        , fStroke(stroke) {
        SkRandom rand;
        const SkScalar offset = SK_Scalar1/3;
        for (int i = 0; i < N; i++) {
            int x = rand.nextU() % W;
            int y = rand.nextU() % H;
            int w = rand.nextU() % W;
            int h = rand.nextU() % H;
            w >>= shift;
            h >>= shift;
            x -= w/2;
            y -= h/2;
            fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
                          SkIntToScalar(x+w), SkIntToScalar(y+h));
            fRects[i].offset(offset, offset);
            fColors[i] = rand.nextU() | 0xFF808080;
        }
    }

    SkString fName;
    const char* computeName(const char root[]) {
        fName.printf("%s_%d", root, fShift);
        if (fStroke > 0) {
            fName.appendf("_stroke_%d", fStroke);
        }
        return fName.c_str();
    }

protected:
    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawRect(r, p);
    }

    virtual const char* onGetName() { return computeName("rects"); }
    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        if (fStroke > 0) {
            paint.setStyle(SkPaint::kStroke_Style);
            paint.setStrokeWidth(SkIntToScalar(fStroke));
        }
        for (int i = 0; i < N; i++) {
            paint.setColor(fColors[i]);
            this->setupPaint(&paint);
            this->drawThisRect(canvas, fRects[i], paint);
        }
    }
private:
    typedef SkBenchmark INHERITED;
};

class SrcModeRectBench : public RectBench {
public:
    SrcModeRectBench(void* param) : INHERITED(param, 1, 0) {
        fMode = SkXfermode::Create(SkXfermode::kSrc_Mode);
    }

    virtual ~SrcModeRectBench() {
        SkSafeUnref(fMode);
    }

protected:
    virtual void setupPaint(SkPaint* paint) SK_OVERRIDE {
        this->INHERITED::setupPaint(paint);
        // srcmode is most interesting when we're not opaque
        paint->setAlpha(0x80);
        paint->setXfermode(fMode);
    }

    virtual const char* onGetName() SK_OVERRIDE {
        fName.set(this->INHERITED::onGetName());
        fName.prepend("srcmode_");
        return fName.c_str();
    }

private:
    SkString fName;
    SkXfermode* fMode;

    typedef RectBench INHERITED;
};

class OvalBench : public RectBench {
public:
    OvalBench(void* param, int shift) : RectBench(param, shift) {}
protected:
    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawOval(r, p);
    }
    virtual const char* onGetName() { return computeName("ovals"); }
};

class RRectBench : public RectBench {
public:
    RRectBench(void* param, int shift) : RectBench(param, shift) {}
protected:
    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
    }
    virtual const char* onGetName() { return computeName("rrects"); }
};

class PointsBench : public RectBench {
public:
    SkCanvas::PointMode fMode;
    const char* fName;

    PointsBench(void* param, SkCanvas::PointMode mode, const char* name) :
        RectBench(param, 2), fMode(mode) {
        fName = name;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) {
        SkScalar gSizes[] = {
            SkIntToScalar(7), 0
        };
        size_t sizes = SK_ARRAY_COUNT(gSizes);

        if (this->hasStrokeWidth()) {
            gSizes[0] = this->getStrokeWidth();
            sizes = 1;
        }

        SkPaint paint;
        paint.setStrokeCap(SkPaint::kRound_Cap);

        for (size_t i = 0; i < sizes; i++) {
            paint.setStrokeWidth(gSizes[i]);
            this->setupPaint(&paint);
            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
            paint.setColor(fColors[i]);
        }
    }
    virtual const char* onGetName() { return fName; }
};

class AARectBench : public SkBenchmark {
public:
    enum {
        W = 640,
        H = 480,
    };

    AARectBench(void* param) : INHERITED(param) {}

protected:

    virtual const char* onGetName() { return "aarects"; }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setAntiAlias(true);
        paint.setColor(SK_ColorBLACK);
        SkRect r;

        // Draw small aa rects in a grid across the screen
        for (SkScalar y = SK_ScalarHalf; y < H; y += SkIntToScalar(2)) {
            for (SkScalar x = SK_ScalarHalf; x < W; x += SkIntToScalar(2)) {
                r.set(x, y,
                      x+SkFloatToScalar(1.5f), y+SkFloatToScalar(1.5f));
                canvas->drawRect(r, paint);
            }
        }

    }
private:
    typedef SkBenchmark INHERITED;
};

/*******************************************************************************
 * to bench BlitMask [Opaque, Black, color, shader]
 *******************************************************************************/

class BlitMaskBench : public RectBench {
public:
    enum kMaskType {
        kMaskOpaque = 0,
        kMaskBlack,
        kMaskColor,
        KMaskShader
    };
    SkCanvas::PointMode fMode;
    const char* fName;

    BlitMaskBench(void* param, SkCanvas::PointMode mode,
                  BlitMaskBench::kMaskType type, const char* name) :
                  RectBench(param, 2), fMode(mode), _type(type) {
        fName = name;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) {
        SkScalar gSizes[] = {
            SkIntToScalar(13), SkIntToScalar(24)
        };
        size_t sizes = SK_ARRAY_COUNT(gSizes);

        if (this->hasStrokeWidth()) {
            gSizes[0] = this->getStrokeWidth();
            sizes = 1;
        }
        SkRandom rand;
        SkColor color = 0xFF000000;
        U8CPU alpha = 0xFF;
        SkPaint paint;
        paint.setStrokeCap(SkPaint::kRound_Cap);
        if (_type == KMaskShader) {
            SkBitmap srcBM;
            srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1);
            srcBM.allocPixels();
            srcBM.eraseColor(0xFF00FF00);

            SkShader* s;
            s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
                                              SkShader::kClamp_TileMode);
            paint.setShader(s)->unref();
        }
        for (size_t i = 0; i < sizes; i++) {
            switch (_type) {
                case kMaskOpaque:
                    color = fColors[i];
                    alpha = 0xFF;
                    break;
                case kMaskBlack:
                    alpha = 0xFF;
                    color = 0xFF000000;
                    break;
                case kMaskColor:
                    color = fColors[i];
                    alpha = rand.nextU() & 255;
                    break;
                case KMaskShader:
                    break;
            }
            paint.setStrokeWidth(gSizes[i]);
            this->setupPaint(&paint);
            paint.setColor(color);
            paint.setAlpha(alpha);
            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
       }
    }
    virtual const char* onGetName() { return fName; }
private:
    typedef RectBench INHERITED;
    kMaskType _type;
};

DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1)); )
DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1, 4)); )
DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3)); )
DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3, 4)); )
DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 1)); )
DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 3)); )
DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1)); )
DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3)); )
DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points")); )
DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines")); )
DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon")); )

DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, (p)); )
DEF_BENCH( return SkNEW_ARGS(AARectBench, (p)); )

/* init the blitmask bench
 */
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                      (p, SkCanvas::kPoints_PointMode,
                      BlitMaskBench::kMaskOpaque, "maskopaque")
                      ); )
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                      (p, SkCanvas::kPoints_PointMode,
                      BlitMaskBench::kMaskBlack, "maskblack")
                      ); )
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                      (p, SkCanvas::kPoints_PointMode,
                      BlitMaskBench::kMaskColor, "maskcolor")
                      ); )
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                     (p, SkCanvas::kPoints_PointMode,
                     BlitMaskBench::KMaskShader, "maskshader")
                     ); )
<commit_msg>Add stroked rrect benches. <commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkString.h"
#include "SkShader.h"

class RectBench : public SkBenchmark {
public:
    int fShift, fStroke;
    enum {
        W = 640,
        H = 480,
        N = SkBENCHLOOP(300)
    };
    SkRect  fRects[N];
    SkColor fColors[N];

    RectBench(void* param, int shift, int stroke = 0)
        : INHERITED(param)
        , fShift(shift)
        , fStroke(stroke) {
        SkRandom rand;
        const SkScalar offset = SK_Scalar1/3;
        for (int i = 0; i < N; i++) {
            int x = rand.nextU() % W;
            int y = rand.nextU() % H;
            int w = rand.nextU() % W;
            int h = rand.nextU() % H;
            w >>= shift;
            h >>= shift;
            x -= w/2;
            y -= h/2;
            fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
                          SkIntToScalar(x+w), SkIntToScalar(y+h));
            fRects[i].offset(offset, offset);
            fColors[i] = rand.nextU() | 0xFF808080;
        }
    }

    SkString fName;
    const char* computeName(const char root[]) {
        fName.printf("%s_%d", root, fShift);
        if (fStroke > 0) {
            fName.appendf("_stroke_%d", fStroke);
        }
        return fName.c_str();
    }

protected:
    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawRect(r, p);
    }

    virtual const char* onGetName() { return computeName("rects"); }
    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        if (fStroke > 0) {
            paint.setStyle(SkPaint::kStroke_Style);
            paint.setStrokeWidth(SkIntToScalar(fStroke));
        }
        for (int i = 0; i < N; i++) {
            paint.setColor(fColors[i]);
            this->setupPaint(&paint);
            this->drawThisRect(canvas, fRects[i], paint);
        }
    }
private:
    typedef SkBenchmark INHERITED;
};

class SrcModeRectBench : public RectBench {
public:
    SrcModeRectBench(void* param) : INHERITED(param, 1, 0) {
        fMode = SkXfermode::Create(SkXfermode::kSrc_Mode);
    }

    virtual ~SrcModeRectBench() {
        SkSafeUnref(fMode);
    }

protected:
    virtual void setupPaint(SkPaint* paint) SK_OVERRIDE {
        this->INHERITED::setupPaint(paint);
        // srcmode is most interesting when we're not opaque
        paint->setAlpha(0x80);
        paint->setXfermode(fMode);
    }

    virtual const char* onGetName() SK_OVERRIDE {
        fName.set(this->INHERITED::onGetName());
        fName.prepend("srcmode_");
        return fName.c_str();
    }

private:
    SkString fName;
    SkXfermode* fMode;

    typedef RectBench INHERITED;
};

class OvalBench : public RectBench {
public:
    OvalBench(void* param, int shift) : RectBench(param, shift) {}
protected:
    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawOval(r, p);
    }
    virtual const char* onGetName() { return computeName("ovals"); }
};

class RRectBench : public RectBench {
public:
    RRectBench(void* param, int shift, int stroke = 0) : RectBench(param, shift, stroke) {}
protected:
    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
    }
    virtual const char* onGetName() { return computeName("rrects"); }
};

class PointsBench : public RectBench {
public:
    SkCanvas::PointMode fMode;
    const char* fName;

    PointsBench(void* param, SkCanvas::PointMode mode, const char* name) :
        RectBench(param, 2), fMode(mode) {
        fName = name;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) {
        SkScalar gSizes[] = {
            SkIntToScalar(7), 0
        };
        size_t sizes = SK_ARRAY_COUNT(gSizes);

        if (this->hasStrokeWidth()) {
            gSizes[0] = this->getStrokeWidth();
            sizes = 1;
        }

        SkPaint paint;
        paint.setStrokeCap(SkPaint::kRound_Cap);

        for (size_t i = 0; i < sizes; i++) {
            paint.setStrokeWidth(gSizes[i]);
            this->setupPaint(&paint);
            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
            paint.setColor(fColors[i]);
        }
    }
    virtual const char* onGetName() { return fName; }
};

class AARectBench : public SkBenchmark {
public:
    enum {
        W = 640,
        H = 480,
    };

    AARectBench(void* param) : INHERITED(param) {}

protected:

    virtual const char* onGetName() { return "aarects"; }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setAntiAlias(true);
        paint.setColor(SK_ColorBLACK);
        SkRect r;

        // Draw small aa rects in a grid across the screen
        for (SkScalar y = SK_ScalarHalf; y < H; y += SkIntToScalar(2)) {
            for (SkScalar x = SK_ScalarHalf; x < W; x += SkIntToScalar(2)) {
                r.set(x, y,
                      x+SkFloatToScalar(1.5f), y+SkFloatToScalar(1.5f));
                canvas->drawRect(r, paint);
            }
        }

    }
private:
    typedef SkBenchmark INHERITED;
};

/*******************************************************************************
 * to bench BlitMask [Opaque, Black, color, shader]
 *******************************************************************************/

class BlitMaskBench : public RectBench {
public:
    enum kMaskType {
        kMaskOpaque = 0,
        kMaskBlack,
        kMaskColor,
        KMaskShader
    };
    SkCanvas::PointMode fMode;
    const char* fName;

    BlitMaskBench(void* param, SkCanvas::PointMode mode,
                  BlitMaskBench::kMaskType type, const char* name) :
                  RectBench(param, 2), fMode(mode), _type(type) {
        fName = name;
    }

protected:
    virtual void onDraw(SkCanvas* canvas) {
        SkScalar gSizes[] = {
            SkIntToScalar(13), SkIntToScalar(24)
        };
        size_t sizes = SK_ARRAY_COUNT(gSizes);

        if (this->hasStrokeWidth()) {
            gSizes[0] = this->getStrokeWidth();
            sizes = 1;
        }
        SkRandom rand;
        SkColor color = 0xFF000000;
        U8CPU alpha = 0xFF;
        SkPaint paint;
        paint.setStrokeCap(SkPaint::kRound_Cap);
        if (_type == KMaskShader) {
            SkBitmap srcBM;
            srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1);
            srcBM.allocPixels();
            srcBM.eraseColor(0xFF00FF00);

            SkShader* s;
            s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
                                              SkShader::kClamp_TileMode);
            paint.setShader(s)->unref();
        }
        for (size_t i = 0; i < sizes; i++) {
            switch (_type) {
                case kMaskOpaque:
                    color = fColors[i];
                    alpha = 0xFF;
                    break;
                case kMaskBlack:
                    alpha = 0xFF;
                    color = 0xFF000000;
                    break;
                case kMaskColor:
                    color = fColors[i];
                    alpha = rand.nextU() & 255;
                    break;
                case KMaskShader:
                    break;
            }
            paint.setStrokeWidth(gSizes[i]);
            this->setupPaint(&paint);
            paint.setColor(color);
            paint.setAlpha(alpha);
            canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
       }
    }
    virtual const char* onGetName() { return fName; }
private:
    typedef RectBench INHERITED;
    kMaskType _type;
};

DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1)); )
DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1, 4)); )
DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3)); )
DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3, 4)); )
DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 1)); )
DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 3)); )
DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1)); )
DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1, 4)); )
DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3)); )
DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3, 4)); )
DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points")); )
DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines")); )
DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon")); )

DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, (p)); )
DEF_BENCH( return SkNEW_ARGS(AARectBench, (p)); )

/* init the blitmask bench
 */
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                      (p, SkCanvas::kPoints_PointMode,
                      BlitMaskBench::kMaskOpaque, "maskopaque")
                      ); )
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                      (p, SkCanvas::kPoints_PointMode,
                      BlitMaskBench::kMaskBlack, "maskblack")
                      ); )
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                      (p, SkCanvas::kPoints_PointMode,
                      BlitMaskBench::kMaskColor, "maskcolor")
                      ); )
DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
                     (p, SkCanvas::kPoints_PointMode,
                     BlitMaskBench::KMaskShader, "maskshader")
                     ); )
<|endoftext|>


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

#include <math.h>

using namespace std;

namespace CODeM {
namespace Utils {

double magnitudeP(const vector<double> &vec, double p)
{
    double magnitude = 0.0;
    for(int i=0; i < vec.size(); i++) {
        magnitude += pow(vec[i], p);
    }
    magnitude = pow(magnitude, 1.0 / p);

    return magnitude;
}

void toUnitVec(vector<double>& vec, double norm)
{
    magnitudeP(vec, norm);
}

double distanceP(const vector<double> &m, const vector<double> &c, double p)
{
    double dist = 0.0;
    if(m.size() == c.size()) {
        for(int i=0; i<m.size(); i++) {
            dist += pow(abs(m[i] - c[i]), p);
        }
        dist = pow(dist, 1.0 / p);
        return dist;
    } else {
        return -1.0;
    }
}

void scale(vector<double>& vec, double factor)
{
    for(int i=0; i < vec.size(); i++) {
        vec[i] *= factor;
    }
}

void normaliseToUnitInterval(double& val, double  lBound, double  uBound)
{
    if(val <= lBound) {
        val = 0.0;
    } else if(val >= uBound) {
            val = 1.0;
    } else {
        val = (val - lBound) / (uBound - lBound);
    }
}

void scaleBackFromUnitInterval(double& normVal, double  lBound, double  uBound)
{
    if(normVal >= 1) {
        normVal = uBound;
    } else if(normVal <= 0.0) {
        normVal = lBound;
    } else {
        normVal = lBound + normVal * (uBound - lBound);
    }
}

void normaliseToUnitBox(vector<double>& vec,
                        const vector<double> &lBounds, const vector<double> &uBounds)
{
    for(int i=0; i < vec.size(); i++) {
        if(vec[i] <= lBounds[i]) {
            vec[i] = 0.0;
        }else if(vec[i] >= uBounds[i]) {
            vec[i] = 1.0;
        }   else {
            vec[i] = (vec[i] - lBounds[i]) / (uBounds[i] - lBounds[i]);
        }
    }
}

void scaleBackFromUnitBox(vector<double>& vec,
                          const vector<double> &lBounds, const vector<double> &uBounds)
{
    for(int i=0; i < vec.size(); i++) {
        if(vec[i] > 1.0) {
            vec[i] = uBounds[i] - (1.0 - vec[i]) * (uBounds[i] - lBounds[i]);
        } else if(vec[i] < 0.0) {
            vec[i] = lBounds[i] - vec[i] * (uBounds[i] - lBounds[i]);
        } else {
            vec[i] = lBounds[i] + vec[i] * (uBounds[i] - lBounds[i]);
        }
    }
}

double directedBoxedIntervalLength(const vector<double> &dir, double p)
{
    double maxComponent = 0.0;
    for(int i=0; i < dir.size(); i++) {
        if(dir[i] > maxComponent) {
            maxComponent = dir[i];
        }
    }
    double len = 0.0;
    for(int i=0; i < dir.size(); i++) {
        len += pow((dir[i] / maxComponent), p);
    }
    len = pow(len, 1.0 / p);
    return len;
}

} // namespace Utils
} // namespace CODeM
<commit_msg>fixed a bug in normalisation. Now the results seem fine<commit_after>/****************************************************************************
**
** The MIT License (MIT)
**
** Copyright (c) 2016 The University of Sheffield (www.sheffield.ac.uk)
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE
**
****************************************************************************/
#include <core/utils/ScalingUtils.h>

#include <math.h>

using namespace std;

namespace CODeM {
namespace Utils {

double magnitudeP(const vector<double> &vec, double p)
{
    double magnitude = 0.0;
    for(int i=0; i < vec.size(); i++) {
        magnitude += pow(vec[i], p);
    }
    magnitude = pow(magnitude, 1.0 / p);

    return magnitude;
}

void toUnitVec(vector<double>& vec, double norm)
{
    double magnitude = magnitudeP(vec, norm);
    scale(vec, 1.0/magnitude);
}

double distanceP(const vector<double> &m, const vector<double> &c, double p)
{
    double dist = 0.0;
    if(m.size() == c.size()) {
        for(int i=0; i<m.size(); i++) {
            dist += pow(abs(m[i] - c[i]), p);
        }
        dist = pow(dist, 1.0 / p);
        return dist;
    } else {
        return -1.0;
    }
}

void scale(vector<double>& vec, double factor)
{
    for(int i=0; i < vec.size(); i++) {
        vec[i] *= factor;
    }
}

void normaliseToUnitInterval(double& val, double  lBound, double  uBound)
{
    if(val <= lBound) {
        val = 0.0;
    } else if(val >= uBound) {
            val = 1.0;
    } else {
        val = (val - lBound) / (uBound - lBound);
    }
}

void scaleBackFromUnitInterval(double& normVal, double  lBound, double  uBound)
{
    if(normVal >= 1) {
        normVal = uBound;
    } else if(normVal <= 0.0) {
        normVal = lBound;
    } else {
        normVal = lBound + normVal * (uBound - lBound);
    }
}

void normaliseToUnitBox(vector<double>& vec,
                        const vector<double> &lBounds, const vector<double> &uBounds)
{
    for(int i=0; i < vec.size(); i++) {
        if(vec[i] <= lBounds[i]) {
            vec[i] = 0.0;
        }else if(vec[i] >= uBounds[i]) {
            vec[i] = 1.0;
        }   else {
            vec[i] = (vec[i] - lBounds[i]) / (uBounds[i] - lBounds[i]);
        }
    }
}

void scaleBackFromUnitBox(vector<double>& vec,
                          const vector<double> &lBounds, const vector<double> &uBounds)
{
    for(int i=0; i < vec.size(); i++) {
        if(vec[i] > 1.0) {
            vec[i] = uBounds[i] - (1.0 - vec[i]) * (uBounds[i] - lBounds[i]);
        } else if(vec[i] < 0.0) {
            vec[i] = lBounds[i] - vec[i] * (uBounds[i] - lBounds[i]);
        } else {
            vec[i] = lBounds[i] + vec[i] * (uBounds[i] - lBounds[i]);
        }
    }
}

double directedBoxedIntervalLength(const vector<double> &dir, double p)
{
    double maxComponent = 0.0;
    for(int i=0; i < dir.size(); i++) {
        if(dir[i] > maxComponent) {
            maxComponent = dir[i];
        }
    }
    double len = 0.0;
    for(int i=0; i < dir.size(); i++) {
        len += pow((dir[i] / maxComponent), p);
    }
    len = pow(len, 1.0 / p);
    return len;
}

} // namespace Utils
} // namespace CODeM
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: str_types.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-12 15:46:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef COSV_STR_TYPES_HXX
#define COSV_STR_TYPES_HXX

namespace csv
{

/** Provides some generally used constants.
*/
struct str
{
  public:
    typedef ::size_t    position;
    typedef ::size_t    size;

    enum constants
    {
        npos = position(-1),
        maxsize = size(-1)
    };

    enum insert_mode
    {
        overwrite = 0,
        insert = 1
    };
};

/** Is used for string comparisons.

    @collab String
    @collab various csv::compare(...) functions
*/
class CharOrder_Table
{
  public:
    /** @precond
        Parameter i_pCharWeightsArray
        must have size of 256.
    */
                        CharOrder_Table(
                            const int *         i_pCharWeightsArray );

    /** @return the weight of the char i_c.
        @precond
        Even with unusual implementations, where char has more than 8 bit,
        there must be true: 0 <= i_c < 256.
    */
    int                 operator()(
                            char                i_c ) const;
  private:
    int                 cWeights[256];
};

// IMPLEMENTATION

inline int
CharOrder_Table::operator()( char i_c ) const
    { return cWeights[i_c]; }

}   // namespace csv

#endif
<commit_msg>INTEGRATION: CWS adc9 (1.2.10); FILE MERGED 2004/11/10 15:01:16 np 1.2.10.1: #i31023#<commit_after>/*************************************************************************
 *
 *  $RCSfile: str_types.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-15 13:46:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef COSV_STR_TYPES_HXX
#define COSV_STR_TYPES_HXX

namespace csv
{

/** Provides some generally used constants.
*/
struct str
{
  public:
    typedef ::size_t    position;
    typedef ::size_t    size;

    enum constants
    {
        npos = position(-1),
        maxsize = size(-1)
    };

    enum insert_mode
    {
        overwrite = 0,
        insert = 1
    };
};

/** Is used for string comparisons.

    @collab String
    @collab various csv::compare(...) functions
*/
class CharOrder_Table
{
  public:
    /** @precond
        Parameter i_pCharWeightsArray
        must have size of 256.
    */
                        CharOrder_Table(
                            const int *         i_pCharWeightsArray );

    /** @return the weight of the char i_c.
        @precond
        Even with unusual implementations, where char has more than 8 bit,
        there must be true: 0 <= i_c < 256.
    */
    int                 operator()(
                            char                i_c ) const;
  private:
    int                 cWeights[256];
};

// IMPLEMENTATION

inline int
CharOrder_Table::operator()( char i_c ) const
    { return cWeights[ UINT8(i_c) ]; }

}   // namespace csv

#endif
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void zeroReduction(const MatrixType& m) {
  // Reductions that must hold for zero sized objects
  VERIFY(m.all());
  VERIFY(!m.any());
  VERIFY(m.prod()==1);
  VERIFY(m.sum()==0);
  VERIFY(m.count()==0);
  VERIFY(m.allFinite());
  VERIFY(!m.hasNaN());
}

template<typename MatrixType> void zeroSizedMatrix()
{
  MatrixType t1;
  typedef typename MatrixType::Scalar Scalar;

  if (MatrixType::SizeAtCompileTime == Dynamic || MatrixType::SizeAtCompileTime == 0)
  {
    zeroReduction(t1);
    if (MatrixType::RowsAtCompileTime == Dynamic)
      VERIFY(t1.rows() == 0);
    if (MatrixType::ColsAtCompileTime == Dynamic)
      VERIFY(t1.cols() == 0);

    if (MatrixType::RowsAtCompileTime == Dynamic && MatrixType::ColsAtCompileTime == Dynamic)
    {

      MatrixType t2(0, 0);
      VERIFY(t2.rows() == 0);
      VERIFY(t2.cols() == 0);

      zeroReduction(t2);
      VERIFY(t1==t2);
    }
  }

  if(MatrixType::MaxColsAtCompileTime!=0 && MatrixType::MaxRowsAtCompileTime!=0)
  {
    Index rows = MatrixType::RowsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : Index(MatrixType::RowsAtCompileTime);
    Index cols = MatrixType::ColsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : Index(MatrixType::ColsAtCompileTime);
    MatrixType m(rows,cols);
    zeroReduction(m.template block<0,MatrixType::ColsAtCompileTime>(0,0,0,cols));
    zeroReduction(m.template block<MatrixType::RowsAtCompileTime,0>(0,0,rows,0));
    zeroReduction(m.template block<0,1>(0,0));
    zeroReduction(m.template block<1,0>(0,0));
    Matrix<Scalar,Dynamic,Dynamic> prod = m.template block<MatrixType::RowsAtCompileTime,0>(0,0,rows,0) * m.template block<0,MatrixType::ColsAtCompileTime>(0,0,0,cols);
    VERIFY(prod.rows()==rows && prod.cols()==cols);
    VERIFY(prod.isZero());
    prod = m.template block<1,0>(0,0) * m.template block<0,1>(0,0);
    VERIFY(prod.size()==1);
    VERIFY(prod.isZero());
  }
}

template<typename VectorType> void zeroSizedVector()
{
  VectorType t1;

  if (VectorType::SizeAtCompileTime == Dynamic || VectorType::SizeAtCompileTime==0)
  {
    zeroReduction(t1);
    VERIFY(t1.size() == 0);
    VectorType t2(DenseIndex(0)); // DenseIndex disambiguates with 0-the-null-pointer (error with gcc 4.4 and MSVC8)
    VERIFY(t2.size() == 0);
    zeroReduction(t2);

    VERIFY(t1==t2);
  }
}

void test_zerosized()
{
  zeroSizedMatrix<Matrix2d>();
  zeroSizedMatrix<Matrix3i>();
  zeroSizedMatrix<Matrix<float, 2, Dynamic> >();
  zeroSizedMatrix<MatrixXf>();
  zeroSizedMatrix<Matrix<float, 0, 0> >();
  zeroSizedMatrix<Matrix<float, Dynamic, 0, 0, 0, 0> >();
  zeroSizedMatrix<Matrix<float, 0, Dynamic, 0, 0, 0> >();
  zeroSizedMatrix<Matrix<float, Dynamic, Dynamic, 0, 0, 0> >();
  zeroSizedMatrix<Matrix<float, 0, 4> >();
  zeroSizedMatrix<Matrix<float, 4, 0> >();

  zeroSizedVector<Vector2d>();
  zeroSizedVector<Vector3i>();
  zeroSizedVector<VectorXf>();
  zeroSizedVector<Matrix<float, 0, 1> >();
  zeroSizedVector<Matrix<float, 1, 0> >();
}
<commit_msg>Extend unit test to stress smart_copy with empty input/output.<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void zeroReduction(const MatrixType& m) {
  // Reductions that must hold for zero sized objects
  VERIFY(m.all());
  VERIFY(!m.any());
  VERIFY(m.prod()==1);
  VERIFY(m.sum()==0);
  VERIFY(m.count()==0);
  VERIFY(m.allFinite());
  VERIFY(!m.hasNaN());
}

template<typename MatrixType> void zeroSizedMatrix()
{
  MatrixType t1;
  typedef typename MatrixType::Scalar Scalar;

  if (MatrixType::SizeAtCompileTime == Dynamic || MatrixType::SizeAtCompileTime == 0)
  {
    zeroReduction(t1);
    if (MatrixType::RowsAtCompileTime == Dynamic)
      VERIFY(t1.rows() == 0);
    if (MatrixType::ColsAtCompileTime == Dynamic)
      VERIFY(t1.cols() == 0);

    if (MatrixType::RowsAtCompileTime == Dynamic && MatrixType::ColsAtCompileTime == Dynamic)
    {

      MatrixType t2(0, 0), t3(t1);
      VERIFY(t2.rows() == 0);
      VERIFY(t2.cols() == 0);

      zeroReduction(t2);
      VERIFY(t1==t2);
    }
  }

  if(MatrixType::MaxColsAtCompileTime!=0 && MatrixType::MaxRowsAtCompileTime!=0)
  {
    Index rows = MatrixType::RowsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : Index(MatrixType::RowsAtCompileTime);
    Index cols = MatrixType::ColsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : Index(MatrixType::ColsAtCompileTime);
    MatrixType m(rows,cols);
    zeroReduction(m.template block<0,MatrixType::ColsAtCompileTime>(0,0,0,cols));
    zeroReduction(m.template block<MatrixType::RowsAtCompileTime,0>(0,0,rows,0));
    zeroReduction(m.template block<0,1>(0,0));
    zeroReduction(m.template block<1,0>(0,0));
    Matrix<Scalar,Dynamic,Dynamic> prod = m.template block<MatrixType::RowsAtCompileTime,0>(0,0,rows,0) * m.template block<0,MatrixType::ColsAtCompileTime>(0,0,0,cols);
    VERIFY(prod.rows()==rows && prod.cols()==cols);
    VERIFY(prod.isZero());
    prod = m.template block<1,0>(0,0) * m.template block<0,1>(0,0);
    VERIFY(prod.size()==1);
    VERIFY(prod.isZero());
  }
}

template<typename VectorType> void zeroSizedVector()
{
  VectorType t1;

  if (VectorType::SizeAtCompileTime == Dynamic || VectorType::SizeAtCompileTime==0)
  {
    zeroReduction(t1);
    VERIFY(t1.size() == 0);
    VectorType t2(DenseIndex(0)); // DenseIndex disambiguates with 0-the-null-pointer (error with gcc 4.4 and MSVC8)
    VERIFY(t2.size() == 0);
    zeroReduction(t2);

    VERIFY(t1==t2);
  }
}

void test_zerosized()
{
  zeroSizedMatrix<Matrix2d>();
  zeroSizedMatrix<Matrix3i>();
  zeroSizedMatrix<Matrix<float, 2, Dynamic> >();
  zeroSizedMatrix<MatrixXf>();
  zeroSizedMatrix<Matrix<float, 0, 0> >();
  zeroSizedMatrix<Matrix<float, Dynamic, 0, 0, 0, 0> >();
  zeroSizedMatrix<Matrix<float, 0, Dynamic, 0, 0, 0> >();
  zeroSizedMatrix<Matrix<float, Dynamic, Dynamic, 0, 0, 0> >();
  zeroSizedMatrix<Matrix<float, 0, 4> >();
  zeroSizedMatrix<Matrix<float, 4, 0> >();

  zeroSizedVector<Vector2d>();
  zeroSizedVector<Vector3i>();
  zeroSizedVector<VectorXf>();
  zeroSizedVector<Matrix<float, 0, 1> >();
  zeroSizedVector<Matrix<float, 1, 0> >();
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions 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 materialsprovided with the
//    distribution.
//
// 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 HOLDER 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.
#pragma once

#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>

namespace wrencc {

using nil_t   = std::nullptr_t;
using byte_t  = std::uint8_t;
using i8_t    = std::int8_t;
using u8_t    = std::uint8_t;
using i16_t   = std::int16_t;
using u16_t   = std::uint16_t;
using i32_t   = std::int32_t;
using u32_t   = std::uint32_t;
using i64_t   = std::int64_t;
using u64_t   = std::uint64_t;
using ssz_t   = std::int32_t;
using sz_t    = std::size_t;
using str_t   = std::string;
using strv_t  = std::string_view;

class Copyable {
protected:
  Copyable(void) noexcept = default;
  ~Copyable(void) noexcept = default;
  Copyable(const Copyable&) noexcept = default;
  Copyable(Copyable&&) noexcept = default;
  Copyable& operator=(const Copyable&) noexcept = default;
  Copyable& operator=(Copyable&&) noexcept = default;
};

class UnCopyable {
  UnCopyable(const UnCopyable&) noexcept = delete;
  UnCopyable(UnCopyable&&) noexcept = delete;
  UnCopyable& operator=(const UnCopyable&) noexcept = delete;
  UnCopyable& operator=(UnCopyable&&) noexcept = delete;
protected:
  UnCopyable(void) noexcept = default;
  ~UnCopyable(void) noexcept = default;
};

namespace Xt {
  template <typename T, typename U>
  inline T as_type(U x) { return static_cast<T>(x); }

  template <typename T, typename U>
  inline T* cast(U* x) { return static_cast<T*>(x); }

  template <typename T, typename U>
  inline T* down(U* x) { return dynamic_cast<T*>(x); }

  inline str_t to_string(double d) {
    std::stringstream ss;
    ss << d;
    return ss.str();
  }
}

}

// if true then Wren will use a NaN tagged double for its core value
// representation, otherwise it will use a larger more conventional struct,
// the former is significantly faster and more compact, the latter is useful
// for debugging and may be more protable
//
// Defaults to on
#ifndef NAN_TAGGING
# define NAN_TAGGING        (true)
#endif

// if true the VM's interpreter loop use computed gotos, see this for more:
// https://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/Labels-as-Values.html, enabling
// this speeds up the main dispatch loop a bit, but requires compiler support
//
// Defaults to on if not MSVC
#ifndef COMPUTED_GOTOS
# ifndef _MSC_VER
#   define COMPUTED_GOTOS   (true)
# else
#   define COMPUTED_GOTOS   (false)
# endif
#endif

// if true loads the `IO` class in the standard library
//
// Defaults to on
#ifndef USE_LIBIO
# define USE_LIBIO          (true)
#endif

// set this to true to stress test the GC, it will perform a collection before
// every allocation, this is useful to ensure that memory is always correctly
// pinned
#define GC_STRESS           (false)

// set this to true to log memory operations as they occured
#define TRACE_MEMORY        (false)

// set this to true to log garbage collections as the occured
#define TRACE_GC            (false)

// set this to true to print out the compiled bytecode of each function
#define DUMP_COMPILED       (false)

// set this to trace each instructions as it's executed
#define TRACE_INSTRUCTIONS  (false)

// set this to display object's detail information
#define TRACE_OBJECT_DETAIL (false)

// the maximum number of globals that may be defined at one time, this
// limitation comes from the 16-bits used for the arguments to
// `Code::LOAD_GLOBAL` and `Code::STORE_GLOBAL`
#define MAX_GLOBALS         (65536)

// the maximum number of arguments that can be passed to a method, note that
// this limitation is hardcoded in order places in the VM, in particular the
// `Code::CALL_*` instructions assume a certain maximum number
#define MAX_PARAMETERS      (16)

// the maximum name of a method, not including the signature, this is an
// arbitrary but enforced maximum just so we know how long the method name
// strings need to be in the parser
#define MAX_METHOD_NAME     (64)

// the maximum length of a method signature, this includes the name and the
// extra spaces added to handle arity and another byte to terminate the string
#define MAX_METHOD_SIGNATURE  (MAX_METHOD_NAME + MAX_PARAMETERS + 1)

// the maximum length of an identifier, the only real reason for this limitation
// is so that error messages mentioning variables can be stack allocated
#define MAX_VARIABLE_NAME   (64)

// the maximum number of fields a class can have, including inherited fields,
// this is explicit in the bytecode since `Code::CLASS` and `Code::SUBCLASS`
// take a single byte for the number of fields, note that it's 255 and not
// 256 because creating a class takes the *number* of fields, not the *highest
// field index*
#define MAX_FIELDS          (255)

#ifndef NDEBUG
# define ASSERT(cond, msg) if (!(cond)) {\
  std::cerr << "[" << __FILE__ << ": " << __LINE__ << "] "\
            << "Assert failed in " << __func__ << "(): "\
            << msg << std::endl;\
  std::abort();\
}
#else
# define ASSERT(cond, msg) ((void)0)
#endif

// assertion to indicate that the given point in the code should never be
// reached
#define UNREACHABLE() ASSERT(false, "this line should not be reached")
<commit_msg>:construction: chore(common): updated common definitions<commit_after>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions 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 materialsprovided with the
//    distribution.
//
// 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 HOLDER 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.
#pragma once

#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>

namespace wrencc {

using nil_t   = std::nullptr_t;
using byte_t  = std::uint8_t;
using i8_t    = std::int8_t;
using u8_t    = std::uint8_t;
using i16_t   = std::int16_t;
using u16_t   = std::uint16_t;
using i32_t   = std::int32_t;
using u32_t   = std::uint32_t;
using i64_t   = std::int64_t;
using u64_t   = std::uint64_t;
using ssz_t   = std::int32_t;
using sz_t    = std::size_t;
using str_t   = std::string;
using strv_t  = std::string_view;

class Copyable {
protected:
  Copyable(void) noexcept = default;
  ~Copyable(void) noexcept = default;
  Copyable(const Copyable&) noexcept = default;
  Copyable(Copyable&&) noexcept = default;
  Copyable& operator=(const Copyable&) noexcept = default;
  Copyable& operator=(Copyable&&) noexcept = default;
};

class UnCopyable {
  UnCopyable(const UnCopyable&) noexcept = delete;
  UnCopyable(UnCopyable&&) noexcept = delete;
  UnCopyable& operator=(const UnCopyable&) noexcept = delete;
  UnCopyable& operator=(UnCopyable&&) noexcept = delete;
protected:
  UnCopyable(void) noexcept = default;
  ~UnCopyable(void) noexcept = default;
};

namespace Xt {
  template <typename T, typename U>
  inline T as_type(U x) { return static_cast<T>(x); }

  template <typename T, typename U>
  inline T* cast(U* x) { return static_cast<T*>(x); }

  template <typename T, typename U>
  inline T* down(U* x) { return dynamic_cast<T*>(x); }

  inline str_t to_string(double d) {
    std::stringstream ss;
    ss << d;
    return ss.str();
  }
}

}

// if true then Wren will use a NaN tagged double for its core value
// representation, otherwise it will use a larger more conventional struct,
// the former is significantly faster and more compact, the latter is useful
// for debugging and may be more protable
//
// Defaults to on
#ifndef NAN_TAGGING
# define NAN_TAGGING        (true)
#endif

// if true the VM's interpreter loop use computed gotos, see this for more:
// https://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/Labels-as-Values.html, enabling
// this speeds up the main dispatch loop a bit, but requires compiler support
//
// Defaults to on if not MSVC
#ifndef COMPUTED_GOTOS
# ifndef _MSC_VER
#   define COMPUTED_GOTOS   (true)
# else
#   define COMPUTED_GOTOS   (false)
# endif
#endif

// if true loads the `IO` class in the standard library
//
// Defaults to on
#ifndef USE_LIBIO
# define USE_LIBIO          (true)
#endif

// set this to true to stress test the GC, it will perform a collection before
// every allocation, this is useful to ensure that memory is always correctly
// pinned
#define GC_STRESS           (false)

// set this to true to log memory operations as they occured
#define TRACE_MEMORY        (false)

// set this to true to log garbage collections as the occured
#define TRACE_GC            (false)

// set this to true to print out the compiled bytecode of each function
#define DUMP_COMPILED       (false)

// set this to trace each instructions as it's executed
#define TRACE_INSTRUCTIONS  (false)

// set this to display object's detail information
#define TRACE_OBJECT_DETAIL (false)

// the maximum number of globals that may be defined at one time, this
// limitation comes from the 16-bits used for the arguments to
// `Code::LOAD_GLOBAL` and `Code::STORE_GLOBAL`
#define MAX_GLOBALS         (65536)

// the maximum number of arguments that can be passed to a method, note that
// this limitation is hardcoded in order places in the VM, in particular the
// `Code::CALL_*` instructions assume a certain maximum number
#define MAX_PARAMETERS      (16)

// the maximum name of a method, not including the signature, this is an
// arbitrary but enforced maximum just so we know how long the method name
// strings need to be in the parser
#define MAX_METHOD_NAME     (64)

// the maximum length of a method signature, this includes the name and the
// extra spaces added to handle arity and another byte to terminate the string
#define MAX_METHOD_SIGNATURE  (MAX_METHOD_NAME + MAX_PARAMETERS + 1)

// the maximum length of an identifier, the only real reason for this limitation
// is so that error messages mentioning variables can be stack allocated
#define MAX_VARIABLE_NAME   (64)

// the maximum number of fields a class can have, including inherited fields,
// this is explicit in the bytecode since `Code::CLASS` and `Code::SUBCLASS`
// take a single byte for the number of fields, note that it's 255 and not
// 256 because creating a class takes the *number* of fields, not the *highest
// field index*
#define MAX_FIELDS          (255)

#ifndef NDEBUG
# define ASSERT(cond, msg) do {\
  if (!(cond)) {\
    std::cerr << "[" << __FILE__ << ": " << __LINE__ << "] "\
              << "Assert failed in " << __func__ << "(): "\
              << msg << std::endl;\
    std::abort();\
  }\
} while (false)

// assertion to indicate that the given point in the code should never
// be reached
#define UNREACHABLE() do {\
  std::cerr << "This line should not be reached" << std::endl;\
  std::abort();\
} while (false)
#else
# define ASSERT(cond, msg)  ((void)0)
# define UNREACHABLE()      ((void)0)
#endif
<|endoftext|>


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

  Program:   Monteverdi2
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

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

#include "mvdMainWindow.h"
#include "ui_mvdMainWindow.h"

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
#include <QtGui>

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdAboutDialog.h"
#include "mvdApplication.h"
#include "mvdColorDynamicsWidget.h"
#include "mvdColorSetupWidget.h"
#include "mvdGLImageWidget.h"
#include "mvdVectorImageModel.h"

namespace mvd
{
/*
  TRANSLATOR mvd::MainWindow

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
MainWindow
::MainWindow( QWidget* parent, Qt::WindowFlags flags ) :
  QMainWindow( parent, flags ),
  m_UI( new mvd::Ui::MainWindow() )
{
  m_UI->setupUi( this );

  Initialize();
}

/*****************************************************************************/
MainWindow
::~MainWindow()
{
}

/*****************************************************************************/
void
MainWindow
::Initialize()
{
  setObjectName( "mvd::MainWindow" );
  setWindowTitle( PROJECT_NAME );

  // Set the GLImageWidget as the centralWidget in MainWindow.
  setCentralWidget( new GLImageWidget( this ) );

  InitializeDockWidgets();

  // Connect Quit action of main menu to QApplication's quit() slot.
  QObject::connect(
    m_UI->action_Quit, SIGNAL( activated() ),
    qApp, SLOT( quit() )
  );

  // Connect the setLargestPossibleregion
  QObject::connect(
    this, SIGNAL(largestPossibleRegionChanged(const ImageRegionType&)),
    centralWidget(), SLOT( onLargestPossibleRegionChanged(const ImageRegionType&)) );

  // Connect Appllication and MainWindow when selected model is about
  // to change.
  QObject::connect(
    qApp, SIGNAL( aboutToChangeSelectedModel( const AbstractModel* ) ),
    this, SLOT( onAboutToChangeSelectedModel( const AbstractModel* ) )
  );

  // Connect Appllication and MainWindow when selected model has been
  // changed.
  QObject::connect(
    qApp, SIGNAL( selectedModelChanged( const AbstractModel* ) ),
    this, SLOT( onSelectedModelChanged( const AbstractModel* ) )
  );
}

/*****************************************************************************/
void
MainWindow::InitializeDockWidgets()
{
  AddWidgetToDock(
    new ColorSetupWidget( this ),
    VIDEO_COLOR_SETUP_DOCK,
    tr( "Video color setup" ),
    Qt::LeftDockWidgetArea
  );

  AddWidgetToDock(
    new ColorDynamicsWidget( this ),
    VIDEO_COLOR_DYNAMICS_DOCK,
    tr( "Video color dynamics" ),
    Qt::LeftDockWidgetArea
  );
}

/*****************************************************************************/
void
MainWindow
::AddWidgetToDock( QWidget* widget,
		   const QString& dockName,
		   const QString& dockTitle,
		   Qt::DockWidgetArea dockArea )
{
  // New dock.
  QDockWidget* dockWidget = new QDockWidget( dockTitle, this );

  // You can use findChild( dockName ) to get dock-widget.
  dockWidget->setObjectName( dockName );
  dockWidget->setWidget( widget );

  /*
  qDebug() << dockWidget;
  qDebug() << widget;
  qDebug() << widget->parent();
  qDebug();
  */

  // Features.
  dockWidget->setFloating( true );
  dockWidget->setFeatures(
    QDockWidget::DockWidgetMovable |
    QDockWidget::DockWidgetFloatable
  );

  // Add dock.
  addDockWidget( dockArea, dockWidget );
}

/*****************************************************************************/
/* SLOTS                                                                     */
/*****************************************************************************/
void
MainWindow
::on_action_Open_activated()
{
  QString filename(
    QFileDialog::getOpenFileName( this, tr( "Open file..." ) )
  );

  if( filename.isNull() )
    {
    return;
    }

  // TODO: Replace with complex model (list of DatasetModel) when implemented.
  VectorImageModel* model = new VectorImageModel();

  model->setObjectName(
    "mvd::VectorImageModel('" + filename + "')"
  );

  // load file
  try
    {
    model->loadFile( filename );

    qobject_cast< Application* >( qApp )->SetModel( model );
    }
  catch( std::exception& exc )
    {
    delete model;
    model = NULL;

    QMessageBox::warning( this, tr("Exception!"), exc.what() );
    return;
    }
}

/*****************************************************************************/
void
MainWindow
::on_action_About_activated()
{
  AboutDialog aboutDialog( this );

  aboutDialog.exec();
}

/*****************************************************************************/
void
MainWindow
::onAboutToChangeSelectedModel( const AbstractModel* )
{
  Application* app = qobject_cast< Application* >( qApp );

  const VectorImageModel* vectorImageModel =
    qobject_cast< const VectorImageModel* >( app->GetModel() );

  if( vectorImageModel==NULL )
    {
    return;
    }

  // Disconnect previously selected model from view.
  QObject::disconnect(
    vectorImageModel,
    SIGNAL( settingsUpdated() ),
    // to:
    centralWidget(),
    SLOT( updateGL() )
  );

  QWidget* widget = GetColorSetupDock()->widget();

  if( widget==NULL )
    {
    return;
    }

  // Disconnect previously selected model from UI controller.
  QObject::disconnect(
    GetColorSetupDock()->widget(),
    SIGNAL( currentIndexChanged( ColorSetupWidget::Channel, int ) ),
    // from:
    vectorImageModel,
    SLOT( onCurrentIndexChanged( ColorSetupWidget::Channel, int ) )
  );
}

/*****************************************************************************/
void
MainWindow
::onSelectedModelChanged( const AbstractModel* model )
{
  ColorSetupWidget* colorSetupWidget =
    qobject_cast< ColorSetupWidget*  >( GetColorSetupDock()->widget() );

  const VectorImageModel* vectorImageModel =
    qobject_cast< const VectorImageModel* >( model );

  // Connect newly selected model to UI controller.
  QObject::connect(
    colorSetupWidget,
    SIGNAL( currentIndexChanged( ColorSetupWidget::Channel, int ) ),
    // to:
    vectorImageModel,
    SLOT( onCurrentIndexChanged( ColorSetupWidget::Channel, int ) )
  );

  // Connect newly selected model to view.
  QObject::connect(
    vectorImageModel,
    SIGNAL( settingsUpdated() ),
    // to:
    centralWidget(),
    SLOT( updateGL()  )
  );

  // Setup color-setup controller.
  colorSetupWidget->blockSignals( true );
  {
  // qDebug() << vectorImageModel->GetBandNames();

  colorSetupWidget->SetComponents( vectorImageModel->GetBandNames() );

  for( int i=0; i<ColorSetupWidget::CHANNEL_COUNT; ++i )
    {
    colorSetupWidget->SetCurrentIndex(
      ColorSetupWidget::Channel( i ),
      vectorImageModel->GetSettings().RgbChannel( i )
    );
    }
  }
  colorSetupWidget->blockSignals( false );

  // set the largest possible region of the image
  // TODO:  rename signal name when handling DataSets collections
  // TODO: move signal into mvdApplication and link it to DockWidget
  // and ImageView.
  emit largestPossibleRegionChanged(
    vectorImageModel->GetOutput( 0 )->GetLargestPossibleRegion()
  );
}

/*****************************************************************************/

} // end namespace 'mvd'
<commit_msg>ENH: Added QToolBox experiment (see MainWindow::InitializeDockWidgets() to enable).<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

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

#include "mvdMainWindow.h"
#include "ui_mvdMainWindow.h"

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
#include <QtGui>

//
// System includes (sorted by alphabetic order)

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdAboutDialog.h"
#include "mvdApplication.h"
#include "mvdColorDynamicsWidget.h"
#include "mvdColorSetupWidget.h"
#include "mvdGLImageWidget.h"
#include "mvdVectorImageModel.h"

namespace mvd
{
/*
  TRANSLATOR mvd::MainWindow

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
MainWindow
::MainWindow( QWidget* parent, Qt::WindowFlags flags ) :
  QMainWindow( parent, flags ),
  m_UI( new mvd::Ui::MainWindow() )
{
  m_UI->setupUi( this );

  Initialize();
}

/*****************************************************************************/
MainWindow
::~MainWindow()
{
}

/*****************************************************************************/
void
MainWindow
::Initialize()
{
  setObjectName( "mvd::MainWindow" );
  setWindowTitle( PROJECT_NAME );

  // Set the GLImageWidget as the centralWidget in MainWindow.
  setCentralWidget( new GLImageWidget( this ) );

  InitializeDockWidgets();

  // Connect Quit action of main menu to QApplication's quit() slot.
  QObject::connect(
    m_UI->action_Quit, SIGNAL( activated() ),
    qApp, SLOT( quit() )
  );

  // Connect the setLargestPossibleregion
  QObject::connect(
    this, SIGNAL(largestPossibleRegionChanged(const ImageRegionType&)),
    centralWidget(), SLOT( onLargestPossibleRegionChanged(const ImageRegionType&)) );

  // Connect Appllication and MainWindow when selected model is about
  // to change.
  QObject::connect(
    qApp, SIGNAL( aboutToChangeSelectedModel( const AbstractModel* ) ),
    this, SLOT( onAboutToChangeSelectedModel( const AbstractModel* ) )
  );

  // Connect Appllication and MainWindow when selected model has been
  // changed.
  QObject::connect(
    qApp, SIGNAL( selectedModelChanged( const AbstractModel* ) ),
    this, SLOT( onSelectedModelChanged( const AbstractModel* ) )
  );
}

/*****************************************************************************/
void
MainWindow
::InitializeDockWidgets()
{
  AddWidgetToDock(
    new ColorSetupWidget( this ),
    VIDEO_COLOR_SETUP_DOCK,
    tr( "Video color setup" ),
    Qt::LeftDockWidgetArea
  );

  AddWidgetToDock(
    new ColorDynamicsWidget( this ),
    VIDEO_COLOR_DYNAMICS_DOCK,
    tr( "Video color dynamics" ),
    Qt::LeftDockWidgetArea
  );

#if 0

  QToolBox* toolBox = new QToolBox( this );

  toolBox->setObjectName( "mvd::VideoColorToolBox" );

  toolBox->addItem( new ColorSetupWidget( toolBox ), tr( "Video color setup" ) );
  toolBox->addItem( new ColorDynamicsWidget( toolBox ), tr( "Video color dynamics" ) );

  AddWidgetToDock(
    toolBox,
    "videoColorSettingsDock",
    tr( "Video color dynamics" ),
    Qt::LeftDockWidgetArea
  );
#endif
}

/*****************************************************************************/
void
MainWindow
::AddWidgetToDock( QWidget* widget,
		   const QString& dockName,
		   const QString& dockTitle,
		   Qt::DockWidgetArea dockArea )
{
  // New dock.
  QDockWidget* dockWidget = new QDockWidget( dockTitle, this );

  // You can use findChild( dockName ) to get dock-widget.
  dockWidget->setObjectName( dockName );
  dockWidget->setWidget( widget );

  /*
  qDebug() << dockWidget;
  qDebug() << widget;
  qDebug() << widget->parent();
  qDebug();
  */

  // Features.
  dockWidget->setFloating( true );
  dockWidget->setFeatures(
    QDockWidget::DockWidgetMovable |
    QDockWidget::DockWidgetFloatable
  );

  // Add dock.
  addDockWidget( dockArea, dockWidget );
}

/*****************************************************************************/
/* SLOTS                                                                     */
/*****************************************************************************/
void
MainWindow
::on_action_Open_activated()
{
  QString filename(
    QFileDialog::getOpenFileName( this, tr( "Open file..." ) )
  );

  if( filename.isNull() )
    {
    return;
    }

  // TODO: Replace with complex model (list of DatasetModel) when implemented.
  VectorImageModel* model = new VectorImageModel();

  model->setObjectName(
    "mvd::VectorImageModel('" + filename + "')"
  );

  // load file
  try
    {
    model->loadFile( filename );

    qobject_cast< Application* >( qApp )->SetModel( model );
    }
  catch( std::exception& exc )
    {
    delete model;
    model = NULL;

    QMessageBox::warning( this, tr("Exception!"), exc.what() );
    return;
    }
}

/*****************************************************************************/
void
MainWindow
::on_action_About_activated()
{
  AboutDialog aboutDialog( this );

  aboutDialog.exec();
}

/*****************************************************************************/
void
MainWindow
::onAboutToChangeSelectedModel( const AbstractModel* )
{
  Application* app = qobject_cast< Application* >( qApp );

  const VectorImageModel* vectorImageModel =
    qobject_cast< const VectorImageModel* >( app->GetModel() );

  if( vectorImageModel==NULL )
    {
    return;
    }

  // Disconnect previously selected model from view.
  QObject::disconnect(
    vectorImageModel,
    SIGNAL( settingsUpdated() ),
    // to:
    centralWidget(),
    SLOT( updateGL() )
  );

  QWidget* widget = GetColorSetupDock()->widget();

  if( widget==NULL )
    {
    return;
    }

  // Disconnect previously selected model from UI controller.
  QObject::disconnect(
    GetColorSetupDock()->widget(),
    SIGNAL( currentIndexChanged( ColorSetupWidget::Channel, int ) ),
    // from:
    vectorImageModel,
    SLOT( onCurrentIndexChanged( ColorSetupWidget::Channel, int ) )
  );
}

/*****************************************************************************/
void
MainWindow
::onSelectedModelChanged( const AbstractModel* model )
{
  ColorSetupWidget* colorSetupWidget =
    qobject_cast< ColorSetupWidget*  >( GetColorSetupDock()->widget() );

  const VectorImageModel* vectorImageModel =
    qobject_cast< const VectorImageModel* >( model );

  // Connect newly selected model to UI controller.
  QObject::connect(
    colorSetupWidget,
    SIGNAL( currentIndexChanged( ColorSetupWidget::Channel, int ) ),
    // to:
    vectorImageModel,
    SLOT( onCurrentIndexChanged( ColorSetupWidget::Channel, int ) )
  );

  // Connect newly selected model to view.
  QObject::connect(
    vectorImageModel,
    SIGNAL( settingsUpdated() ),
    // to:
    centralWidget(),
    SLOT( updateGL()  )
  );

  // Setup color-setup controller.
  colorSetupWidget->blockSignals( true );
  {
  // qDebug() << vectorImageModel->GetBandNames();

  colorSetupWidget->SetComponents( vectorImageModel->GetBandNames() );

  for( int i=0; i<ColorSetupWidget::CHANNEL_COUNT; ++i )
    {
    colorSetupWidget->SetCurrentIndex(
      ColorSetupWidget::Channel( i ),
      vectorImageModel->GetSettings().RgbChannel( i )
    );
    }
  }
  colorSetupWidget->blockSignals( false );

  // set the largest possible region of the image
  // TODO:  rename signal name when handling DataSets collections
  // TODO: move signal into mvdApplication and link it to DockWidget
  // and ImageView.
  emit largestPossibleRegionChanged(
    vectorImageModel->GetOutput( 0 )->GetLargestPossibleRegion()
  );
}

/*****************************************************************************/

} // end namespace 'mvd'
<|endoftext|>


<commit_before>#include <QtGui>
#include <QMessageBox>
#include <QFileDialog>
#include <QGraphicsScene>
#include <iostream>
#include <algorithm>
#include "main_window.hpp"

#include <QDebug>

using namespace Qt;

namespace map_marker {

	const double map_min = -5;
	const double map_max = 5;
	const double map_pix = 992;

	const QColor red = QColor(180, 40, 0);
	const QColor blue = QColor(30, 30, 140);
	const QColor green = QColor(50, 140, 30);
	const QColor orange = QColor(230, 120, 0);

	MainWindow::MainWindow(int argc, char** argv, QWidget *parent) : QMainWindow(parent), qnode(argc,argv) {
		ui.setupUi(this);
		qnode.init();

		// Connect list update to draw function
		QObject::connect(ui.tableWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(UpdateWindow()));
		QObject::connect(&qnode, SIGNAL(robotPosUpdated(geometry_msgs::Pose)), this, SLOT(UpdateRobotPose(geometry_msgs::Pose)));
		QObject::connect(&qnode, SIGNAL(rosShutdown()), QApplication::instance(), SLOT(quit()));

		// Load map image
		QString url = "/home/lars/git/ESA-PROJ/maps/legomap3-cropped.pgm";
		map = new QPixmap(url);

		// Ttable editing
		ui.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
		ui.tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
		ui.tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);

		// Create map image
		lblMapImage = new ClickableLabel(this);
		lblMapImage->setAlignment(Qt::AlignBottom | Qt::AlignRight);
		lblMapImage->setGeometry(QRect(0, 0, map_pix, map_pix));
		QObject::connect(lblMapImage, SIGNAL(clicked(QPoint)), this, SLOT(lblMapImage_clicked(QPoint)));

		// Set validator for input fields
		ui.inpCustomX->setValidator(new QDoubleValidator(-100, 100, 5, ui.inpCustomX));
		ui.inpCustomY->setValidator(new QDoubleValidator(-100, 100, 5, ui.inpCustomY));
		ui.inpCustomAngle->setValidator(new QDoubleValidator(0, 360, 5, ui.inpCustomAngle));

		// Panic button color
		ui.btnPanic->setStyleSheet("color: rgb(192,0,0);");

		// Add marker for testing
		Marker m(1.0, 2.0, 40.0, Navigation);
		AddMarker(m);

		UpdateTable();
	}

	MainWindow::~MainWindow() {
		delete map;
		delete lblMapImage;

	}

	void MainWindow::paintEvent(QPaintEvent *e) {

      Q_UNUSED(e);

      QPainter qp(this);

      qp.drawPixmap(0, 0, map_pix, map_pix, *map);
      drawMarkers(&qp);
    }

    void MainWindow::drawMarkers(QPainter *qp) {
		QPen pen(Qt::black, 2, Qt::SolidLine);
		//geometry_msgs::Pose pos = qnode.GetRobotPosition();
		QPoint p1;
		int selected = GetSelectedMarker();

		ROS_INFO("test %d", selected);

		pen.setWidth(10);

		for(int i = 0; i < markers.size(); i++) {

			if(i == selected) {
				pen.setColor(red);
			} else if(markers[i].GetType() == Workspace) {
				pen.setColor(green);
			} else {
				pen.setColor(orange);
			}

			p1.setX(ConvertRobotToPixel(markers[i].GetX()));
			p1.setY(ConvertRobotToPixel(markers[i].GetY()));

			qp->setPen(pen);
			qp->drawPoint(p1);
		}

		p1.setX(ConvertRobotToPixel(robotPose.position.x));
		p1.setY(ConvertRobotToPixel(robotPose.position.y));

		pen.setColor(blue);

		qp->setPen(pen);
		qp->drawPoint(p1);
    }

	void MainWindow::lblMapImage_clicked(QPoint a) {
		QString x = QString::number(ConvertPixelToRobot(a.x()));
		QString y = QString::number(ConvertPixelToRobot(a.y()));
		ui.inpCustomX->setText(x);
		ui.inpCustomY->setText(y);
	}

	void MainWindow::on_btnLoadYaml_clicked() {
		QFileDialog dialog(this);
		dialog.setFileMode(QFileDialog::AnyFile);
		dialog.setNameFilter(tr("Map image file (*.yaml)"));

		QStringList fileNames;
		if (dialog.exec())
		fileNames = dialog.selectedFiles();

		yaml.loadYaml(fileNames[0].toUtf8().constData());
		mapConfig.setFullConfigData(yaml.parsedYaml);

	}

	void MainWindow::on_btnLoadMap_clicked() {
		QFileDialog dialog(this);
		dialog.setFileMode(QFileDialog::AnyFile);
		dialog.setNameFilter(tr("Map image file (*.pbm *.pgm *.ppm)"));

		QStringList fileNames;
		if (dialog.exec())
		fileNames = dialog.selectedFiles();

		map = new QPixmap(fileNames[0]);
		UpdateWindow();
	}

	void MainWindow::on_btnWriteYaml_clicked() {
		yamlWriter.writeAllMarkers(markers, "/home/viki/git/ESA-PROJ/maps/markers.yaml");
	}

	void MainWindow::on_btnClearYaml_clicked() {
		ROS_ERROR("Not implemented yet :(");
	}

	void MainWindow::on_btnAddCurrentPose_clicked() {
		geometry_msgs::Pose pos = qnode.GetRobotPosition();

		MarkerType type;
		if(ui.radioNav->isChecked()) {
			type = Navigation;
		} else if (ui.radioWorkspace->isChecked()) {
			type = Workspace;
		}

		AddMarker(Marker(pos, type));
		UpdateTable();
	}

	void MainWindow::on_btnAddCustomPose_clicked() {
		double x = ui.inpCustomX->text().toDouble();
		double y = ui.inpCustomY->text().toDouble();
		double angle = ui.inpCustomAngle->text().toDouble();

		MarkerType type;
		if(ui.radioNav->isChecked()) {
			type = Navigation;
		} else if (ui.radioWorkspace->isChecked()) {
			type = Workspace;
		}

		AddMarker(Marker(x, y, angle, type));
		UpdateTable();
	}

	void MainWindow::on_btnMoveRobot_clicked() {
		int index = GetSelectedMarker();
		if(index == -1) {
			ROS_WARN("No marker selected");
			return;
		}
		Marker * m = &markers[index];
		qnode.MoveRobotToPose(m->GetPose());
	}

	void MainWindow::on_btnRemoveMarker_clicked() {
		int index = GetSelectedMarker();
		if(index == -1) {
			ROS_WARN("No marker selected");
			return;
		}
		markers.erase(markers.begin()+index);
		UpdateTable();
	}

	void MainWindow::on_btnPanic_clicked() {
		qnode.Panic();
		ROS_INFO("Panic button pressed, stopped robot...");
	}

	void MainWindow::on_btnMoveMarkerUp_clicked() {
		int selectedMarker = GetSelectedMarker();
		MoveMarkerUp(selectedMarker);
		UpdateTable();
	}

	void MainWindow::on_btnMoveMarkerDown_clicked() {
		int selectedMarker = GetSelectedMarker();
		MoveMarkerDown(selectedMarker);
		UpdateTable();
	}

	void MainWindow::on_btnClearAllMarkers_clicked() {
		markers.clear();
		UpdateTable();
	}

	int MainWindow::GetSelectedMarker() {
		int j = -1;
		QModelIndexList indexes = ui.tableWidget->selectionModel()->selectedRows();

		for (int i = 0; i < indexes.count(); ++i) {
			j = indexes.at(i).row();
		}

		return j;
	}

	void MainWindow::AddMarker(Marker marker) {
		markers.push_back(marker);
	}

	void MainWindow::MoveMarkerUp(int selectedMarker) {
		if(selectedMarker > 0) {
			std::swap(markers.at(selectedMarker), markers.at(selectedMarker - 1));
		} else {
			ROS_WARN("No marker selected");
		}
	}

	void MainWindow::MoveMarkerDown(int selectedMarker) {
		if(selectedMarker + 1 < markers.size() && selectedMarker >= 0) {
			std::swap(markers.at(selectedMarker), markers.at(selectedMarker + 1));
		} else {
			ROS_WARN("No marker selected");
		}
	}

	void MainWindow::UpdateTable() {
		ui.tableWidget->setRowCount(0);
		for(int i=0; i < markers.size(); i++) {
			ui.tableWidget->insertRow ( ui.tableWidget->rowCount() );
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 0, new QTableWidgetItem(QString::fromStdString(markers[i].GetTypeStr())));
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 1, new QTableWidgetItem(QString::number(markers[i].GetX())));
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 2, new QTableWidgetItem(QString::number(markers[i].GetY())));
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 3, new QTableWidgetItem(QString::number(markers[i].GetAngle())));
		}

		UpdateWindow();
	}

	void MainWindow::UpdateWindow() {
		// Update window - draw map and points again
		this->update();
	}

	void MainWindow::UpdateRobotPose(geometry_msgs::Pose p) {
		robotPose = p;
	}

	int MainWindow::ConvertRobotToPixel(double a) {
		return (a - map_min) * (map_pix - 0) / (map_max - map_min);
	}

	double MainWindow::ConvertPixelToRobot(int a) {
		return (a) * (map_max - map_min) / (map_pix) + map_min;
	}
}
<commit_msg>Fixed segfault<commit_after>#include <QtGui>
#include <QMessageBox>
#include <QFileDialog>
#include <QGraphicsScene>
#include <iostream>
#include <algorithm>
#include "main_window.hpp"

#include <QDebug>

using namespace Qt;

namespace map_marker {

	const double map_min = -5;
	const double map_max = 5;
	const double map_pix = 992;

	const QColor red = QColor(180, 40, 0);
	const QColor blue = QColor(30, 30, 140);
	const QColor green = QColor(50, 140, 30);
	const QColor orange = QColor(230, 120, 0);

	MainWindow::MainWindow(int argc, char** argv, QWidget *parent) : QMainWindow(parent), qnode(argc,argv) {
		ui.setupUi(this);
		qnode.init();

		// Connect list update to draw function
		QObject::connect(ui.tableWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(UpdateWindow()));
		QObject::connect(&qnode, SIGNAL(robotPosUpdated(geometry_msgs::Pose)), this, SLOT(UpdateRobotPose(geometry_msgs::Pose)));
		QObject::connect(&qnode, SIGNAL(rosShutdown()), QApplication::instance(), SLOT(quit()));

		// Load map image
		QString url = "/home/lars/git/ESA-PROJ/maps/legomap3-cropped.pgm";
		map = new QPixmap(url);

		// Ttable editing
		ui.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
		ui.tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
		ui.tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);

		// Create map image
		lblMapImage = new ClickableLabel(this);
		lblMapImage->setAlignment(Qt::AlignBottom | Qt::AlignRight);
		lblMapImage->setGeometry(QRect(0, 0, map_pix, map_pix));
		QObject::connect(lblMapImage, SIGNAL(clicked(QPoint)), this, SLOT(lblMapImage_clicked(QPoint)));

		// Set validator for input fields
		ui.inpCustomX->setValidator(new QDoubleValidator(-100, 100, 5, ui.inpCustomX));
		ui.inpCustomY->setValidator(new QDoubleValidator(-100, 100, 5, ui.inpCustomY));
		ui.inpCustomAngle->setValidator(new QDoubleValidator(0, 360, 5, ui.inpCustomAngle));

		// Panic button color
		ui.btnPanic->setStyleSheet("color: rgb(192,0,0);");

		// Add marker for testing
		Marker m(1.0, 2.0, 40.0, Navigation);
		AddMarker(m);

		UpdateTable();
	}

	MainWindow::~MainWindow() {
		delete map;
		delete lblMapImage;

	}

	void MainWindow::paintEvent(QPaintEvent *e) {

      Q_UNUSED(e);

      QPainter qp(this);

      qp.drawPixmap(0, 0, map_pix, map_pix, *map);
      drawMarkers(&qp);
    }

    void MainWindow::drawMarkers(QPainter *qp) {
		QPen pen(Qt::black, 2, Qt::SolidLine);
		//geometry_msgs::Pose pos = qnode.GetRobotPosition();
		QPoint p1;
		int selected = GetSelectedMarker();

		pen.setWidth(10);

		for(int i = 0; i < markers.size(); i++) {

			if(i == selected) {
				pen.setColor(red);
			} else if(markers[i].GetType() == Workspace) {
				pen.setColor(green);
			} else {
				pen.setColor(orange);
			}

			p1.setX(ConvertRobotToPixel(markers[i].GetX()));
			p1.setY(ConvertRobotToPixel(markers[i].GetY()));

			qp->setPen(pen);
			qp->drawPoint(p1);
		}

		p1.setX(ConvertRobotToPixel(robotPose.position.x));
		p1.setY(ConvertRobotToPixel(robotPose.position.y));

		pen.setColor(blue);

		qp->setPen(pen);
		qp->drawPoint(p1);
    }

	void MainWindow::lblMapImage_clicked(QPoint a) {
		QString x = QString::number(ConvertPixelToRobot(a.x()));
		QString y = QString::number(ConvertPixelToRobot(a.y()));
		ui.inpCustomX->setText(x);
		ui.inpCustomY->setText(y);
	}

	void MainWindow::on_btnLoadYaml_clicked() {
		QFileDialog dialog(this);
		dialog.setFileMode(QFileDialog::ExistingFile);
		dialog.setNameFilter(tr("Map yaml file (*.yaml)"));

		QStringList fileNames;
		if (dialog.exec()){
			fileNames = dialog.selectedFiles();
			yaml.loadYaml(fileNames[0].toUtf8().constData());
			mapConfig.setFullConfigData(yaml.parsedYaml);
		} else {
			ROS_ERROR("No file selected, nothing loaded");
		}
	}

	void MainWindow::on_btnLoadMap_clicked() {
		QFileDialog dialog(this);
		dialog.setFileMode(QFileDialog::ExistingFile);
		dialog.setNameFilter(tr("Map image file (*.pbm *.pgm *.ppm)"));

		QStringList fileNames;
		if (dialog.exec()) {
			fileNames = dialog.selectedFiles();
			map = new QPixmap(fileNames[0]);
			UpdateWindow();
		} else {
			ROS_ERROR("No file selected, nothing loaded");
		}
	}

	void MainWindow::on_btnWriteYaml_clicked() {
		yamlWriter.writeAllMarkers(markers, "/home/viki/git/ESA-PROJ/maps/markers.yaml");
	}

	void MainWindow::on_btnClearYaml_clicked() {
		ROS_ERROR("Not implemented yet :(");
	}

	void MainWindow::on_btnAddCurrentPose_clicked() {
		geometry_msgs::Pose pos = qnode.GetRobotPosition();

		MarkerType type;
		if(ui.radioNav->isChecked()) {
			type = Navigation;
		} else if (ui.radioWorkspace->isChecked()) {
			type = Workspace;
		}

		AddMarker(Marker(pos, type));
		UpdateTable();
	}

	void MainWindow::on_btnAddCustomPose_clicked() {
		double x = ui.inpCustomX->text().toDouble();
		double y = ui.inpCustomY->text().toDouble();
		double angle = ui.inpCustomAngle->text().toDouble();

		MarkerType type;
		if(ui.radioNav->isChecked()) {
			type = Navigation;
		} else if (ui.radioWorkspace->isChecked()) {
			type = Workspace;
		}

		AddMarker(Marker(x, y, angle, type));
		UpdateTable();
	}

	void MainWindow::on_btnMoveRobot_clicked() {
		int index = GetSelectedMarker();
		if(index == -1) {
			ROS_WARN("No marker selected");
			return;
		}
		Marker * m = &markers[index];
		qnode.MoveRobotToPose(m->GetPose());
	}

	void MainWindow::on_btnRemoveMarker_clicked() {
		int index = GetSelectedMarker();
		if(index == -1) {
			ROS_WARN("No marker selected");
			return;
		}
		markers.erase(markers.begin()+index);
		UpdateTable();
	}

	void MainWindow::on_btnPanic_clicked() {
		qnode.Panic();
		ROS_INFO("Panic button pressed, stopped robot...");
	}

	void MainWindow::on_btnMoveMarkerUp_clicked() {
		int selectedMarker = GetSelectedMarker();
		MoveMarkerUp(selectedMarker);
		UpdateTable();
	}

	void MainWindow::on_btnMoveMarkerDown_clicked() {
		int selectedMarker = GetSelectedMarker();
		MoveMarkerDown(selectedMarker);
		UpdateTable();
	}

	void MainWindow::on_btnClearAllMarkers_clicked() {
		markers.clear();
		UpdateTable();
	}

	int MainWindow::GetSelectedMarker() {
		int j = -1;
		QModelIndexList indexes = ui.tableWidget->selectionModel()->selectedRows();

		for (int i = 0; i < indexes.count(); ++i) {
			j = indexes.at(i).row();
		}

		return j;
	}

	void MainWindow::AddMarker(Marker marker) {
		markers.push_back(marker);
	}

	void MainWindow::MoveMarkerUp(int selectedMarker) {
		if(selectedMarker > 0) {
			std::swap(markers.at(selectedMarker), markers.at(selectedMarker - 1));
		} else {
			ROS_WARN("No marker selected");
		}
	}

	void MainWindow::MoveMarkerDown(int selectedMarker) {
		if(selectedMarker + 1 < markers.size() && selectedMarker >= 0) {
			std::swap(markers.at(selectedMarker), markers.at(selectedMarker + 1));
		} else {
			ROS_WARN("No marker selected");
		}
	}

	void MainWindow::UpdateTable() {
		ui.tableWidget->setRowCount(0);
		for(int i=0; i < markers.size(); i++) {
			ui.tableWidget->insertRow ( ui.tableWidget->rowCount() );
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 0, new QTableWidgetItem(QString::fromStdString(markers[i].GetTypeStr())));
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 1, new QTableWidgetItem(QString::number(markers[i].GetX())));
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 2, new QTableWidgetItem(QString::number(markers[i].GetY())));
			ui.tableWidget->setItem(ui.tableWidget->rowCount()-1, 3, new QTableWidgetItem(QString::number(markers[i].GetAngle())));
		}

		UpdateWindow();
	}

	void MainWindow::UpdateWindow() {
		// Update window - draw map and points again
		this->update();
	}

	void MainWindow::UpdateRobotPose(geometry_msgs::Pose p) {
		robotPose = p;
	}

	int MainWindow::ConvertRobotToPixel(double a) {
		return (a - map_min) * (map_pix - 0) / (map_max - map_min);
	}

	double MainWindow::ConvertPixelToRobot(int a) {
		return (a) * (map_max - map_min) / (map_pix) + map_min;
	}
}
<|endoftext|>


<commit_before>/** Test harness for TexPHPUtil::DeserialisePHPObject().
 */
#include <iostream>
#include <memory>
#include <string>
#include <stdexcept>
#include <typeinfo>
#include <cstdlib>
#include <cstdio>
#include "Compiler.h"
#include "PHPUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "usage: " << ::progname << " serialised_object_input_file\n";
    std::exit(EXIT_FAILURE);
}

void PrintString(const std::shared_ptr<PHPUtil::DataType> &string_candidate, const unsigned indent) {
    const PHPUtil::String * const string(dynamic_cast<PHPUtil::String *>(string_candidate.get()));
    if (unlikely(string == nullptr))
        Error("in PrintString: expected PHPUtil::String, found "
              + std::string(typeid(*string_candidate).name()) + " instead!");

    std::cout << std::string(indent, ' ') << "String: " << string->getName() << '(' << string->getValue() << ")\n";
}

void PrintInteger(const std::shared_ptr<PHPUtil::DataType> &integer_candidate, const unsigned indent) {
    const PHPUtil::Integer * const integer(dynamic_cast<PHPUtil::Integer *>(integer_candidate.get()));
    if (unlikely(integer == nullptr))
        Error("in PrintInteger: expected PHPUtil::Integer, found "
              + std::string(typeid(*integer_candidate).name()) + " instead!");

    std::cout << std::string(indent, ' ') << "Integer: " << integer->getName() << '(' << integer->getValue() << ")\n";
}

void PrintFloat(const std::shared_ptr<PHPUtil::DataType> &float_candidate, const unsigned indent) {
    const PHPUtil::Float * const flt(dynamic_cast<PHPUtil::Float *>(float_candidate.get()));
    if (unlikely(flt == nullptr))
        Error("in PrintFloat: expected PHPUtil::Float, found "
              + std::string(typeid(*float_candidate).name()) + " instead!");

    std::cout << std::string(indent, ' ') << "Float: " << flt->getName() << '(' << flt->getValue() << ")\n";
}

// Forward declaration:
void PrintObject(const std::shared_ptr<PHPUtil::DataType> &object_candidate, const unsigned indent);

void PrintArray(const std::shared_ptr<PHPUtil::DataType> &array_candidate, const unsigned indent) {
    const PHPUtil::Array * const array(dynamic_cast<PHPUtil::Array *>(array_candidate.get()));
    if (unlikely(array == nullptr))
        Error("in PrintArray: expected PHPUtil::Array, found " + std::string(typeid(*array_candidate).name())
              + " instead!");

    std::cout << std::string(indent, ' ') << "Array: " << array->getName() << "(size:" << array->size() << ")\n";

    for (auto entry(array->cbegin()); entry != array->cend(); ++entry) {
        std::cout << std::string(indent + 2, ' ') << "Index(" << entry->first << ")\n";
        switch (entry->second->getType()) {
        case PHPUtil::Type::OBJECT:
            PrintObject(entry->second, indent + 2);
            break;
        case PHPUtil::Type::ARRAY:
            PrintArray(entry->second, indent + 2);
            break;
        case PHPUtil::Type::STRING:
            PrintString(entry->second, indent + 2);
            break;
        case PHPUtil::Type::INTEGER:
            PrintInteger(entry->second, indent + 2);
            break;
        case PHPUtil::Type::FLOAT:
            PrintFloat(entry->second, indent + 2);
            break;
        }
    }
}

void PrintObject(const std::shared_ptr<PHPUtil::DataType> &object_candidate, const unsigned indent = 0) {
    const PHPUtil::Object * const object(dynamic_cast<PHPUtil::Object *>(object_candidate.get()));
    if (unlikely(object == nullptr))
        Error("in PrintObject: expected PHPUtil::Object, found " + std::string(typeid(*object_candidate).name())
              + " instead!");

    std::cout << std::string(indent, ' ') << "Object: ";
    const std::string &name(object->getName());
    std::cout << (name.empty() ? "*top level*" : name) << '(' << object->getClass() << ")\n";

    for (auto entry(object->cbegin()); entry != object->cend(); ++entry) {
        switch (entry->second->getType()) {
        case PHPUtil::Type::OBJECT:
            PrintObject(entry->second, indent + 2);
            break;
        case PHPUtil::Type::ARRAY:
            PrintArray(entry->second, indent + 2);
            break;
        case PHPUtil::Type::STRING:
            PrintString(entry->second, indent + 2);
            break;
        case PHPUtil::Type::INTEGER:
            PrintInteger(entry->second, indent + 2);
            break;
        case PHPUtil::Type::FLOAT:
            PrintFloat(entry->second, indent + 2);
            break;
        }
    }
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];
    if (argc != 2)
        Usage();

    const std::string input_filename(argv[1]);
    FILE * const input(std::fopen(input_filename.c_str(), "rbm"));
    if (input == nullptr)
        Error("can't open \"" + input_filename + "\" for reading!");

    const size_t MAX_BUFFER_SIZE(10240);
    char buffer[MAX_BUFFER_SIZE];
    const size_t actual_size(std::fread(buffer, 1, sizeof buffer, input));
    if (std::ferror(input) != 0)
        Error("a read error occurred!");

    try {
        std::shared_ptr<PHPUtil::DataType> php_object(
            PHPUtil::DeserialisePHPObject(std::string(buffer, actual_size)));
        PrintObject(php_object);
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }

    std::fclose(input);
}
<commit_msg>Adpated for a newer compiler version.<commit_after>/** Test harness for TexPHPUtil::DeserialisePHPObject().
 */
#include <iostream>
#include <memory>
#include <string>
#include <stdexcept>
#include <typeinfo>
#include <cstdlib>
#include <cstdio>
#include "Compiler.h"
#include "PHPUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "usage: " << ::progname << " serialised_object_input_file\n";
    std::exit(EXIT_FAILURE);
}

void PrintString(const std::shared_ptr<PHPUtil::DataType> &string_candidate, const unsigned indent) {
    const PHPUtil::String * const string(dynamic_cast<PHPUtil::String *>(string_candidate.get()));
    if (unlikely(string == nullptr))
        Error("in PrintString: expected PHPUtil::String, found "
              + std::string(typeid(string_candidate).name()) + " instead!");

    std::cout << std::string(indent, ' ') << "String: " << string->getName() << '(' << string->getValue() << ")\n";
}

void PrintInteger(const std::shared_ptr<PHPUtil::DataType> &integer_candidate, const unsigned indent) {
    const PHPUtil::Integer * const integer(dynamic_cast<PHPUtil::Integer *>(integer_candidate.get()));
    if (unlikely(integer == nullptr))
        Error("in PrintInteger: expected PHPUtil::Integer, found "
              + std::string(typeid(integer_candidate).name()) + " instead!");

    std::cout << std::string(indent, ' ') << "Integer: " << integer->getName() << '(' << integer->getValue() << ")\n";
}

void PrintFloat(const std::shared_ptr<PHPUtil::DataType> &float_candidate, const unsigned indent) {
    const PHPUtil::Float * const flt(dynamic_cast<PHPUtil::Float *>(float_candidate.get()));
    if (unlikely(flt == nullptr))
        Error("in PrintFloat: expected PHPUtil::Float, found "
              + std::string(typeid(float_candidate).name()) + " instead!");

    std::cout << std::string(indent, ' ') << "Float: " << flt->getName() << '(' << flt->getValue() << ")\n";
}

// Forward declaration:
void PrintObject(const std::shared_ptr<PHPUtil::DataType> &object_candidate, const unsigned indent);

void PrintArray(const std::shared_ptr<PHPUtil::DataType> &array_candidate, const unsigned indent) {
    const PHPUtil::Array * const array(dynamic_cast<PHPUtil::Array *>(array_candidate.get()));
    if (unlikely(array == nullptr))
        Error("in PrintArray: expected PHPUtil::Array, found " + std::string(typeid(array_candidate).name())
              + " instead!");

    std::cout << std::string(indent, ' ') << "Array: " << array->getName() << "(size:" << array->size() << ")\n";

    for (auto entry(array->cbegin()); entry != array->cend(); ++entry) {
        std::cout << std::string(indent + 2, ' ') << "Index(" << entry->first << ")\n";
        switch (entry->second->getType()) {
        case PHPUtil::Type::OBJECT:
            PrintObject(entry->second, indent + 2);
            break;
        case PHPUtil::Type::ARRAY:
            PrintArray(entry->second, indent + 2);
            break;
        case PHPUtil::Type::STRING:
            PrintString(entry->second, indent + 2);
            break;
        case PHPUtil::Type::INTEGER:
            PrintInteger(entry->second, indent + 2);
            break;
        case PHPUtil::Type::FLOAT:
            PrintFloat(entry->second, indent + 2);
            break;
        }
    }
}

void PrintObject(const std::shared_ptr<PHPUtil::DataType> &object_candidate, const unsigned indent = 0) {
    const PHPUtil::Object * const object(dynamic_cast<PHPUtil::Object *>(object_candidate.get()));
    if (unlikely(object == nullptr))
        Error("in PrintObject: expected PHPUtil::Object, found " + std::string(typeid(object_candidate).name())
              + " instead!");

    std::cout << std::string(indent, ' ') << "Object: ";
    const std::string &name(object->getName());
    std::cout << (name.empty() ? "*top level*" : name) << '(' << object->getClass() << ")\n";

    for (auto entry(object->cbegin()); entry != object->cend(); ++entry) {
        switch (entry->second->getType()) {
        case PHPUtil::Type::OBJECT:
            PrintObject(entry->second, indent + 2);
            break;
        case PHPUtil::Type::ARRAY:
            PrintArray(entry->second, indent + 2);
            break;
        case PHPUtil::Type::STRING:
            PrintString(entry->second, indent + 2);
            break;
        case PHPUtil::Type::INTEGER:
            PrintInteger(entry->second, indent + 2);
            break;
        case PHPUtil::Type::FLOAT:
            PrintFloat(entry->second, indent + 2);
            break;
        }
    }
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];
    if (argc != 2)
        Usage();

    const std::string input_filename(argv[1]);
    FILE * const input(std::fopen(input_filename.c_str(), "rbm"));
    if (input == nullptr)
        Error("can't open \"" + input_filename + "\" for reading!");

    const size_t MAX_BUFFER_SIZE(10240);
    char buffer[MAX_BUFFER_SIZE];
    const size_t actual_size(std::fread(buffer, 1, sizeof buffer, input));
    if (std::ferror(input) != 0)
        Error("a read error occurred!");

    try {
        std::shared_ptr<PHPUtil::DataType> php_object(
            PHPUtil::DeserialisePHPObject(std::string(buffer, actual_size)));
        PrintObject(php_object);
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }

    std::fclose(input);
}
<|endoftext|>