text:
// Bring in my package's API, which is what I'm testing
#include <bsplines/BSpline.hpp>

// Bring in gtest
#include <gtest/gtest.h>
#include <boost/cstdint.hpp>

// Helpful functions from schweizer_messer
#include <sm/eigen/NumericalDiff.hpp>
#include <sm/eigen/gtest.hpp>

#include <boost/tuple/tuple.hpp>

using namespace bsplines;

struct BSplineJacobianFunctor {
    // Necessary for eigen fixed sized type member variables.
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    typedef Eigen::VectorXd input_t;
    typedef Eigen::MatrixXd jacobian_t;
    typedef Eigen::VectorXd value_t;
    typedef double scalar_t;

    BSplineJacobianFunctor(BSpline bs, double t, int d) : bs_(bs), t_(t), d_(d) {}

    input_t update(const input_t& x, int c, double delta) {
        input_t xnew = x;
        xnew[c] += delta;
        return xnew;
    }

    Eigen::VectorXd operator()(const Eigen::VectorXd& c) {
        bs_.setLocalCoefficientVector(t_, c);
        return bs_.evalD(t_, d_);
    }

    BSpline bs_;
    double t_;
    int d_;
};

// Check that the Jacobian calculation is correct.
TEST(SplineTestSuite, testBSplineJacobian) {
    const int segments = 2;
    for (int order = 2; order < 10; order++) {
        BSpline bs(order);
        int nk = bs.numKnotsRequired(segments);
        std::vector<double> knots;
        for (int i = 0; i < nk; i++) {
            knots.push_back(i);
        }

        for (int dim = 1; dim < 4; dim++) {
            int nc = bs.numCoefficientsRequired(segments);
            Eigen::MatrixXd C = Eigen::MatrixXd::Random(dim, nc);
            bs.setKnotsAndCoefficients(knots, C);

            for (int derivative = 0; derivative < order; derivative++) {
                for (double t = bs.t_min(); t < bs.t_max(); t += 0.1) {
                    BSplineJacobianFunctor f(bs, t, derivative);
                    sm::eigen::NumericalDiff<BSplineJacobianFunctor> nd(f);
                    Eigen::MatrixXd estJ = nd.estimateJacobian(bs.localCoefficientVector(t));
                    Eigen::MatrixXd J;
                    Eigen::VectorXd v;
                    boost::tie(v, J) = bs.evalDAndJacobian(t, derivative);

                    sm::eigen::assertNear(J, estJ, 1e-5, SM_SOURCE_FILE_POS);
                }
            }
        }
    }
}

TEST(SplineTestSuite, testCoefficientMap) {
    const int order = 4;
    const int segments = 10;
    const int dim = 5;
    BSpline bs(order);
    int nk = bs.numKnotsRequired(segments);
    int nc = bs.numCoefficientsRequired(segments);

    std::vector<double> knots;
    for (int i = 0; i < nk; i++) {
        knots.push_back(i);
    }

    Eigen::MatrixXd C = Eigen::MatrixXd::Random(dim, nc);
    bs.setKnotsAndCoefficients(knots, C);

    const Eigen::MatrixXd& CC = bs.coefficients();
    for (int i = 0; i < bs.numVvCoefficients(); i++) {
        Eigen::Map<Eigen::VectorXd> m = bs.vvCoefficientVector(i);
        // Test pass by value...
        Eigen::Map<Eigen::Matrix<double, 5, 1> > m2 = bs.fixedSizeVvCoefficientVector<dim>(i);
        for (int r = 0; r < m.size(); ++r) {
            ASSERT_TRUE(&m[r] == &CC(r, i));
            ASSERT_TRUE(&m[r] == &m2[r]);
            m[r] = rand();
            ASSERT_EQ(m[r], CC(r, i));
            ASSERT_EQ(m[r], m2[r]);
        }
    }
}

TEST(SplineTestSuite, testGetBi) {
    const int order = 4;
    const int segments = 10;
    const double startTime = 0;
    const double endTime = 5;
    const int numTimeSteps = 43;
    BSpline bs(order);
    bs.initConstantSpline(startTime, endTime, segments, Eigen::VectorXd::Zero(1));

    for (int i = 0; i <= numTimeSteps; i++) {
        double t = startTime + (endTime - startTime) * ((double)i / numTimeSteps);
        Eigen::VectorXd localBiVector = bs.getLocalBiVector(t);
        SM_ASSERT_NEAR(std::runtime_error, localBiVector.sum(), 1.0, 1e-10,
                       "the bis at a given time should always sum up to 1")
        Eigen::VectorXd biVector = bs.getBiVector(t);
        SM_ASSERT_NEAR(std::runtime_error, localBiVector.sum(), 1.0, 1e-10,
                       "the bis at a given time should always sum up to 1")

        Eigen::VectorXd cumulativeBiVector = bs.getCumulativeBiVector(t);
        Eigen::VectorXd localCumulativeBiVector = bs.getLocalCumulativeBiVector(t);

        Eigen::VectorXi localCoefficientVectorIndices = bs.localCoefficientVectorIndices(t);
        int firstIndex = localCoefficientVectorIndices[0];
        SM_ASSERT_EQ(std::runtime_error, localCoefficientVectorIndices.size(), order,
                     "localCoefficientVectorIndices has to have exactly " << order << " entries");

        for (int j = 0; j < order; j++) {
            SM_ASSERT_EQ(std::runtime_error, localCoefficientVectorIndices[j], firstIndex + j,
                         "localCoefficientVectorIndices have to be successive");
        }

        for (int j = 0, n = biVector.size(); j < n; j++) {
            if (j < firstIndex) {
                SM_ASSERT_EQ(std::runtime_error, biVector[j], 0, "");
                SM_ASSERT_EQ(std::runtime_error, cumulativeBiVector[j], 1, "");
            } else if (j < firstIndex + order) {
                SM_ASSERT_EQ(std::runtime_error, biVector[j], localBiVector[j - firstIndex],
                             "localBiVector should be a slice of the biVector");
                SM_ASSERT_EQ(std::runtime_error, cumulativeBiVector[j], localCumulativeBiVector[j - firstIndex],
                             "localCumulativeBiVector must be a slice of the cumulativeBiVector");
                SM_ASSERT_NEAR(
                    std::runtime_error, cumulativeBiVector[j],
                    localBiVector.segment(j - firstIndex, order - (j - firstIndex)).sum(), 1e-13,
                    "cumulativeBiVector must be the sum of the localBiVector where it overlaps, but it is not at "
                        << (j - firstIndex) << " (localBiVector=" << localBiVector << ")");
            } else {
                SM_ASSERT_EQ(std::runtime_error, biVector[j], 0, "at position " << j);
                SM_ASSERT_EQ(std::runtime_error, cumulativeBiVector[j], 0, "at position " << j);
            }
        }
    }
}

// TEST(SplineTestSuite, testBSplineCubic)
// {
//   double knots_d[] = {-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
//   double control_d[] = { 0.0,1.0, 2.0, 3.0 };

//   std::vector<double> knots;
//   knots.insert(knots.begin(),knots_d,knots_d + (sizeof(knots_d)/sizeof(double)));

//   std::vector<double> control;
//   control.insert(control.begin(),control_d,control_d + (sizeof(control_d)/sizeof(double)));

//   BSpline<double,4> s(knots,control);

//   for(double i = 1.0; i < 2.0; i += 0.1)
//     {
//       //std::cout << "s(" << i << ") = " << s.eval(i) << std::endl;
//       ASSERT_DOUBLE_EQ(s.eval(i),i);
//       //std::cout << "D1 s(" << i << ") = " << s.evalD(i,1) << std::endl;
//       //std::cout << "D2 s(" << i << ") = " << s.evalD(i,2) << std::endl;
//       //std::cout << "D3 s(" << i << ") = " << s.evalD(i,3) << std::endl;
//       //std::cout << "D4 s(" << i << ") = " << s.evalD(i,4) << std::endl;
//     }

//   // Check the bounds of evaluation.
//   // Lower bound.
//   ASSERT_THROW(s.eval(0.999),Exception);
//   ASSERT_NO_THROW(s.eval(1.0));
//   // Upper bound
//   ASSERT_NO_THROW(s.eval(1.999));
//   ASSERT_THROW(s.eval(2.0),Exception);

// }

// TEST(SplineTestSuite, testBSplineLinear)
// {
//   double knots_d[] = {-1.0, 0.0, 1.0, 2.0, 3.0, 4.0 };
//   double control_d[] = { 0.0,1.0, 2.0, 3.0 };

//   std::vector<double> knots;
//   knots.insert(knots.begin(),knots_d,knots_d + (sizeof(knots_d)/sizeof(double)));

//   std::vector<double> control;
//   control.insert(control.begin(),control_d,control_d + (sizeof(control_d)/sizeof(double)));

//   BSpline<double,2> s(knots,control);

//   for(double i = 0.0; i < 3.0; i += 0.1)
//     {
//       //std::cout << "s(" << i << ") = " << s.eval(i) << std::endl;
//       ASSERT_DOUBLE_EQ(s.eval(i),i);
//     }

//   // Check the bounds of evaluation.
//   // Lower bound.
//   ASSERT_THROW(s.eval(-0.0001),Exception);
//   ASSERT_NO_THROW(s.eval(0.0));
//   // Upper bound
//   ASSERT_NO_THROW(s.eval(2.999));
//   ASSERT_THROW(s.eval(3.0),Exception);

// }

// TEST(SplineTestSuite, testBSplineQuadratic)
// {
//   double knots_d[] = {-1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
//   double control_d[] = { 0.5,1.5, 2.5, 3.5 };

//   std::vector<double> knots;
//   knots.insert(knots.begin(),knots_d,knots_d + (sizeof(knots_d)/sizeof(double)));

//   std::vector<double> control;
//   control.insert(control.begin(),control_d,control_d + (sizeof(control_d)/sizeof(double)));

//   BSpline<double,3> s(knots,control);

//     for(double i = 1.0; i < 3.0; i += 0.1)
//     {
//       //std::cout << "s(" << i << ") = " << s.eval(i) << std::endl;
//       ASSERT_DOUBLE_EQ(s.eval(i),i);
//     }

//     // Check the bounds of evaluation.
//   // Lower bound.
//   ASSERT_THROW(s.eval(0.999),Exception);
//   ASSERT_NO_THROW(s.eval(1.0));
//   // Upper bound
//   ASSERT_NO_THROW(s.eval(2.999));
//   ASSERT_THROW(s.eval(3.0),Exception);
// }

max_stars_repo_name: chengfzy/kalibr

max_issues_repo_name: chengfzy/kalibr

max_forks_repo_name: chengfzy/kalibr


text:
#include <Eigen/Core>
#include <Eigen/SparseCore>
#include <Eigen/QR>
#include <Eigen/Householder>
#include <Eigen/SVD>
#include "toperations.h"

using namespace std;
using namespace Eigen;

/* QR */
void tQR::fwd(){
	int i=0;
	Segment xs = c->xt->segment(0, ccols);
	assert((*c->edgesOut.begin())->n2 == c);
    Edge* eself = *(c->edgesOut.begin());
	MatrixXd R = (eself->A21)->topRows(xs.size());

	trsv(&R, &xs, CblasUpper, CblasTrans, CblasNonUnit); // Do inv(R')*xs
	for (auto e: c->edgesIn){
		assert(e->A21 != nullptr);
		int s = A12_indices[i];
		assert(e->A21->cols() == s);
		(e->n1->xt->segment(0, s)) -= (e->A21->topRows(ccols)).transpose()*xs;
		++i;
	}
}

void tQR::bwd(){
	MatrixXd Q = MatrixXd::Zero(nrows, ncols);
	VectorXd xc = VectorXd::Zero(nrows);

	int curr_row = 0;
	int i=0;
	for (auto e: c->edgesOut){
		if (e->A21 != nullptr){
			int s = A21_indices[i];
			xc.segment(curr_row, s) = e->n2->xt->segment(0, s);
			Q.middleRows(curr_row, s) = *(e->A21);
			curr_row += s;
			++i;
		}
	}

	larfb(&Q, c->get_T(), &xc, 'L', 'N', 'F', 'C');
	curr_row = 0;
	i=0;
	for (auto e: c->edgesOut){
		if (e->A21 != nullptr){
			int s = A21_indices[i];
			e->n2->xt->segment(0, s) = xc.segment(curr_row, s);
			curr_row += s;
			++i;
		}
	}
}

/* Reassign rows */
void tReassign::bwd(){
	// cout << c->get_id() << " " << n->get_id() << endl;
	assert(indices.size() == nrows);
	for (int i= nstart; i < nstart+nrows; ++i){
		(*c->xt)[indices[i-nstart]] = (*n->xt)[i];
	}

}

/* Scaling */
void tScale::fwd(){
    trsv(R, &xs, CblasUpper, CblasTrans, CblasNonUnit);
}

void tScaleD::fwd(){
	MatrixXd R = Q->topRows(xs.size());
	trsv(&R, &xs, CblasUpper, CblasTrans, CblasNonUnit);
}

/* Sparsification using Orthogonal transformations */
void tOrthogonal::fwd(){ormqr_trans(V, tau, &xs);}

void tOrthogonalD::fwd(){
	ormqr_trans(V, tau, &xs);
}
void tOrthogonalD::bwd(){
	ormqr_notrans(V, tau, &xs);
}

/* Merging in the cluster heirarchy */
void tMerge::fwd(){
	int k=0;
	for (auto c: parent->children){
		for (int i=0; i < c->cols(); ++i){
			(*parent->xt)[k] = (*c->xt)[i];
			++k;
		}
	}
}

void tMerge::bwd(){
	int k=0;
	for (auto c: parent->children){
		for (int i=0; i < c->rows(); ++i){
			(*c->xt)[i] = (*parent->xt)[k];
			++k;
		}
	}
	// assert(k== parent->get_x()->size());
}

/* Split between coarse and fine nodes */
void tSplit::fwd(){xsf = xsc_head.bottomRows(xsf.size());}
void tSplit::bwd(){xsc.bottomRows(xsf.size()) = xsf;}

void tSplitD::fwd(){
	xsf = xsc.middleRows(rank, ccols-rank);
	VectorXd xsc_rem = xsc.bottomRows(crows-ccols);
	xsc.middleRows(rank, crows-ccols) = xsc_rem;
	xsc.bottomRows(ccols-rank) = xsf;
}
void tSplitD::bwd(){
	// VectorXd xsf = xsc.bottomRows(ccols-rank);
	VectorXd xsc_rem = xsc.middleRows(rank, crows-ccols);
	xsc.middleRows(rank, ccols-rank) = xsf;
	xsc.bottomRows(crows-ccols) = xsc_rem;
}

ext: cpp


text:
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <iomanip>
#include <array>

#include <boost/nondet_random.hpp>
#include <boost/random.hpp>
#include <boost/timer.hpp>
#include <boost/progress.hpp>

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/variance.hpp>

extern "C"
{
#include "sha1.h"
#include "ubc_check.h"

	void ubc_check_verify(const uint32_t W[80], uint32_t dvmask[DVMASKSIZE]);

	void nc_callback(uint64_t byteoffset, const uint32_t ihvin1[5], const uint32_t ihvin2[5], const uint32_t m1[80], const uint32_t m2[80])
	{
		unsigned i;
		printf("Detected near-collision block:\n");
		printf("IHVin1  = { 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x };\n", ihvin1[0], ihvin1[1], ihvin1[2], ihvin1[3], ihvin1[4]);
		printf("IHVin2  = { 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x };\n", ihvin2[0], ihvin2[1], ihvin2[2], ihvin2[3], ihvin2[4]);
		printf("MSGBLK1 = { 0x%08x", m1[0]);
		for (i = 1; i < 16; ++i)
			printf(", 0x%08x", m1[i]);
		printf(" };\n");
		printf("MSGBLK2 = { 0x%08x", m2[0]);
		for (i = 1; i < 16; ++i)
			printf(", 0x%08x", m2[i]);
		printf(" };\n");
	}

	// the SHA-1 context
	typedef struct {
		uint64_t total;
		uint32_t ihv[5];
		unsigned char buffer[64];
		int bigendian;
	} SHA1reg_CTX;

	#define LE32_TO_BE32(X) \
		{X = ((X << 8) & 0xFF00FF00) | ((X >> 8) & 0xFF00FF); X = (X << 16) | (X >> 16);}

	void swap_bytes(uint32_t val[16])
	{
		LE32_TO_BE32(val[0]);
        	LE32_TO_BE32(val[1]);
	        LE32_TO_BE32(val[2]);
        	LE32_TO_BE32(val[3]);
        	LE32_TO_BE32(val[4]);
        	LE32_TO_BE32(val[5]);
        	LE32_TO_BE32(val[6]);
        	LE32_TO_BE32(val[7]);
        	LE32_TO_BE32(val[8]);
        	LE32_TO_BE32(val[9]);
        	LE32_TO_BE32(val[10]);
        	LE32_TO_BE32(val[11]);
        	LE32_TO_BE32(val[12]);
        	LE32_TO_BE32(val[13]);
        	LE32_TO_BE32(val[14]);
        	LE32_TO_BE32(val[15]);
	}

#define Rotate_right(x,n) (((x)>>(n))|((x)<<(32-(n))))
#define Rotate_left(x,n)  (((x)<<(n))|((x)>>(32-(n))))

#define sha1_f1(b,c,d) ((d)^((b)&((c)^(d))))
#define sha1_f2(b,c,d) ((b)^(c)^(d))
#define sha1_f3(b,c,d) (((b) & ((c)|(d))) | ((c)&(d)))
#define sha1_f4(b,c,d) ((b)^(c)^(d))

#define HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, m, t) \
	{ e += Rotate_left(a, 5) + sha1_f1(b,c,d) + 0x5A827999 + m[t]; b = Rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, m, t) \
	{ e += Rotate_left(a, 5) + sha1_f2(b,c,d) + 0x6ED9EBA1 + m[t]; b = Rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, m, t) \
	{ e += Rotate_left(a, 5) + sha1_f3(b,c,d) + 0x8F1BBCDC + m[t]; b = Rotate_left(b, 30); }
#define HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, m, t) \
	{ e += Rotate_left(a, 5) + sha1_f4(b,c,d) + 0xCA62C1D6 + m[t]; b = Rotate_left(b, 30); }

void sha1_compression(uint32_t ihv[5], const uint32_t m[16])
{
	uint32_t W[80];
	uint32_t a,b,c,d,e;
	unsigned i;

	memcpy(W, m, 16 * 4);
	for (i = 16; i < 80; ++i)
		W[i] = Rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);

	a = ihv[0]; b = ihv[1]; c = ihv[2]; d = ihv[3]; e = ihv[4];

	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 0);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 1);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 2);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 3);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 4);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 5);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 6);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 7);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 8);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 9);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 10);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 11);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 12);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 13);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 14);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 15);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 16);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 17);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 18);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 19);

	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 20);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 21);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 22);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 23);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 24);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 25);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 26);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 27);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 28);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 29);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 30);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 31);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 32);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 33);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 34);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 35);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 36);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 37);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 38);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 39);

	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 40);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 41);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 42);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 43);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 44);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 45);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 46);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 47);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 48);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 49);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 50);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 51);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 52);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 53);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 54);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 55);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 56);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 57);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 58);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 59);

	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 60);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 61);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 62);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 63);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 64);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 65);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 66);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 67);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 68);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 69);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 70);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 71);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 72);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 73);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 74);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 75);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 76);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 77);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 78);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 79);

	ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d; ihv[4] += e;
}

void sha1_compression_W(uint32_t ihv[5], const uint32_t W[80])
{
	uint32_t a = ihv[0], b = ihv[1], c = ihv[2], d = ihv[3], e = ihv[4];

	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 0);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 1);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 2);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 3);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 4);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 5);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 6);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 7);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 8);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 9);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 10);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 11);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 12);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 13);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 14);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, W, 15);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(e, a, b, c, d, W, 16);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(d, e, a, b, c, W, 17);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(c, d, e, a, b, W, 18);
	HASHCLASH_SHA1COMPRESS_ROUND1_STEP(b, c, d, e, a, W, 19);

	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 20);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 21);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 22);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 23);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 24);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 25);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 26);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 27);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 28);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 29);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 30);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 31);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 32);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 33);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 34);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, W, 35);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(e, a, b, c, d, W, 36);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(d, e, a, b, c, W, 37);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(c, d, e, a, b, W, 38);
	HASHCLASH_SHA1COMPRESS_ROUND2_STEP(b, c, d, e, a, W, 39);

	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 40);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 41);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 42);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 43);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 44);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 45);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 46);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 47);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 48);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 49);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 50);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 51);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 52);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 53);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 54);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, W, 55);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(e, a, b, c, d, W, 56);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(d, e, a, b, c, W, 57);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(c, d, e, a, b, W, 58);
	HASHCLASH_SHA1COMPRESS_ROUND3_STEP(b, c, d, e, a, W, 59);

	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 60);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 61);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 62);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 63);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 64);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 65);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 66);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 67);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 68);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 69);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 70);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 71);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 72);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 73);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 74);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, W, 75);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(e, a, b, c, d, W, 76);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(d, e, a, b, c, W, 77);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(c, d, e, a, b, W, 78);
	HASHCLASH_SHA1COMPRESS_ROUND4_STEP(b, c, d, e, a, W, 79);

	ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d; ihv[4] += e;
}

	void SHA1reg_Init(SHA1reg_CTX* ctx)
	{
		static const union { unsigned char bytes[4]; uint32_t value; } endianness = { { 0, 1, 2, 3 } };
		static const uint32_t littleendian = 0x03020100;
		ctx->total = 0;
		ctx->ihv[0] = 0x67452301;
		ctx->ihv[1] = 0xEFCDAB89;
		ctx->ihv[2] = 0x98BADCFE;
		ctx->ihv[3] = 0x10325476;
		ctx->ihv[4] = 0xC3D2E1F0;
		ctx->bigendian = (endianness.value != littleendian);
	}

	void SHA1reg_Update(SHA1reg_CTX* ctx, const char* buf, unsigned len)
	{
		unsigned left, fill;
		if (len == 0)
			return;

		left = ctx->total & 63;
		fill = 64 - left;

		if (left && len >= fill)
		{
			ctx->total += fill;
			memcpy(ctx->buffer + left, buf, fill);
			if (!ctx->bigendian)
				swap_bytes((uint32_t*)(ctx->buffer));
			sha1_compression(ctx->ihv, (uint32_t*)(ctx->buffer));
			buf += fill;
			len -= fill;
			left = 0;
		}
		while (len >= 64)
		{
			ctx->total += 64;
			if (!ctx->bigendian)
			{
				memcpy(ctx->buffer, buf, 64);
				swap_bytes((uint32_t*)(ctx->buffer));
				sha1_compression(ctx->ihv, (uint32_t*)(ctx->buffer));
			}
			else
				sha1_compression(ctx->ihv, (uint32_t*)(ctx->buffer));
			buf += 64;
			len -= 64;
		}
		if (len > 0)
		{
			ctx->total += len;
			memcpy(ctx->buffer + left, buf, len);
		}
	}

	static const unsigned char sha1_padding[64] =
	{
		0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
	};

	void SHA1reg_Final(unsigned char output[20], SHA1reg_CTX *ctx)
	{
		uint32_t last = ctx->total & 63;
		uint32_t padn = (last < 56) ? (56 - last) : (120 - last);
		uint64_t total;
		SHA1reg_Update(ctx, (const char*)(sha1_padding), padn);

		total = ctx->total - padn;
		total <<= 3;
		ctx->buffer[56] = (unsigned char)(total >> 56);
		ctx->buffer[57] = (unsigned char)(total >> 48);
		ctx->buffer[58] = (unsigned char)(total >> 40);
		ctx->buffer[59] = (unsigned char)(total >> 32);
		ctx->buffer[60] = (unsigned char)(total >> 24);
		ctx->buffer[61] = (unsigned char)(total >> 16);
		ctx->buffer[62] = (unsigned char)(total >> 8);
		ctx->buffer[63] = (unsigned char)(total);
		if (!ctx->bigendian)
			swap_bytes((uint32_t*)(ctx->buffer));
		sha1_compression(ctx->ihv, (uint32_t*)(ctx->buffer));
		output[0] = (unsigned char)(ctx->ihv[0] >> 24);
		output[1] = (unsigned char)(ctx->ihv[0] >> 16);
		output[2] = (unsigned char)(ctx->ihv[0] >> 8);
		output[3] = (unsigned char)(ctx->ihv[0]);
		output[4] = (unsigned char)(ctx->ihv[1] >> 24);
		output[5] = (unsigned char)(ctx->ihv[1] >> 16);
		output[6] = (unsigned char)(ctx->ihv[1] >> 8);
		output[7] = (unsigned char)(ctx->ihv[1]);
		output[8] = (unsigned char)(ctx->ihv[2] >> 24);
		output[9] = (unsigned char)(ctx->ihv[2] >> 16);
		output[10] = (unsigned char)(ctx->ihv[2] >> 8);
		output[11] = (unsigned char)(ctx->ihv[2]);
		output[12] = (unsigned char)(ctx->ihv[3] >> 24);
		output[13] = (unsigned char)(ctx->ihv[3] >> 16);
		output[14] = (unsigned char)(ctx->ihv[3] >> 8);
		output[15] = (unsigned char)(ctx->ihv[3]);
		output[16] = (unsigned char)(ctx->ihv[4] >> 24);
		output[17] = (unsigned char)(ctx->ihv[4] >> 16);
		output[18] = (unsigned char)(ctx->ihv[4] >> 8);
		output[19] = (unsigned char)(ctx->ihv[4]);
	}

} // extern "C"

using namespace std;
using namespace boost::accumulators;

inline double LogBase2(double x)
{
	return (log(x) / log(2.0));
}

inline uint32_t rotate_left(const uint32_t x, const unsigned n)
{
	return (x << n) | (x >> (32 - n));
}

template<typename RNG>
void gen_W(RNG& rng, uint32_t W[80])
{
	for (unsigned i = 0; i < 16; ++i)
		W[i] = rng();
	for (unsigned i = 16; i < 80; ++i)
		W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
}

int main(int argc, char** argv)
{
	boost::random::random_device seeder;
	boost::random::mt19937 rng(seeder);

	SHA1_CTX ctx;
	SHA1reg_CTX ctxreg;
	unsigned char hash[20];

	vector<char> buffer;

	boost::timer timer;

	uint32_t dvmask[DVMASKSIZE], dvmask_test[DVMASKSIZE];

	cout << "Verifying ubc_check() against ubc_check_verify():" << endl;
	boost::progress_display pd(1 << 24);
	for (unsigned ll = 0; ll < (1 << 24); ++ll, ++pd)
	{
		uint32_t W[80];

		gen_W(rng, W);

		for (unsigned i = 0; i < DVMASKSIZE; ++i)
		{
			dvmask[i] = 0;
			dvmask_test[i] = ~uint32_t(0);
		}

		ubc_check(W, dvmask);
		ubc_check_verify(W, dvmask_test);

		for (unsigned i = 0; i < DVMASKSIZE; ++i)
			if (dvmask[i] != dvmask_test[i])
			{
				cerr << "Found error:" << endl
					<< "dvmask [" << i << "] = 0x" << hex << std::setw(8) << std::setfill('0') << dvmask[i] << dec << endl
					<< "dvmask2[" << i << "] = 0x" << hex << std::setw(8) << std::setfill('0') << dvmask_test[i] << dec << endl
					;
				return 1;
			}
	}
	cout << "Found no discrepancies between ubc_check() and ubc_check_verify()." << endl << endl;

	const size_t testCnt = 17;
	size_t iterCnt = 1 << 24;

	accumulator_set<double, stats<tag::mean, tag::variance, tag::median> > acc_ubc;
	accumulator_set<double, stats<tag::mean, tag::variance, tag::median> > acc_sha;
	accumulator_set<double, stats<tag::mean, tag::variance, tag::median> > acc_shawnome;

	cout << "Measuring performance of ubc_check, SHA-1 Compress and SHA-1 Compress w/out message expansion." << endl;

	uint32_t x = 0; // variable that accumulates results from inner loops to prevent them from being optimized away

	boost::progress_display perf_pd(testCnt);

	for (size_t k = 0; k < testCnt; k++, ++perf_pd)
	{
		vector< vector<uint32_t> > Wlist;
		for (size_t i = 0; i < (1 << 20); ++i)
		{
			vector<uint32_t> W(80);
			for (unsigned j = 0; j < 80; ++j)
				W[j] = rng();
			Wlist.push_back(W);
		}

		timer.restart();
		for (size_t j = 0; j < (iterCnt >> 20); ++j)
			for (size_t i = 0; i < (1 << 20); ++i)
			{
				ubc_check(&Wlist[i][0], dvmask);
				x += dvmask[0];
			}
		double ubcchecktime = timer.elapsed();

		acc_ubc(iterCnt/ubcchecktime);

		uint32_t IHV[5], M[80];
		for (unsigned i = 0; i < 5; ++i)
			IHV[i] = rng();
		for (unsigned i = 0; i < 80; ++i)
			M[i] = rng();

		timer.restart();
		for (size_t i = 0; i < iterCnt; ++i)
			sha1_compression(IHV, M);
		double shatime = timer.elapsed();

		acc_sha(iterCnt/shatime);

		timer.restart();
		for (size_t i = 0; i < (iterCnt); ++i)
			sha1_compression_W(IHV, M);
		double shawometime = timer.elapsed();

		x += IHV[0] + IHV[1] + IHV[2] + IHV[3] + IHV[4]; // prevent l
		acc_shawnome(iterCnt/shawometime);
	}

	cout << "SHA-1 compress performance: ";
	cout << "median 2^" << LogBase2(median(acc_sha)) << " sha1 compress/s ";
	cout << "mean 2^" << LogBase2(mean(acc_sha)) << " sha1 compress/s ";
	cout << "variance " << variance(acc_sha) << endl;

	cout << "UBC Check performance: ";
	cout << "median 2^" << LogBase2(median(acc_ubc)) << " ubc_check/s (" << median(acc_ubc) / mean(acc_sha) << ") ";
	cout << "mean 2^" << LogBase2(mean(acc_ubc)) << " ubc_check/s (" << mean(acc_ubc) / mean(acc_sha) << ") ";
	cout << "variance " << variance(acc_ubc) << " DVMASK:[" << x << "]" << endl;

	cout << "SHA-1 compress w/o msgexp performance: ";
	cout << "median 2^" << LogBase2(median(acc_shawnome)) << " sha1 compress no ME/s (" << median(acc_shawnome) / mean(acc_sha) << ") ";
	cout << "mean 2^" << LogBase2(mean(acc_shawnome)) << " sha1 compress no ME/s (" << mean(acc_shawnome) / mean(acc_sha) << ") ";
	cout << "variance " << variance(acc_shawnome) << endl;

	size_t testcount = 128;
	size_t mindata = 1 << 20;

	for (size_t i = 11; i < 12; ++i)
	{
		buffer.resize(mindata);

		size_t minloop = mindata / (1<<i);
		if (minloop == 0)
			minloop = 1;

		double elap_noubc = 0;
		double elap_ubc = 0;
		double elap_reg = 0;

		accumulator_set<double, stats<tag::mean, tag::variance, tag::median> > acc_shafullcd;
		accumulator_set<double, stats<tag::mean, tag::variance, tag::median> > acc_shaubc;
		accumulator_set<double, stats<tag::mean, tag::variance, tag::median> > acc_shareg;

		for (size_t n = 0; n < testCnt; n++)
		{
			for (size_t r = 0; r < testcount; ++r)
			{
				for (size_t j = 0; j < buffer.size(); ++j)
					buffer[j] = rng();

				timer.restart();
				for (size_t k = 0; k < minloop; ++k)
				{
					SHA1DCInit(&ctx);
					SHA1DCSetCallback(&ctx, nc_callback);
					SHA1DCSetUseDetectColl(&ctx, 0);
					SHA1DCUpdate(&ctx, &buffer[k * (1<<i)], 1<<i);
					SHA1DCFinal(hash, &ctx);
					x += hash[0];
				}
				elap_reg += timer.elapsed();

				timer.restart();
				for (size_t k = 0; k < minloop; ++k)
				{
					SHA1DCInit(&ctx);
					SHA1DCSetCallback(&ctx, nc_callback);
					SHA1DCSetUseUBC(&ctx, 0);
					SHA1DCUpdate(&ctx, &buffer[k * (1<<i)], 1<<i);
					SHA1DCFinal(hash, &ctx);
					x += hash[0];
				}
				elap_noubc += timer.elapsed();

				timer.restart();
				for (size_t k = 0; k < minloop; ++k)
				{
					SHA1DCInit(&ctx);
					SHA1DCSetCallback(&ctx, nc_callback);
	//				SHA1DCSetUseUBC(&ctx, 1);
					SHA1DCUpdate(&ctx, &buffer[k*(1<<i)], 1<<i);
					SHA1DCFinal(hash, &ctx);
					x += hash[0];
				}
				elap_ubc += timer.elapsed();

			}

			elap_noubc /= double(minloop)*double(testcount);
			elap_ubc /= double(minloop)*double(testcount);
			elap_reg /= double(minloop)*double(testcount);

			acc_shafullcd(elap_noubc);
			acc_shaubc(elap_ubc);
			acc_shareg(elap_reg);

		}

		cout << (1 << i) << "\t : SHA Regular Median: " << median(acc_shareg) << "s \tMean: " << mean(acc_shareg) << "s \t Variance: " << variance(acc_shareg) << "s" << endl;
		cout << (1 << i) << "\t : SHA Collision Detection w/out UBC Median: " << median(acc_shafullcd) << "s " << median(acc_shafullcd) / median(acc_shareg) << "(no ubc/reg) \tMean: " << mean(acc_shafullcd) << "s " << mean(acc_shafullcd) / mean(acc_shareg) << "(no ubc/reg) \t Variance: " << variance(acc_shafullcd) << "s" << endl;
		cout << (1 << i) << "\t : SHA Collision Detection w/ UBC Median: " << median(acc_shaubc) << "s " << median(acc_shaubc) / median(acc_shareg) << "(no ubc/reg) \tMean: " << mean(acc_shaubc) << "s " << mean(acc_shaubc) / mean(acc_shareg) << "(no ubc/reg) \t Variance: " << variance(acc_shaubc) << "s" << endl;
	}
	// finally act on x to prevent this variable to be optimized away
	if (x)
		cout << " " << flush;
	else
		cout << " ";
	return 0;

	cout << "Performing endurance test..." << endl;
	uint64_t total = 0;
	SHA1DCInit(&ctx);
	SHA1DCSetCallback(&ctx, nc_callback);
	buffer.resize(1 << 30);
	timer.restart();
	while (true)
	{
		for (size_t i = 0; i < buffer.size(); i += 4)
			(*reinterpret_cast<uint32_t*>(&buffer[i])) = rng();
		SHA1DCUpdate(&ctx, &buffer[0], buffer.size());
		total += buffer.size();
		if (timer.elapsed() > 60)
		{
			cout << "Hashed " << (total >> 30) << " GB..." << endl;
			timer.restart();
		}
	}

}


text:
/*
 * Copyright (C) Your copyright notice.
 *
 * Author: BOUBAKER Bassem
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the PG_ORGANIZATION nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY	THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS-IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <boost/test/tools/old/interface.hpp>
#include <dbus-c++/connection.h>
#include <dbus-c++/property.h>
#include <dbus-c++/types.h>
#include <dbus-c++/dispatcher.h>
#include <dbus-c++/glib-integration.h>
#include <stddef.h>
#include "CanConfig.hpp"
#include <iostream>
#include "SocketCan.h"
#include <arpa/inet.h>

#include "BroadcastManager.hpp"
#include "Can.hpp"
#include "CanSignalListener.hpp"
using namespace std;

#define BOOST_TEST_MODULE CAN_LIB_TEST

#include <boost/test/included/unit_test_framework.hpp>

/*class TestPropertiesListener: public DBus::PropertiesProxy,
 public Lib::CanConfig {
 public:
 TestPropertiesListener(DBus::Connection &connection,
 const std::string &canInterfaceName) :
 Lib::CanConfig(connection, canInterfaceName) {
 //connect_signal("com.actia.platform.can",PropertiesChangedcb,PropertiesChanged);
 //org.freedesktop.DBus
 connection.add_match("type='signal',sender='com.actia.platform.can'");

 }

 ~TestPropertiesListener() {

 }
 virtual void PropertiesChanged(const std::string &interface_name,
 const std::map<std::string, ::DBus::Variant> &changed_properties,
 const std::vector<std::string> &invalidated_properties) {
 for (auto p : changed_properties) {
 std::cout << "Property updated : " << p.first << std::endl;
 BOOST_TEST_MESSAGE("properties changed");
 }
 }
 };*/

BOOST_AUTO_TEST_CASE( Test_Dbus_session_Deamon ) {

	BOOST_TEST_MESSAGE("...System DBus connection testing...");
	// Specify the default dispatcher for D-Bus
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_Dbus_system_Deamon ) {

	BOOST_TEST_MESSAGE("...Session DBus connection testing...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SystemBus();
	BOOST_REQUIRE(bus.connected() == true);
	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_CAN0 ) {

	BOOST_TEST_MESSAGE("...Test CAN0 Interface configuration...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	Lib::CanConfig can0(bus, "can0");
	can0.StartInterface(250000);
	BOOST_REQUIRE(can0.LinkState() == true);
	can0.StopInterface();
	BOOST_REQUIRE(can0.LinkState() == false);

	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_CAN1 ) {

	BOOST_TEST_MESSAGE("...Test CAN1 Interface configuration...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	Lib::CanConfig can1(bus, "can1");
	can1.StartInterface(250000);
	BOOST_REQUIRE(can1.LinkState() == true);
	can1.StopInterface();
	BOOST_REQUIRE(can1.LinkState() == false);

	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_CAN0_status ) {

	BOOST_TEST_MESSAGE("...Test CAN0 Interface status...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	Lib::CanStatus can0(bus, "can0");
	BOOST_REQUIRE(can0.BusState() != 5);
	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_CAN1_status ) {

	BOOST_TEST_MESSAGE("...Test CAN1 Interface status...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	Lib::CanStatus can1(bus, "can1");
	BOOST_REQUIRE(can1.BusState() != 5);

	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_CAN0_configuration_status ) {

	BOOST_TEST_MESSAGE("...Test CAN0 Interface configuration and status...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	Lib::CanStatus can0Status(bus, "can0");
	BOOST_REQUIRE(can0Status.BusState() != 5);
	Lib::CanConfig can0Config(bus, "can0");
	can0Config.StartInterface(250000);
	BOOST_REQUIRE(can0Config.LinkState() == true);
	can0Config.StopInterface();
	BOOST_REQUIRE(can0Config.LinkState() == false);
	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_CAN1_configuration_status ) {

	BOOST_TEST_MESSAGE("...Test CAN1 Interface configuration and status...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	BOOST_REQUIRE(bus.connected() == true);
	Lib::CanStatus can1Status(bus, "can1");
	BOOST_REQUIRE(can1Status.BusState() != 5);
	Lib::CanConfig can1Config(bus, "can1");
	can1Config.StartInterface(250000);
	BOOST_REQUIRE(can1Config.LinkState() == true);
	can1Config.StopInterface();
	BOOST_REQUIRE(can1Config.LinkState() == false);
	BOOST_TEST_MESSAGE("Test passed!");
}
BOOST_AUTO_TEST_CASE( Test_Stop_CAN ) {

	BOOST_TEST_MESSAGE("...Test CAN1 Interface configuration and status...");

}

BOOST_AUTO_TEST_CASE( Test_Lib_CAN0 ) {

	BOOST_TEST_MESSAGE("...Test CAN0 Lib...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	Can can0(bus, "can0");
	can0.getConfiguration()->StartInterface(250000);
	BOOST_REQUIRE(can0.getConfiguration()->LinkState() == true);
	can0.getConfiguration()->StopInterface();
	BOOST_REQUIRE(can0.getConfiguration()->LinkState() == false);
	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_Lib_CAN1 ) {
	BOOST_TEST_MESSAGE("...Test CAN1 Lib...");
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	Can can1(bus, "can1");
	can1.getConfiguration()->StartInterface(250000);
	BOOST_REQUIRE(can1.getConfiguration()->LinkState() == true);
	can1.getConfiguration()->StopInterface();
	BOOST_REQUIRE(can1.getConfiguration()->LinkState() == false);
	BOOST_TEST_MESSAGE("Test passed!");
}

BOOST_AUTO_TEST_CASE( Test_Lib_Broadcast_Manager_sending_mechanism ) {
	BOOST_TEST_MESSAGE(
			"...Test Broadcast Manager for can0 sending mechanism...");
	uint16_t id = 0x0FD;
	uint8_t dlc = 8;
	uint8_t data[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	DBus::Glib::BusDispatcher dispatcher;
	DBus::default_dispatcher = &dispatcher;
	dispatcher.attach(NULL);
	DBus::Connection bus = DBus::Connection::SessionBus();
	Can can0(bus, CanInterface::can0);
	can0.getConfiguration()->StartInterface(250000);
	BOOST_REQUIRE(can0.getConfiguration()->LinkState() == true);
	BroadcastManager bcm;
	bcm.open(CanInterface::can0);
	BOOST_REQUIRE(bcm.send_periodic(id, data, dlc, 100) == true);
	sleep(1);
	BOOST_REQUIRE(bcm.cancel_send_periodic(id) == true);
	sleep(1);
	BOOST_REQUIRE(bcm.send(id, data, dlc) == true);
	sleep(1);
	BOOST_TEST_MESSAGE("Test passed!");
}

/*
 BOOST_AUTO_TEST_CASE( Test_Lib_Broadcast_Manager_receiving_mechanism ) {
 BOOST_TEST_MESSAGE(
 "...Test Broadcast Manager for can0 receiving mechanism...");
 auto loop = g_main_loop_new(NULL, false);
 DBus::Glib::BusDispatcher dispatcher;
 DBus::default_dispatcher = &dispatcher;
 dispatcher.attach(NULL);
 DBus::Connection bus = DBus::Connection::SessionBus();
 Can can0(bus, "can0");
 can0.getConfiguration()->StartInterface(250000);
 BOOST_REQUIRE(can0.getConfiguration()->LinkState() == true);
 BroadcastManager bcm;
 bcm.open("can0");

 uint16_t id1;
 uint8_t data1[8];
 uint8_t dlc1;

 if (bcm.receive(&id1, data1, &dlc1)) {
 BOOST_TEST_MESSAGE("yeyyyyyy");

 }

 can0.getConfiguration()->StopInterface();
 Can can1(bus, "can1");
 can1.getConfiguration()->StopInterface();
 g_main_loop_run(loop);
 BOOST_TEST_MESSAGE("Test passed!");
 }*/
/*int main() {
 auto loop = g_main_loop_new(NULL, false);

 DBus::Glib::BusDispatcher dispatcher;
 DBus::default_dispatcher = &dispatcher;
 dispatcher.attach(NULL);
 DBus::Connection bus = DBus::Connection::SessionBus();
 Can can0(bus, "can0");
 can0.getConfiguration()->StartInterface(250000);

 BroadcastManager bcm;

 //bcm.open("can0");

 //uint16_t id1;
 //uint8_t data1[8];
 //uint8_t dlc1;

 SocketCAN can("can0");

 auto can_frame_received = [](uint32_t id, uint8_t data[8], uint8_t dlc) {

 std::cout << "START frame received." << std::endl;
 };
 // When a CAN frame has been received, can_frame_received() will be
 // called.
 if (!can.receive(can_frame_received)) {
 return 1;
 }
 g_main_loop_run(loop);
 return 0;

 }*/

max_stars_repo_name: boubakerbassem/fms-service

max_issues_repo_name: boubakerbassem/fms-service

max_forks_repo_name: boubakerbassem/fms-service


text:
#include <libgui/InputAction.h>
#include <libgui/InputType.h>
#include <libgui/Point.h>
#include "libgui/Slider.h"
#include "libgui/ElementManager.h"

#include <boost/msm/front/states.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/euml/euml.hpp>
#include <libgui/ScopeExit.h>

using namespace boost::msm::front;
using namespace boost::msm::back;
using boost::msm::front::euml::func_state;
using emptyvector = boost::fusion::vector<>;
using boost::mpl::vector1;
using boost::mpl::vector2;
using boost::msm::TerminateFlag;

namespace libgui
{

Slider::Slider(Element::Dependencies elementDependencies)
  : Slider(elementDependencies, "Slider")
{
}

Slider::Slider(Element::Dependencies elementDependencies, std::string_view typeName)
  : Element(elementDependencies, typeName)
{
}

void Slider::PostConstruct()
{
  _track = this->CreateChild<Track>();
  _thumb = _track->CreateChild<Thumb>();

  #ifdef DBG
  printf("Initializing Slider\n");
  fflush(stdout);
  #endif
}

double Slider::GetValue() const
{
  return _value;
}

void Slider::SetValue(double value)
{
  auto oldValue = _value;

  _value = value;

  if (_valueIsChangingByInput && (value != oldValue))
  {
    OnValueChangedByInput();
  }
}

double Slider::GetThumbHeight() const
{
  return _thumbHeight;
}

void Slider::SetThumbHeight(double thumbHeight)
{
  _thumbHeight = thumbHeight;
}

double Slider::GetFinenessMultiplier() const
{
  return _finenessMultiplier;
}

void Slider::SetFinenessMultiplier(double finenessMultiplier)
{
  _finenessMultiplier = finenessMultiplier;
}

void Slider::SetValueChangedByInputCallback(
  const std::function<void(std::shared_ptr<Slider>)>& valueChangedByInputCallback)
{
  _valueChangedByInputCallback = valueChangedByInputCallback;
}

std::shared_ptr<Slider::Thumb> Slider::GetThumb() const
{
  return _thumb;
}

std::shared_ptr<Slider::Track> Slider::GetTrack() const
{
  return _track;
}

namespace SmSlider
{
// events
struct Enter
{
};
struct Leave
{
};
struct Push
{
};
struct Release
{
};
struct EngagedEscape
{
};
struct EngagedReturn
{
};

class StateMachineFrontEnd: public state_machine_def<StateMachineFrontEnd>
{

public:
  typedef int no_exception_thrown;

  StateMachineFrontEnd(Slider::Thumb* parent)
    : _parent(parent)
  {
  }

  // states
  struct Idle: public state<>
  {
  };
  struct Pending: public state<>
  {
  };
  struct Engaged: public state<>
  {
  };
  struct EngagedRemotely: public state<>
  {
  };

  // actions
  struct RecordAnchor
  {
    template<class EVT, class FSM, class SourceState, class TargetState>
    void operator()(EVT const& evt, FSM& fsm, SourceState& ss, TargetState& ts)
    {
      fsm._parent->RecordAnchor();
    }
  };

  // Replaces the default no-transition response.
  template<class FSM, class Event>
  void no_transition(Event const& e, FSM&, int state)
  {
    // Simply ignore any event that doesn't generate a transition
  }

  // Set up the starting state of the state machine
  typedef Idle initial_state;

  // Transition table for state machine
  // @formatter:off

    // NOTE: The order of the states listed in this table must match the order in the State enum
    struct transition_table : boost::mpl::vector<
    //    Start              Event           Next State         Action           Guard
    //  +------------------+-----------    +------------------+----------------+---------+
    Row < Idle             , Enter         , Pending          , none           , none    >,
    //  +------------------+-----------    +------------------+----------------+---------+
    Row < Pending          , Leave         , Idle             , none           , none    >,
    Row < Pending          , Push          , Engaged          , RecordAnchor   , none    >,
    //  +------------------+-----------    +------------------+----------------+---------+
    Row < Engaged          , Release       , Pending          , none           , none    >,
    Row < Engaged          , EngagedEscape , EngagedRemotely  , none           , none    >,
    Row < Engaged          , Leave         , Idle             , none           , none    >,
    //  +------------------+-----------    +------------------+----------------+---------+
    Row < EngagedRemotely  , EngagedReturn , Engaged          , none           , none    >,
    Row < EngagedRemotely  , Release       , Idle             , none           , none    >,
    Row < EngagedRemotely  , Leave         , Idle             , none           , none    >
    //  +------------------+-----------    +------------------+----------------+---------+
    > {};

    // @formatter:on

private:
  Slider::Thumb* _parent;

};

typedef state_machine<StateMachineFrontEnd> StateMachine;
}

Slider::Track::Track(Element::Dependencies elementDependencies)
  : Element(elementDependencies, "Slider::Track")
{
}

std::shared_ptr<Slider> Slider::Track::GetSlider() const
{
  return std::dynamic_pointer_cast<Slider>(GetParent());
}

Slider::Thumb::Thumb(Element::Dependencies elementDependencies)
  : Control(elementDependencies, "Slider::Thumb"),
    _track(std::dynamic_pointer_cast<Track>(elementDependencies.parent)),
    _slider(_track.lock()->GetSlider())
{
  // Create and store state machine
  auto stateMachine = new SmSlider::StateMachine(this);
  stateMachine->start();

  _stateMachine = stateMachine;
}

Slider::Thumb::~Thumb()
{
  // Delete state machine
  auto stateMachine = (SmSlider::StateMachine*) _stateMachine;
  delete stateMachine;
  _stateMachine = nullptr;
}

void Slider::Thumb::Arrange()
{
  if (auto slider = _slider.lock())
  {
    auto p = GetParent();
    SetLeft(p->GetLeft());
    SetRight(p->GetRight());
    auto thumbHeight  = slider->GetThumbHeight();
    auto boundsTop    = p->GetTop();
    auto boundsHeight = p->GetHeight() - thumbHeight;
    auto top          = boundsTop + (slider->GetRawFromValue() * boundsHeight);
    SetTop(std::round(top));
    SetBottom(std::round(top + thumbHeight));
  }
}

void Slider::Thumb::NotifyInput(InputType inputType, InputAction inputAction, Point point)
{
  _inputPoint = point;

  auto stateMachine = (SmSlider::StateMachine*) _stateMachine;

  auto stateBefore = GetState();

  switch (inputAction)
  {
    case InputAction::EnterReleased:
      stateMachine->process_event(SmSlider::Enter());
      break;
    case InputAction::EnterPushed:
      stateMachine->process_event(SmSlider::Enter());
      break;
    case InputAction::Move:
      NotifyMove(point);
      break;
    case InputAction::Push:
      stateMachine->process_event(SmSlider::Push());
      break;
    case InputAction::Release:
      stateMachine->process_event(SmSlider::Release());
      break;
    case InputAction::Leave:
      stateMachine->process_event(SmSlider::Leave());
      break;
    case InputAction::EngagedEscape:
      stateMachine->process_event(SmSlider::EngagedEscape());
      NotifyMove(point);
      break;
    case InputAction::EngagedReturn:
      stateMachine->process_event(SmSlider::EngagedReturn());
      NotifyMove(point);
      break;
  }

  if (stateBefore != GetState())
  {
    if (auto slider = _slider.lock())
    {
      slider->OnThumbStateChangedByInput();
    }
  }

  if (InputAction::Move != inputAction)
  {
    // After any state changes except moving, we update the control (move updates are handled separately)
    UpdateAfterModify();
  }
}

void Slider::Thumb::RecordAnchor()
{
  auto slider = _slider.lock();
  if (!slider) return;

  _anchorOffset = _inputPoint.Y;
  _valueAtAnchor = slider->GetValue();
}

void Slider::Thumb::NotifyMove(Point point)
{
  auto state = GetState();
  if (State::Engaged == state ||
      State::EngagedRemotely == state)
  {
    auto slider = _slider.lock();
    auto track  = _track.lock();
    if (slider && track)
    {
      auto virtualTrackHeight = (track->GetHeight() - slider->GetThumbHeight());
      virtualTrackHeight *= slider->GetFinenessMultiplier();
      auto offsetPercent = (_anchorOffset - point.Y) / virtualTrackHeight;
      if (0.0 != offsetPercent)
      {
        auto newValue = _valueAtAnchor + offsetPercent;
        newValue = std::max(0.0, newValue);
        newValue = std::min(1.0, newValue);
        if (slider->GetValue() != newValue)
        {
          {
            slider->_valueIsChangingByInput = true;
            ScopeExit onScopeExit([slider]() {
              slider->_valueIsChangingByInput = false; });
            slider->SetValue(newValue);
          }
          UpdateAfterModify();
        }
      }
    }
  }
}

std::weak_ptr<Slider> Slider::Thumb::GetSlider() const
{
  return _slider;
}

void Slider::OnValueChangedByInput()
{
  if (_valueChangedByInputCallback)
  {
    _valueChangedByInputCallback(std::dynamic_pointer_cast<Slider>(shared_from_this()));
  }
}

void Slider::OnThumbStateChangedByInput()
{
}

double Slider::GetRawFromValue()
{
  return 1.0 - GetValue();
}

Slider::Thumb::State Slider::Thumb::GetState() const
{
  auto stateMachine = (SmSlider::StateMachine*) _stateMachine;
  return (State) stateMachine->current_state()[0];
}

const Inches Slider::GetThumbHeightInches() const
{
  return libgui::Inches(GetThumbHeight() / GetElementManager()->GetDpiY());
}

void Slider::SetThumbHeight(Inches thumbHeight)
{
  SetThumbHeight(double(thumbHeight) * GetElementManager()->GetDpiY());
}

void Slider::OnElementIsBeingRemoved()
{
  // Release anything held in a lambda capture
  _valueChangedByInputCallback = nullptr;
}
}

max_stars_repo_name: bobkocisko/libgui

max_issues_repo_name: bobkocisko/libgui

max_forks_repo_name: bobkocisko/libgui


text:
#define BOOST_TEST_MODULE IsSetColdnessAvailableTestSuite
#define BOOST_TEST_DYN_LINK

#include <boost/test/included/unit_test.hpp>
#include <hops/MarkovChain/IsSetColdnessAvailable.hpp>

BOOST_AUTO_TEST_SUITE(IsSetColdnessAvailable)

    BOOST_AUTO_TEST_CASE( WhenSetColdnessIsNotAvailable) {
        class Mock {
        public:
        };
        BOOST_CHECK(hops::IsSetColdnessAvailable<Mock>::value == false);
    }

    BOOST_AUTO_TEST_CASE( WhenSetColdnessHasWrongSignature) {
        class Mock {
        public:
            void setColdness();
        };

        BOOST_CHECK(hops::IsSetColdnessAvailable<Mock>::value == false);
    }

    BOOST_AUTO_TEST_CASE( WhenSetColdnessIsAvailableWithCorrectTypedef) {
        class Mock {
        public:
            void setColdness(double);
        };

        BOOST_CHECK(hops::IsSetColdnessAvailable<Mock>::value);
    }

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: modsim/hops

max_issues_repo_name: modsim/hops

max_forks_repo_name: modsim/hops


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T. Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_ACSCD_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_ACSCD_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!

    @ingroup group-trigonometric
    Function object implementing acscd capabilities

    inverse cosecant in degree.

    @par Semantic:

    For every parameter of floating type T

    @code
    T r = acscd(x);
    @endcode

    is similar to:

    @code
    T r =  asind(rec(x));;
    @endcode

    @see acsc

  **/
  const boost::dispatch::functor<tag::acscd_> acscd = {};
} }
#endif

#include <boost/simd/function/scalar/acscd.hpp>
#include <boost/simd/function/simd/acscd.hpp>

#endif

ext: hpp


text:
//==================================================================================================
/*!

  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#include <boost/simd/constant/logeps.hpp>
#include <boost/simd/as.hpp>
#include <scalar_test.hpp>

STF_CASE_TPL( "Check logeps behavior for integral types"
            , (std::uint8_t)(std::uint16_t)(std::uint32_t)(std::uint64_t)
              (std::int8_t)(std::int16_t)(std::int32_t)(std::int64_t)
            )
{
  using boost::simd::as;
  using boost::simd::detail::logeps;
  using boost::simd::Logeps;

  STF_TYPE_IS(decltype(Logeps<T>()), T);
  STF_EQUAL(Logeps<T>(), T(0));
  STF_EQUAL(logeps( as(T{}) ),T(0));
}

STF_CASE_TPL( "Check logeps behavior for double type"
            , (double)
            )
{
  using boost::simd::as;
  using boost::simd::detail::logeps;
  using boost::simd::Logeps;

  STF_TYPE_IS(decltype(Logeps<T>()), T);
  STF_IEEE_EQUAL(Logeps<T>(), -36.043653389117156089696070315825);
  STF_IEEE_EQUAL(logeps( as(T{}) ), -36.043653389117156089696070315825);
}

STF_CASE_TPL( "Check logeps behavior for float type"
            , (float)
            )
{
  using boost::simd::as;
  using boost::simd::detail::logeps;
  using boost::simd::Logeps;

  STF_TYPE_IS(decltype(Logeps<T>()), T);
  STF_IEEE_EQUAL(Logeps<T>(), -15.9423847f);
  STF_IEEE_EQUAL(logeps( as(T{}) ), -15.9423847f);
}


text:
/*  Copyright (c) 2013, Abdullah A. Hassan <voodooattack@hotmail.com>
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided with the distribution.
 *
 *  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.
 */

#include "noiseutils.hpp"

#include "config.hpp"
#include "jsonutils.hpp"
#include "noisemodules.hpp"

#ifdef NOISE_DIR_IS_LIBNOISE
#include <libnoise/noise.h>
#else
#include <noise/noise.h>
#endif

#include <boost/algorithm/string.hpp>

namespace ADWIF
{
  std::shared_ptr<noise::module::Module> buildNoiseGraph(const Json::Value & value,
    std::vector<std::shared_ptr<noise::module::Module>> & modules,
    std::map<std::string, std::shared_ptr<noise::module::Module>> & defs,
    const std::shared_ptr<HeightMapModule> & heightMap, int seed)
  {
    std::shared_ptr<noise::module::Module> m;

    if (value["module"].empty())
    {
      if (!value["ref"].empty() && defs.find(value["ref"].asString()) != defs.end())
        return defs[value["ref"].asString()];
      else
        throw ParsingException("undefined module missing reference or reference not found:\n" +
                                value.toStyledString());
    }

    std::string module = value["module"].asString();
    boost::to_lower(module);

    if (module == "add")
    {
      std::shared_ptr<noise::module::Add> add(new noise::module::Add);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      add->SetSourceModule(0, *m1);
      add->SetSourceModule(1, *m2);
      m = add;
    }
    else if (module == "mul" || module == "multiply")
    {
      std::shared_ptr<noise::module::Multiply> mul(new noise::module::Multiply);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      mul->SetSourceModule(0, *m1);
      mul->SetSourceModule(1, *m2);
      m = mul;
    }
    else if (module == "pow" || module == "power")
    {
      std::shared_ptr<noise::module::Power> pow(new noise::module::Power);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      pow->SetSourceModule(0, *m1);
      pow->SetSourceModule(1, *m2);
      m = pow;
    }
    else if (module == "min")
    {
      std::shared_ptr<noise::module::Min> min(new noise::module::Min);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      min->SetSourceModule(0, *m1);
      min->SetSourceModule(1, *m2);
      m = min;
    }
    else if (module == "max")
    {
      std::shared_ptr<noise::module::Max> max(new noise::module::Max);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      max->SetSourceModule(0, *m1);
      max->SetSourceModule(1, *m2);
      m = max;
    }
    else if (module == "sel" || module == "select")
    {
      std::shared_ptr<noise::module::Select> sel(new noise::module::Select);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> ctl;
      if (!value["controller"].empty())
        ctl = buildNoiseGraph(value["controller"], modules, defs, heightMap, seed);
      else
        ctl = buildNoiseGraph(value["sources"][2], modules, defs, heightMap, seed);
      sel->SetSourceModule(0, *m1);
      sel->SetSourceModule(1, *m2);
      sel->SetControlModule(*ctl);
      if (!value["falloff"].empty())
        sel->SetEdgeFalloff(value["falloff"].asDouble());
      if (value["bounds"].isArray())
      {
        if (value["bounds"][0].asDouble() < value["bounds"][1].asDouble())
          sel->SetBounds(value["bounds"][0].asDouble(), value["bounds"][1].asDouble());
        else
          throw ParsingException("Select: Upper bound must be greater than lower bound");
      }
      m = sel;
    }
    else if (module == "blend")
    {
      std::shared_ptr<noise::module::Blend> blend(new noise::module::Blend);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> ctl;
      if (!value["controller"].empty())
        ctl = buildNoiseGraph(value["controller"], modules, defs, heightMap, seed);
      else
        ctl = buildNoiseGraph(value["sources"][2], modules, defs, heightMap, seed);
      blend->SetSourceModule(0, *m1);
      blend->SetSourceModule(1, *m2);
      blend->SetControlModule(*ctl);
      m = blend;
    }
    else if (module == "displace")
    {
      std::shared_ptr<noise::module::Blend> displace(new noise::module::Blend);
      std::shared_ptr<noise::module::Module> m1 = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m2 = buildNoiseGraph(value["sources"][1], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m3 = buildNoiseGraph(value["sources"][2], modules, defs, heightMap, seed);
      std::shared_ptr<noise::module::Module> m4 = buildNoiseGraph(value["sources"][3], modules, defs, heightMap, seed);
      displace->SetSourceModule(0, *m1);
      displace->SetSourceModule(1, *m2);
      displace->SetSourceModule(2, *m2);
      displace->SetSourceModule(3, *m3);
      m = displace;
    }
    else if (module == "curve")
    {
      std::shared_ptr<noise::module::Curve> curve(new noise::module::Curve);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      curve->SetSourceModule(0, *src);
      for(const Json::Value & c : value["curve"])
        curve->AddControlPoint(c[0].asDouble(), c[1].asDouble()); // FIXME: No two control points can have the same input value.
      m = curve;
    }
    else if (module == "terrace")
    {
      std::shared_ptr<noise::module::Terrace> terrace(new noise::module::Terrace);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      terrace->SetSourceModule(0, *src);
      for(const Json::Value & c : value["curve"])
        terrace->AddControlPoint(c.asDouble()); // FIXME: No two control points can have the same input value.
      m = terrace;
    }
    else if (module == "clamp")
    {
      std::shared_ptr<noise::module::Clamp> clamp(new noise::module::Clamp);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      clamp->SetSourceModule(0, *src);
      clamp->SetBounds(value["min"].asDouble(), value["max"].asDouble());
      m = clamp;
    }
    else if (module == "exp" || module == "exponent")
    {
      std::shared_ptr<noise::module::Exponent> exp(new noise::module::Exponent);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      exp->SetSourceModule(0, *src);
      if (!value["exponent"].empty())
        exp->SetExponent(value["exponent"].asDouble());
      m = exp;
    }
    else if (module == "abs")
    {
      std::shared_ptr<noise::module::Abs> abs(new noise::module::Abs);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      abs->SetSourceModule(0, *src);
      m = abs;
    }
    else if (module == "invert")
    {
      std::shared_ptr<noise::module::Invert> invert(new noise::module::Invert);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      invert->SetSourceModule(0, *src);
      m = invert;
    }
    else if (module == "cache")
    {
      std::shared_ptr<noise::module::Cache> cache(new noise::module::Cache);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      cache->SetSourceModule(0, *src);
      m = cache;
    }
    else if (module == "scale" || module == "scalebias")
    {
      std::shared_ptr<noise::module::ScaleBias> scale(new noise::module::ScaleBias);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      scale->SetSourceModule(0, *src);
      if (!value["scale"].empty())
        scale->SetScale(value["scale"].asDouble());
      if (!value["bias"].empty())
        scale->SetScale(value["bias"].asDouble());
      m = scale;
    }
    else if (module == "scalep" || module == "scalepoint")
    {
      std::shared_ptr<noise::module::ScalePoint> scale(new noise::module::ScalePoint);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      scale->SetSourceModule(0, *src);
      if (!value["scale"].empty())
      {
        scale->SetScale(value["scale"].asDouble());
        if (!value["scalex"].empty())
          scale->SetXScale(value["scalex"].asDouble());
        if (!value["scaley"].empty())
          scale->SetYScale(value["scaley"].asDouble());
        if (!value["scalez"].empty())
          scale->SetZScale(value["scalez"].asDouble());
      }
      else if (value["scale"].isArray())
        scale->SetScale(value["scale"][0].asDouble(), value["scale"][1].asDouble(), value["scale"][2].asDouble());
      m = scale;
    }
    else if (module == "trans" || module == "translate")
    {
      std::shared_ptr<noise::module::TranslatePoint> trans(new noise::module::TranslatePoint);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      trans->SetSourceModule(0, *src);
      if (!value["translation"].empty())
      {
        trans->SetTranslation(value["translation"].asDouble());
        if (!value["x"].empty())
          trans->SetXTranslation(value["x"].asDouble());
        if (!value["y"].empty())
          trans->SetYTranslation(value["y"].asDouble());
        if (!value["z"].empty())
          trans->SetZTranslation(value["z"].asDouble());
      }
      else if (value["translation"].isArray())
        trans->SetTranslation(value["translation"][0].asDouble(), value["translation"][1].asDouble(), value["translation"][2].asDouble());
      m = trans;
    }
    else if (module == "rot" || module == "rotate")
    {
      std::shared_ptr<noise::module::RotatePoint> rot(new noise::module::RotatePoint);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      rot->SetSourceModule(0, *src);
      if (value["rotation"].isArray())
        rot->SetAngles(value["rotation"][0].asDouble(), value["rotation"][1].asDouble(), value["rotation"][2].asDouble());
      m = rot;
    }
    else if (module == "const" || module == "constant")
    {
      std::shared_ptr<noise::module::Const> con(new noise::module::Const);
      con->SetConstValue(value["value"].asDouble());
      m = con;
    }
    else if (module == "checkerboard")
    {
      std::shared_ptr<noise::module::Checkerboard> cb(new noise::module::Checkerboard);
      m = cb;
    }
    else if (module == "billow")
    {
      std::shared_ptr<noise::module::Billow> billow(new noise::module::Billow);
      if (!value["frequency"].empty())
        billow->SetFrequency(value["frequency"].asDouble());
      if (!value["lacunarity"].empty())
        billow->SetLacunarity(value["lacunarity"].asDouble());
      if (!value["octaves"].empty())
        billow->SetOctaveCount(value["octaves"].asInt());
      if (!value["persistence"].empty())
        billow->SetPersistence(value["persistence"].asDouble());
      if (value["quality"].isString())
      {
        std::string quality = value["quality"].asString();
        boost::to_lower(quality);
        if (quality == "fast")
          billow->SetNoiseQuality(noise::NoiseQuality::QUALITY_FAST);
        else if (quality == "standard")
          billow->SetNoiseQuality(noise::NoiseQuality::QUALITY_STD);
        else if (quality == "best")
          billow->SetNoiseQuality(noise::NoiseQuality::QUALITY_BEST);
        else
          throw ParsingException("unsupported quality specifier:\n" + value.toStyledString());
      }
      int s = seed;
      if (!value["seed"].empty())
        s ^= value["seed"].asInt();
      billow->SetSeed(seed);
      m = billow;
    }
    else if (module == "perlin")
    {
      std::shared_ptr<noise::module::Perlin> perlin(new noise::module::Perlin);
      if (!value["frequency"].empty())
        perlin->SetFrequency(value["frequency"].asDouble());
      if (!value["lacunarity"].empty())
        perlin->SetLacunarity(value["lacunarity"].asDouble());
      if (!value["octaves"].empty())
        perlin->SetOctaveCount(value["octaves"].asInt());
      if (!value["persistence"].empty())
        perlin->SetPersistence(value["persistence"].asDouble());
      if (value["quality"].isString())
      {
        std::string quality = value["quality"].asString();
        boost::to_lower(quality);
        if (quality == "fast")
          perlin->SetNoiseQuality(noise::NoiseQuality::QUALITY_FAST);
        else if (quality == "standard")
          perlin->SetNoiseQuality(noise::NoiseQuality::QUALITY_STD);
        else if (quality == "best")
          perlin->SetNoiseQuality(noise::NoiseQuality::QUALITY_BEST);
        else
          throw ParsingException("unsupported quality specifier:\n" + value.toStyledString());
      }
      int s = seed;
      if (!value["seed"].empty())
        s ^= value["seed"].asInt();
      perlin->SetSeed(seed);
      m = perlin;
    }
    else if (module == "ridged" || module == "ridgedmulti")
    {
      std::shared_ptr<noise::module::RidgedMulti> ridged(new noise::module::RidgedMulti);
      if (!value["frequency"].empty())
        ridged->SetFrequency(value["frequency"].asDouble());
      if (!value["lacunarity"].empty())
        ridged->SetLacunarity(value["lacunarity"].asDouble());
      if (!value["octaves"].empty())
        ridged->SetOctaveCount(value["octaves"].asInt());
      if (value["quality"].isString())
      {
        std::string quality = value["quality"].asString();
        boost::to_lower(quality);
        if (quality == "fast")
          ridged->SetNoiseQuality(noise::NoiseQuality::QUALITY_FAST);
        else if (quality == "standard")
          ridged->SetNoiseQuality(noise::NoiseQuality::QUALITY_STD);
        else if (quality == "best")
          ridged->SetNoiseQuality(noise::NoiseQuality::QUALITY_BEST);
        else
          throw ParsingException("unsupported quality specifier:\n" + value.toStyledString());
      }
      int s = seed;
      if (!value["seed"].empty())
        s ^= value["seed"].asInt();
      ridged->SetSeed(seed);
      m = ridged;
    }
    else if (module == "voronoi")
    {
      std::shared_ptr<noise::module::Voronoi> voronoi(new noise::module::Voronoi);
      if (!value["frequency"].empty())
        voronoi->SetFrequency(value["frequency"].asDouble());
      if (!value["displacement"].empty())
        voronoi->SetDisplacement(value["displacement"].asDouble());
      int s = seed;
      if (!value["seed"].empty())
        s ^= value["seed"].asInt();
      voronoi->SetSeed(seed);
      m = voronoi;
    }
    else if (module == "cylinders")
    {
      std::shared_ptr<noise::module::Cylinders> cylinders(new noise::module::Cylinders);
      if (!value["frequency"].empty())
        cylinders->SetFrequency(value["frequency"].asDouble());
      m = cylinders;
    }
    else if (module == "spheres")
    {
      std::shared_ptr<noise::module::Spheres> spheres(new noise::module::Spheres);
      if (!value["frequency"].empty())
        spheres->SetFrequency(value["frequency"].asDouble());
      m = spheres;
    }
    else if (module == "turbulence")
    {
      std::shared_ptr<noise::module::Turbulence> turbulence(new noise::module::Turbulence);
      std::shared_ptr<noise::module::Module> src = buildNoiseGraph(value["sources"][0], modules, defs, heightMap, seed);
      turbulence->SetSourceModule(0, *src);
      if (!value["frequency"].empty())
        turbulence->SetFrequency(value["frequency"].asDouble());
      if (!value["power"].empty())
        turbulence->SetPower(value["power"].asDouble());
      if (!value["roughness"].empty())
        turbulence->SetRoughness(value["roughness"].asDouble());
      int s = seed;
      if (!value["seed"].empty())
        s ^= value["seed"].asInt();
      turbulence->SetSeed(seed);
      m = turbulence;
    }
    else if (module == "heightmap")
    {
      m = heightMap;
    }
    else
      throw ParsingException("unknown noise module:\n" + value.toStyledString());

    modules.push_back(m);

    if (value["name"].isString())
      defs.insert({value["name"].asString(), m});

    return m;
  }
}

max_stars_repo_name: voodooattack/ADWIF

max_issues_repo_name: voodooattack/ADWIF

max_forks_repo_name: voodooattack/ADWIF