text:
/*
 * Copyright (c) 2014, Stanislav Vorobiov
 * 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 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 "ConeLight.h"
#include "Utils.h"
#include "Scene.h"
#include "SceneObject.h"
#include "Renderer.h"
#include "RenderLightComponent.h"
#include "Settings.h"
#include <boost/bind.hpp>

namespace af
{
    ConeLight::ConeLight(const std::string& name)
    : Light(name),
      nearDistance_(0.0f),
      farDistance_(1.0f),
      coneAngle_(b2_pi / 4.0f)
    {
    }

    ConeLight::~ConeLight()
    {
    }

    void ConeLight::setNearDistance(float value)
    {
        if (nearDistance_ != value) {
            nearDistance_ = value;
            setDirty();
        }
    }

    void ConeLight::setFarDistance(float value)
    {
        if (farDistance_ != value) {
            farDistance_ = value;
            setDirty();
        }
    }

    void ConeLight::setConeAngle(float value)
    {
        if (coneAngle_ != value) {
            coneAngle_ = value;
            setDirty();
        }
    }

    void ConeLight::update()
    {
        vertices_.clear();
        colors_.clear();
        s_.clear();

        softVertices_.clear();
        softColors_.clear();
        softS_.clear();

        edgeVertices_.clear();
        edgeColors_.clear();
        edgeS_.clear();

        b2Vec2 absPos = b2Mul(finalTransform(), b2Vec2_zero);

        float farDist = parent()->gammaCorrected(farDistance_);

        if (nearDistance_ != 0.0f) {
            addNearEdge();
        }

        for (UInt32 i = 0; i < numRays(); ++i) {
            float a = coneAngle_ - 2.0f * coneAngle_ * i / (numRays() - 1);

            b2Vec2 pt = b2Mul(finalTransform(),
                b2Vec2(nearDistance_, nearDistance_ * tanf(a)));

            appendTriangleStrip(vertices_, pt.x, pt.y);
            appendColorStrip(colors_, color());
            appendGenericStrip(s_, nearS(1.0f));

            b2Vec2 endPt = b2Mul(finalTransform(), farDist * b2Vec2(cosf(a), sinf(a)));
            float fraction = 1.0f;

            if (!xray()) {
                parent()->scene()->rayCast(absPos, endPt,
                    boost::bind(&Light::rayCastCb, this,
                    _1, _2, _3, _4, boost::ref(endPt), boost::ref(fraction)));
            }

            appendTriangleStrip(vertices_, endPt.x, endPt.y);
            appendColorStrip(colors_, color());
            appendGenericStrip(s_, farS(1.0f - fraction));

            if (i == 0) {
                addEdge(pt, endPt, fraction, false);
            } else if (i == (numRays() - 1)) {
                addEdge(pt, endPt, fraction, true);
            }

            if (soft() && !xray()) {
                appendTriangleStrip(softVertices_, endPt.x, endPt.y);
                appendColorStrip(softColors_, color());
                appendGenericStrip(softS_, farS(1.0f - fraction));

                endPt = b2Mul(finalTransform(),
                    (farDist * fraction +
                    (1.0f - fraction) * softLength()) * b2Vec2(cosf(a), sinf(a)));

                appendTriangleStrip(softVertices_, endPt.x, endPt.y);
                appendColorStrip(softColors_, Color(0.0f, 0.0f, 0.0f, 0.0f));
                appendGenericStrip(softS_, farS(0.0f));
            }
        }
    }

    void ConeLight::render()
    {
        RenderSimple rop = renderer.renderTriangles();

        rop.addVertices(&vertices_[0], vertices_.size() / 2);
        rop.addGeneric1(&s_[0], s_.size());
        rop.addColors(&colors_[0], colors_.size() / 4);

        if (!softVertices_.empty()) {
            rop.addVertices(&softVertices_[0], softVertices_.size() / 2);
            rop.addGeneric1(&softS_[0], softS_.size());
            rop.addColors(&softColors_[0], softColors_.size() / 4);
        }

        rop.addVertices(&edgeVertices_[0], edgeVertices_.size() / 2);
        rop.addGeneric1(&edgeS_[0], edgeS_.size());
        rop.addColors(&edgeColors_[0], edgeColors_.size() / 4);
    }

    b2AABB ConeLight::calculateAABB()
    {
        float farDist = parent()->gammaCorrected(farDistance_);

        float p = farDist * sinf(coneAngle_);

        b2Vec2 v[] = {
            b2Mul(finalTransform(), b2Vec2(nearDistance_, -p)),
            b2Mul(finalTransform(), b2Vec2(nearDistance_, p)),
            b2Mul(finalTransform(), b2Vec2(farDist, -p)),
            b2Mul(finalTransform(), b2Vec2(farDist, p))
        };

        return computeAABB(v, sizeof(v)/sizeof(v[0]));
    }

    /*
     * This is needed in order to smooth that light cone edge crap that happens
     * even after 3 gaussian blur passes.
     * @{
     */

    void ConeLight::addNearEdge()
    {
        float p = nearDistance_ * tanf(coneAngle_);

        b2Vec2 pt = b2Mul(finalTransform(), b2Vec2(nearDistance_, -p));
        b2Vec2 endPt = b2Mul(finalTransform(), b2Vec2(nearDistance_, p));

        b2Vec2 v = (endPt - pt).Skew();
        v.Normalize();

        size_t bv = edgeVertices_.size();
        size_t bc = edgeColors_.size();
        size_t bs = edgeS_.size();

        appendTriangleStrip(edgeVertices_, pt.x, pt.y, bv);
        appendColorStrip(edgeColors_, color(), bc);
        appendGenericStrip(edgeS_, nearS(1.0f), bs);

        b2Vec2 tmp = pt + settings.light.edgeSmooth * v;

        appendTriangleStrip(edgeVertices_, tmp.x, tmp.y, bv);
        appendColorStrip(edgeColors_, Color(0.0f, 0.0f, 0.0f, 0.0f), bc);
        appendGenericStrip(edgeS_, nearS(1.0f), bs);

        appendTriangleStrip(edgeVertices_, endPt.x, endPt.y, bv);
        appendColorStrip(edgeColors_, color(), bc);
        appendGenericStrip(edgeS_, nearS(1.0f), bs);

        tmp = endPt + settings.light.edgeSmooth * v;

        appendTriangleStrip(edgeVertices_, tmp.x, tmp.y, bv);
        appendColorStrip(edgeColors_, Color(0.0f, 0.0f, 0.0f, 0.0f), bc);
        appendGenericStrip(edgeS_, nearS(1.0f), bs);
    }

    void ConeLight::addEdge(const b2Vec2& pt, const b2Vec2& endPt, float fraction, bool dir)
    {
        b2Vec2 v = (endPt - pt).Skew();
        if (dir) {
            v = -v;
        }
        v.Normalize();

        size_t bv = edgeVertices_.size();
        size_t bc = edgeColors_.size();
        size_t bs = edgeS_.size();

        appendTriangleStrip(edgeVertices_, pt.x, pt.y, bv);
        appendColorStrip(edgeColors_, color(), bc);
        appendGenericStrip(edgeS_, nearS(1.0f), bs);

        b2Vec2 tmp = pt + settings.light.edgeSmooth * v;

        appendTriangleStrip(edgeVertices_, tmp.x, tmp.y, bv);
        appendColorStrip(edgeColors_, Color(0.0f, 0.0f, 0.0f, 0.0f), bc);
        appendGenericStrip(edgeS_, nearS(1.0f), bs);

        appendTriangleStrip(edgeVertices_, endPt.x, endPt.y, bv);
        appendColorStrip(edgeColors_, color(), bc);
        appendGenericStrip(edgeS_, farS(1.0f - fraction), bs);

        tmp = endPt + settings.light.edgeSmooth * v;

        appendTriangleStrip(edgeVertices_, tmp.x, tmp.y, bv);
        appendColorStrip(edgeColors_, Color(0.0f, 0.0f, 0.0f, 0.0f), bc);
        appendGenericStrip(edgeS_, farS(1.0f - fraction), bs);
    }

    /*
     * @}
     */
}

max_stars_repo_name: Sheph/TriggerTime

max_issues_repo_name: Sheph/TriggerTime

max_forks_repo_name: Sheph/TriggerTime


text:
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <limits>
#include <numeric>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include "losslessops.h"

using namespace crolol;
using namespace backend;
namespace mp = boost::multiprecision;
using std::int64_t;
using slims = std::numeric_limits<int64_t>;
using int128 = mp::int128_t;
using float128 = mp::cpp_bin_float_quad;

static constexpr int64_t slmax = slims::max();
static constexpr int64_t slmin = slims::min();
static constexpr int64_t scale = 1000;
static const float128 slmaxlog2 = mp::log2(static_cast<float128>(slmax) / scale);
static const float128 slminlog2 = mp::log2(-static_cast<float128>(slmax) / scale);

static saferet clamp(const int128& n)
{
	saferet out;
	out.val = static_cast<int64_t>(n);

	if (n > static_cast<int128>(slmax))
		out.flow = overflow;
	else if (n < static_cast<int128>(slmin))
		out.flow = underflow;

	return out;
}

static saferet make_error(const flowstatus flow)
{
	saferet out;
	out.flow = flow;

	return out;
}

static saferet make_badarg(const int64_t val)
{
	saferet out = make_error(badarg);
	out.val = val;

	return out;
}

saferet backend::multiply(int64_t n, int64_t m)
{
	return clamp((static_cast<int128>(n) * static_cast<int128>(m))
		/ static_cast<int128>(scale));
}

saferet backend::divide(int64_t n, int64_t m)
{
	if (m == 0) return make_badarg(n);
	else return clamp((static_cast<int128>(n) * scale)
		/ static_cast<int128>(m));
}

saferet backend::pow(int64_t n, int64_t m)
{
	if (n < 0 && m % scale != 0) return make_badarg(m);
	else if (n == 0 && m == 0) return clamp(scale);
	else if (n == 0 && m < 0) return make_badarg(m);
	else if (n == scale || m == 0) return clamp(scale);
	else if (m == scale) return clamp(n);

	const float128 nf = static_cast<float128>(n) / scale;
	const float128 mf = static_cast<float128>(m) / scale;
	const float128 size = mp::log2(mp::abs(nf)) * mf;

	if (size > slmaxlog2) return clamp(slmax);
	else if (mp::abs(size) > slminlog2) return clamp(slmin);
	else return clamp(static_cast<int128>(
		mp::llrint(mp::trunc(mp::pow(nf, mf) * scale))
	));
}

saferet backend::factorial(int64_t n)
{
	if (n < 0 or n % scale != 0) return make_badarg(n);

	saferet acc = clamp(scale);

	for (int64_t i = 0; i < n && acc.flow == noflow; i += scale)
		acc = multiply(acc.val, i);

	return acc;
}

static const int64_t cr2pi = std::llrintl(std::truncl(M_PI * 2.L * scale));
static constexpr long double radtodeg = 360.L / (M_PI * 2.L);
static constexpr long double degtorad = (M_PI * 2.L) / 360.L;

static long double trigmod(int64_t n)
{
	return static_cast<long double>(n % cr2pi) * degtorad / scale;
}

saferet backend::sin(int64_t n)
{
	return clamp(static_cast<int128>(
		std::truncl(std::sin(trigmod(n))) * scale
	));
}

saferet backend::cos(int64_t n)
{
	return clamp(static_cast<int128>(
		std::truncl(std::cos(trigmod(n))) * scale
	));
}

saferet backend::tan(int64_t n)
{
	return clamp(static_cast<int128>(
		std::truncl(std::tan(trigmod(n))) * scale
	));
}

saferet backend::asin(int64_t n)
{
	if (n > scale or n < -scale) return make_badarg(n);
	else return clamp(static_cast<int128>(
		std::truncl(std::asin(
			static_cast<long double>(n) / scale
		)) * scale * radtodeg
	));
}

saferet backend::acos(int64_t n)
{
	if (n > scale or n < -scale) return make_badarg(n);
	else return clamp(static_cast<int128>(
		std::truncl(std::acos(
			static_cast<long double>(n) / scale
		)) * scale * radtodeg
	));
}

saferet backend::atan(int64_t n)
{
	return clamp(static_cast<int128>(
		std::truncl(std::atan(
			static_cast<long double>(n) / scale
		)) * scale * radtodeg
	));
}

ext: cpp

max_stars_repo_name: ocornoc/crolol

max_issues_repo_name: ocornoc/crolol

max_forks_repo_name: ocornoc/crolol


text:
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//% Code implementing the paper "Accelerated Quadratic Proxy for Geometric Optimization", SIGGRAPH 2016.
//% Disclaimer: The code is provided as-is for academic use only and without any guarantees.
//%             Please contact the author to report any bugs.
//% Written by Shahar Kovalsky (http://www.wisdom.weizmann.ac.il/~shaharko/)
//%            Meirav Galun (http://www.wisdom.weizmann.ac.il/~/meirav/)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#include "mex.h"
#include <Eigen/Dense>
#include <Eigen/SparseCore>
#include "mexHelpers.cpp"

using namespace Eigen;

void projBlockRotation(VectorXd &pA, int dim)
{
	int block_size = dim*dim;
	int num_blocks = pA.size() / block_size;
	JacobiSVD<MatrixXd> svdA(dim, dim, (ComputeFullU | ComputeFullV));
	bool flipped;
	MatrixXd U, V;
	Map<MatrixXd> currA(pA.data(), dim, dim);

	// project
	for (int ii = 0; ii < num_blocks; ii++)
	{
		// get current block
		new (&currA) Map<MatrixXd>(pA.data() + ii*block_size, dim, dim);
		// sign of determinant
		flipped = (currA.determinant() < 0);
		// svd
		svdA.compute(currA);
		// compute frames
		U = svdA.matrixU();
		V = svdA.matrixV();
		// ssvd
		if (flipped)
		{
			U.col(dim - 1) = -U.col(dim - 1);
		}
		// project block
		currA = U*V.transpose();
	}
}

void mexFunction(int nlhs, mxArray *plhs[],
	int nrhs, const mxArray*prhs[])

{
	// assign input
	int A_rows = mxGetM(prhs[0]); // # rows of A
	int A_cols = mxGetN(prhs[0]); // # cols of A
	double *dim;
	const Map<VectorXd> A(mxGetPr(prhs[0]), A_rows, A_cols);
	dim = mxGetPr(prhs[1]);

	// init output
	VectorXd pA(A_rows);
	pA = A;

	// project
	projBlockRotation(pA, *dim);

	// assign outputs
	mapDenseMatrixToMex(pA, &(plhs[0]));

}

max_stars_repo_name: shaharkov/AcceleratedQuadraticProxy

max_issues_repo_name: shaharkov/AcceleratedQuadraticProxy

max_forks_repo_name: shaharkov/AcceleratedQuadraticProxy


text:
//==============================================================================
//         Copyright 2003 - 2012 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#define NT2_UNIT_MODULE "nt2 operator toolbox - load/scalar Mode"

#include <boost/simd/include/functions/load.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <boost/simd/sdk/config/types.hpp>
#include <boost/simd/sdk/config/type_lists.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>

NT2_TEST_CASE_TPL(load, BOOST_SIMD_TYPES)
{
  using boost::simd::load;

  T data[5] = {0,1,2,3,4};

  NT2_TEST_EQUAL( (load<T,-4>(&data[0],4)), T(0) );
  NT2_TEST_EQUAL( (load<T,-4>(&data[0],5)), T(1) );
  NT2_TEST_EQUAL( (load<T,-4>(&data[0],6)), T(2) );
  NT2_TEST_EQUAL( (load<T,-4>(&data[0],7)), T(3) );
  NT2_TEST_EQUAL( (load<T,-4>(&data[0],8)), T(4) );

  NT2_TEST_EQUAL( (load<T,-3>(&data[0],3)), T(0) );
  NT2_TEST_EQUAL( (load<T,-3>(&data[0],4)), T(1) );
  NT2_TEST_EQUAL( (load<T,-3>(&data[0],5)), T(2) );
  NT2_TEST_EQUAL( (load<T,-3>(&data[0],6)), T(3) );
  NT2_TEST_EQUAL( (load<T,-3>(&data[0],7)), T(4) );

  NT2_TEST_EQUAL( (load<T,-2>(&data[0],2)), T(0) );
  NT2_TEST_EQUAL( (load<T,-2>(&data[0],3)), T(1) );
  NT2_TEST_EQUAL( (load<T,-2>(&data[0],4)), T(2) );
  NT2_TEST_EQUAL( (load<T,-2>(&data[0],5)), T(3) );
  NT2_TEST_EQUAL( (load<T,-2>(&data[0],6)), T(4) );

  NT2_TEST_EQUAL( (load<T,-1>(&data[0],1)), T(0) );
  NT2_TEST_EQUAL( (load<T,-1>(&data[0],2)), T(1) );
  NT2_TEST_EQUAL( (load<T,-1>(&data[0],3)), T(2) );
  NT2_TEST_EQUAL( (load<T,-1>(&data[0],4)), T(3) );
  NT2_TEST_EQUAL( (load<T,-1>(&data[0],5)), T(4) );

  NT2_TEST_EQUAL( load<T>(&data[0],0), T(0) );
  NT2_TEST_EQUAL( load<T>(&data[0],1), T(1) );
  NT2_TEST_EQUAL( load<T>(&data[0],2), T(2) );
  NT2_TEST_EQUAL( load<T>(&data[0],3), T(3) );
  NT2_TEST_EQUAL( load<T>(&data[0],4), T(4) );

  NT2_TEST_EQUAL( (load<T,0>(&data[0],0)), T(0) );
  NT2_TEST_EQUAL( (load<T,0>(&data[0],1)), T(1) );
  NT2_TEST_EQUAL( (load<T,0>(&data[0],2)), T(2) );
  NT2_TEST_EQUAL( (load<T,0>(&data[0],3)), T(3) );
  NT2_TEST_EQUAL( (load<T,0>(&data[0],4)), T(4) );

  NT2_TEST_EQUAL( (load<T,1>(&data[0],-1)), T(0) );
  NT2_TEST_EQUAL( (load<T,1>(&data[0],0)) , T(1) );
  NT2_TEST_EQUAL( (load<T,1>(&data[0],1)) , T(2) );
  NT2_TEST_EQUAL( (load<T,1>(&data[0],2)) , T(3) );
  NT2_TEST_EQUAL( (load<T,1>(&data[0],3)) , T(4) );

  NT2_TEST_EQUAL( (load<T,2>(&data[0],-2)), T(0) );
  NT2_TEST_EQUAL( (load<T,2>(&data[0],-1)), T(1) );
  NT2_TEST_EQUAL( (load<T,2>(&data[0],0)) , T(2) );
  NT2_TEST_EQUAL( (load<T,2>(&data[0],1)) , T(3) );
  NT2_TEST_EQUAL( (load<T,2>(&data[0],2)) , T(4) );

  NT2_TEST_EQUAL( (load<T,3>(&data[0],-3)), T(0) );
  NT2_TEST_EQUAL( (load<T,3>(&data[0],-2)), T(1) );
  NT2_TEST_EQUAL( (load<T,3>(&data[0],-1)), T(2) );
  NT2_TEST_EQUAL( (load<T,3>(&data[0],0)) , T(3) );
  NT2_TEST_EQUAL( (load<T,3>(&data[0],1)) , T(4) );

  NT2_TEST_EQUAL( (load<T,4>(&data[0],-4)), T(0) );
  NT2_TEST_EQUAL( (load<T,4>(&data[0],-3)), T(1) );
  NT2_TEST_EQUAL( (load<T,4>(&data[0],-2)), T(2) );
  NT2_TEST_EQUAL( (load<T,4>(&data[0],-1)), T(3) );
  NT2_TEST_EQUAL( (load<T,4>(&data[0],0)) , T(4) );
}

NT2_TEST_CASE( load_sequence )
{
  using boost::simd::load;
  using boost::simd::tag::load_;
  typedef BOOST_SIMD_DEFAULT_EXTENSION  ext_t;

  double d = 3.4;
  float  f = 1.8f;
  char   c = 'a';

  boost::fusion::vector<double,float,char> v;

  v = load< boost::fusion::vector<double,float,char> >(boost::fusion::make_vector(&d, &f, &c), 0);

  NT2_TEST_EQUAL(boost::fusion::at_c<0>(v) , d);
  NT2_TEST_EQUAL(boost::fusion::at_c<1>(v) , f);
  NT2_TEST_EQUAL(boost::fusion::at_c<2>(v) , c);
}

NT2_TEST_CASE( load_pointer_of_sequence )
{
  using boost::simd::load;
  using boost::simd::tag::load_;
  typedef BOOST_SIMD_DEFAULT_EXTENSION  ext_t;

  double d = 3.4;
  float  f = 1.8f;
  char   c = 'a';

  boost::fusion::vector<double,float,char> s(d,f,c);
  boost::fusion::vector<double,float,char> v;

  v = load< boost::fusion::vector<double,float,char> >(&s, 0);

  NT2_TEST_EQUAL(boost::fusion::at_c<0>(v) , d);
  NT2_TEST_EQUAL(boost::fusion::at_c<1>(v) , f);
  NT2_TEST_EQUAL(boost::fusion::at_c<2>(v) , c);
}


text:
/**
   @file modulescheduler.cpp
   @brief This file is part of Kalinka mediaserver.
   @author Ivan Murashko <ivan.murashko@gmail.com>

   Copyright (c) 2007-2012 Kalinka Team

   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.

   CHANGE HISTORY

   @date
   - 2009/01/09 created by ipp (Ivan Murashko)
   - 2009/08/02 header was changed by header.py script
   - 2010/01/06 header was changed by header.py script
   - 2011/01/01 header was changed by header.py script
   - 2012/02/03 header was changed by header.py script
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <mysql.h>

#include <boost/bind.hpp>

#include "modulescheduler.h"
#include "log.h"
#include "exception.h"

using namespace klk;
using namespace klk::mod;

//
// TimerThread class
//

// Constructor
TimerThread::TimerThread(TimerFunction f, time_t intrv) :
    Thread(), m_f(f), m_intrv(intrv), m_wait()
{
}

// starts the thread
void TimerThread::start()
{
    // wait first
    m_wait.startWait(m_intrv);

    while (!isStopped())
    {
        try
        {
            // do the action
            m_f();
        }
        catch(const std::exception& err)
        {
            klk_log(KLKLOG_ERROR,
                    "Got an error in timer thread: %s",
                    err.what());
        }
        catch(...)
        {
            klk_log(KLKLOG_ERROR, "Got an unspecified error in timer thread");
        }

        m_wait.startWait(m_intrv);
    }
}

// stops the thread
void TimerThread::stop() throw()
{
    Thread::stop();
    m_wait.stopWait();
}

//
// Scheduler class
//

// Constructor
Scheduler::Scheduler() :
    base::Scheduler(), m_list()
{
}

// Adds a thread to be started
void Scheduler::addThread(const IThreadPtr& thread)
{
    Locker lock(&m_lock);
    BOOST_ASSERT(thread);
    BOOST_ASSERT(std::find(m_list.begin(), m_list.end(), thread) ==
                 m_list.end());
    m_list.push_back(thread);
}

// @brief Starts the scheduler
void Scheduler::start()
{
    clear(); // to be able restart a module

    std::for_each(m_list.begin(), m_list.end(),
                  boost::bind(&Scheduler::startThread, this, _1));
}

max_stars_repo_name: ivanmurashko/kalinka

max_issues_repo_name: ivanmurashko/kalinka

max_forks_repo_name: ivanmurashko/kalinka


text:
	/*
 * Copyright (C) 2005-2011 National Association of REALTORS(R)
 *
 * All rights reserved.
 *
 * 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, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished
 * to do so, provided that the above copyright notice(s) and this
 * permission notice appear in all copies of the Software and that
 * both the above copyright notice(s) and this permission notice
 * appear in supporting documentation.
 */

#include <fstream>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include "librets.h"
#include "librets/CurlHttpClient.h"
#include "librets/XmlMetadataParser.h"
#include "librets/DefaultMetadataCollector.h"
#include "librets/IncrementalMetadataFinder.h"
#include "librets/SearchRequest.h"
#include "librets/ServerInfoRequest.h"
#include "librets/ServerInfoResponse.h"
#include "librets/GetObjectRequest.h"
#include "librets/GetObjectResponse.h"
#include "librets/ObjectDescriptor.h"
#include "librets/PayloadListResultSet.h"
#include "librets/str_stream.h"
#include "librets/ExceptionErrorHandler.h"
#include "librets/RetsHttpException.h"
#include "boost/lexical_cast.hpp"

using namespace librets;
using namespace librets::util;
using std::ostringstream;
using std::string;
namespace ba = boost::algorithm;

typedef RetsSession CLASS;

const char * CLASS::DEFAULT_USER_AGENT  = "librets/" LIBRETS_VERSION;
const RetsVersion CLASS::DEFAULT_RETS_VERSION = RETS_1_5;
const char * CLASS::HTTP_EXPECT_HEADER  = "Expect";
const char * CLASS::RETS_REQUEST_ID_HEADER = "RETS-Request-ID";
const char * CLASS::RETS_SESSION_ID_HEADER = "RETS-Session-ID";
const char * CLASS::RETS_VERSION_HEADER = "RETS-Version";
const char * CLASS::RETS_UA_AUTH_HEADER = "RETS-UA-Authorization";
const char * CLASS::RETS_1_0_STRING     = "RETS/1.0";
const char * CLASS::RETS_1_5_STRING     = "RETS/1.5";
const char * CLASS::RETS_1_7_STRING     = "RETS/1.7";
const char * CLASS::RETS_1_7_2_STRING   = "RETS/1.7.2";
const char * CLASS::RETS_1_8_STRING     = "RETS/1.8";
const char * CLASS::RETS_1_8_0_STRING   = "RETS/1.8.0";

const int CLASS::MODE_CACHE             = 0x01;
const int CLASS::MODE_NO_STREAM         = 0x02;
const int CLASS::MODE_NO_EXPECT         = 0x04;
const int CLASS::MODE_NO_SSL_VERIFY     = 0x08;

static librets::EncodingType
GetEncoding(RetsHttpResponsePtr httpResponse, librets::EncodingType defaultEncoding)
{
    string content_type = httpResponse->GetContentType();
    if (content_type.empty())
        return defaultEncoding;

    // parse content type
    StringVector parameters;
    ba::split(parameters, content_type, ba::is_any_of(";"));
    StringVector::iterator i;
    for (i = parameters.begin(); i != parameters.end(); i++)
    {
        string parameter = ba::trim_copy(*i);
        string name;
        string value;
        if (splitField(parameter, "=", name, value) && (ba::to_lower_copy(name) == "charset"))
        {
            ba::trim(value);
            ba::to_lower(value);

            // Strip off leading and trailing quote, if it exists
            string::size_type quotePosition = value.find_first_of("\"");
            if (quotePosition == string::size_type(0))
            {
                value.erase(0, 1);
            }

            quotePosition = value.find_last_of("\"");
            if (quotePosition == (value.size() - 1))
            {
                value.erase(value.size() - 1, 1);
            }

            if (value == "utf-8")
                return RETS_XML_UTF8_ENCODING;
            else if (value == "iso-8859-1")
                return RETS_XML_ISO_ENCODING;
            else
                return defaultEncoding;
        }
    }

    return defaultEncoding;
}

CLASS::RetsSession(string login_url)
{
    mLoginUrl = login_url;
    mLoginResponse.reset();
    mCapabilityUrls.reset();
    mHttpMethod = RetsHttpRequest::POST;
    mHttpClient.reset(new CurlHttpClient());
    mHttpClient->SetUserAgent(DEFAULT_USER_AGENT);
    mRetsVersion = DEFAULT_RETS_VERSION;
    mErrorHandler = ExceptionErrorHandler::GetInstance();
    mIncrementalMetadata = true;
    mUserAgentAuthCalculator.SetUserAgentPassword("");
    mUserAgentAuthCalculator.SetUserAgentAuthType(USER_AGENT_AUTH_RETS_1_7);
    SetDefaultEncoding(RETS_XML_ISO_ENCODING);
    mFlags = 0;
    mLoggedIn = false;
    mTimeout = 0;
    /*
     * By default, do not log GetObject() transactions.
     */
    mLogEverything = false;
    mLogStream.reset(new std::ofstream());
    mHttpResponseCaching = false;
    mHttpResponse.reset();
}

CLASS::~RetsSession()
{
    if (mLogStream->is_open())
    {
        mLogStream->close();
    }
}

string CLASS::GetLoginUrl() const
{
    return mLoginUrl;
}

RetsHttpResponsePtr CLASS::DoRequest(RetsHttpRequest * request)
{
#ifdef LIBRETS_THREAD_SAFE
    boost::mutex::scoped_lock   lock(mMutex);
#endif

    if (mUserAgentAuthCalculator.HasAuthorizationValue())
    {
        mUserAgentAuthCalculator.SetRequestId("");
        mUserAgentAuthCalculator.SetSessionId("");
        if (mUserAgentAuthCalculator.GetUserAgentAuthType() == USER_AGENT_AUTH_RETS_1_7)
        {
            string requestId = mHttpClient->GetCookie(RETS_REQUEST_ID_HEADER);
            string sessionId = mHttpClient->GetCookie(RETS_SESSION_ID_HEADER);

            mUserAgentAuthCalculator.SetRequestId(requestId);
            mUserAgentAuthCalculator.SetSessionId(sessionId);
        }
        mUserAgentAuthCalculator.SetVersionInfo(
            mHttpClient->GetDefaultHeader(RETS_VERSION_HEADER));
        string headerValue = "Digest " + mUserAgentAuthCalculator.AuthorizationValue();
        request->SetHeader(RETS_UA_AUTH_HEADER, headerValue);
    }

    if (mFlags & MODE_NO_EXPECT && request->GetMethod() == RetsHttpRequest::POST)
    {
        mHttpClient->SetDefaultHeader(HTTP_EXPECT_HEADER, "");
    }

    RetsHttpResponsePtr httpResponse = mHttpClient->StartRequest(request);

    if (mHttpResponseCaching)
    {
        mHttpResponse = httpResponse;
    }

    /*
     * If we are not streaming, complete the request.
     */
    if (mFlags & MODE_NO_STREAM)
    {
        while (mHttpClient->ContinueRequest());
    }

    return httpResponse;
}

void CLASS::AssertSuccessfulResponse(RetsHttpResponsePtr response,
                                     string url)
{
    int responseCode = response->GetResponseCode();
    if (responseCode != 200)
    {
        ostringstream message;
        message << "Could not get URL [" << url << "] - HTTP response code: "
                << responseCode
                << " " << response->GetAdditionalErrorText();
        throw RetsHttpException(responseCode, message.str());
    }
}

bool CLASS::Login(string user_name, string passwd)
{
    return Login(user_name, passwd, "", "");
}

bool CLASS::Login(string user_name,
                    string passwd,
                    string brokerCode,
                    string savedMetadataTimestamp)
{
    mLoginResponse.reset();
    mCapabilityUrls.reset();
    mLoggedIn = false;
    mHttpClient->SetDefaultHeader(RETS_VERSION_HEADER,
                                  RetsVersionToString(mRetsVersion));
    RetsHttpRequest request;
    request.SetUrl(mLoginUrl);
    if (!brokerCode.empty())
    {
        request.SetQueryParameter("BrokerCode", brokerCode);
    }

    if (!savedMetadataTimestamp.empty())
    {
        request.SetQueryParameter("SavedMetadataTimestamp", savedMetadataTimestamp);
    }

    mHttpClient->SetUserCredentials(user_name, passwd);
    RetsHttpResponsePtr httpResponse(DoRequest(&request));

    if (httpResponse->GetResponseCode() == 401)
    {
        /* Just make sure we read the rest of the original response and free
           up the CurlEasy object before we issue the next request. It will
           make it possible to re-use the existing connection. */
        httpResponse->FinishResponse();
        httpResponse = DoRequest(&request);
        if (httpResponse->GetResponseCode() == 401)
        {
            return false;
        }
    }

    AssertSuccessfulResponse(httpResponse, mLoginUrl);
    mDetectedRetsVersion =
        RetsVersionFromString(httpResponse->GetHeader(RETS_VERSION_HEADER));
    mHttpClient->SetDefaultHeader(RETS_VERSION_HEADER,
                                  RetsVersionToString(mDetectedRetsVersion));

    mLoginResponse.reset(new LoginResponse);
    mLoginResponse->Parse(httpResponse->GetInputStream(), mDetectedRetsVersion,
        GetEncoding(httpResponse, mEncoding));
    if (mLoginResponse->GetRetsReplyCode() != 0)
        return false;

    mCapabilityUrls.reset(
        mLoginResponse->CreateCapabilityUrls(mLoginUrl).release());

    RetrieveAction();

    mLoggedIn = true;

    try
    {
        std::string seconds = mLoginResponse->GetTimeout();
        mTimeout = boost::lexical_cast<int>(seconds);
    }
    catch (boost::bad_lexical_cast &)
    {
        mTimeout = 0;
    }

    return true;
}

LoginResponse * CLASS::GetLoginResponse() const
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    return mLoginResponse.get();
}

CapabilityUrls * CLASS::GetCapabilityUrls() const
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    return mCapabilityUrls.get();
}

void CLASS::RetrieveAction()
{
    string actionUrl = mCapabilityUrls->GetActionUrl();
    if (actionUrl == "")
    {
        mAction = "";
        return;
    }

    RetsHttpRequest request;
    request.SetUrl(actionUrl);
    RetsHttpResponsePtr httpResponse(DoRequest(&request));

    AssertSuccessfulResponse(httpResponse, actionUrl);
    mAction = readIntoString(httpResponse->GetInputStream());
}

string CLASS::GetAction()
{
    return mAction;
}

RetsMetadata * CLASS::GetMetadata()
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    if (!mMetadata)
    {
        InitializeMetadata();
    }
    return mMetadata.get();
}

void CLASS::GetMetadata(std::ostream & outputStream)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    string getMetadataUrl = mCapabilityUrls->GetGetMetadataUrl();
    RetsHttpRequest request;
    request.SetUrl(getMetadataUrl);
    request.SetMethod(mHttpMethod);
    request.SetQueryParameter("Type", "METADATA-SYSTEM");
    request.SetQueryParameter("ID", "*");
    request.SetQueryParameter("Format", "COMPACT");
    RetsHttpResponsePtr httpResponse(DoRequest(&request));
    AssertSuccessfulResponse(httpResponse, getMetadataUrl);
    readUntilEof(httpResponse->GetInputStream(), outputStream);
}

BinaryDataAPtr CLASS::GetMetadata_()
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    BinaryDataAPtr data(new BinaryData());

    string getMetadataUrl = mCapabilityUrls->GetGetMetadataUrl();
    RetsHttpRequest request;

    request.SetUrl(getMetadataUrl);
    request.SetMethod(mHttpMethod);
    request.SetQueryParameter("Type", "METADATA-SYSTEM");
    request.SetQueryParameter("ID", "*");
    request.SetQueryParameter("Format", "COMPACT");
    /*
     * Start the transaction, copy to output stream
     */
    RetsHttpResponsePtr httpResponse = DoRequest(&request);
    AssertSuccessfulResponse(httpResponse, getMetadataUrl);

    data->ReadToEof(httpResponse->GetInputStream());

    return data;
}

bool CLASS::IsIncrementalMetadata() const
{
    return mIncrementalMetadata;
}

void CLASS::SetIncrementalMetadata(bool incrementalMetadata)
{
    mIncrementalMetadata = incrementalMetadata;
}

void CLASS::SetCollector(MetadataElementCollectorPtr collector)
{
    mLoaderCollector = collector;
}

std::string CLASS::MetadataTypeToString(MetadataElement::Type type)
{
    switch (type)
    {
        case MetadataElement::SYSTEM:
            return "METADATA-SYSTEM";
        case MetadataElement::RESOURCE:
            return "METADATA-RESOURCE";
        case MetadataElement::CLASS:
            return "METADATA-CLASS";
        case MetadataElement::TABLE:
            return "METADATA-TABLE";
        case MetadataElement::UPDATE:
            return "METADATA-UPDATE";
        case MetadataElement::UPDATE_TYPE:
            return "METADATA-UPDATE_TYPE";
        case MetadataElement::OBJECT:
            return "METADATA-OBJECT";
        case MetadataElement::SEARCH_HELP:
            return "METADATA-SEARCH_HELP";
        case MetadataElement::EDIT_MASK:
            return "METADATA-EDIT_MASK";
        case MetadataElement::LOOKUP:
            return "METADATA-LOOKUP";
        case MetadataElement::LOOKUP_TYPE:
            return "METADATA-LOOKUP_TYPE";
        case MetadataElement::UPDATE_HELP:
            return "METADATA-UPDATE_HELP";
        case MetadataElement::VALIDATION_LOOKUP:
            return "METADATA-VALIDATION_LOOKUP";
        case MetadataElement::VALIDATION_LOOKUP_TYPE:
            return "METADATA-VALIDATION_LOOKUP_TYPE";
        case MetadataElement::VALIDATION_EXTERNAL:
            return "METADATA-VALIDATION_EXTERNAL";
        case MetadataElement::VALIDATION_EXTERNAL_TYPE:
            return "METADATA-VALIDATION_EXTERNAL_TYPE";
        case MetadataElement::VALIDATION_EXPRESSION:
            return "METADATA-VALIDATION_EXPRESSION";
        case MetadataElement::FOREIGN_KEY:
            return "METADATA-FOREIGN_KEYS";
        default:
            throw RetsException(str_stream() << "Invalid metadata type: "
                                << type);
    }
}

void CLASS::LoadMetadata(MetadataElement::Type type,
                         std::string level)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    string getMetadataUrl = mCapabilityUrls->GetGetMetadataUrl();
    RetsHttpRequest request;
    request.SetUrl(getMetadataUrl);
    request.SetMethod(mHttpMethod);
    request.SetQueryParameter("Type", MetadataTypeToString(type));
    request.SetQueryParameter("ID", level.empty() ? "0" : level);
    request.SetQueryParameter("Format", "COMPACT");
    RetsHttpResponsePtr httpResponse(DoRequest(&request));

    AssertSuccessfulResponse(httpResponse, getMetadataUrl);

    XmlMetadataParserPtr parser(new XmlMetadataParser(mLoaderCollector,
                                                      mErrorHandler));
    parser->SetEncoding(GetEncoding(httpResponse, mEncoding));
    parser->Parse(httpResponse->GetInputStream());
}

void CLASS::InitializeMetadata()
{
    if (mIncrementalMetadata)
    {
        IncrementalMetadataFinderPtr
            incrementalFinder(new IncrementalMetadataFinder(this));
        mMetadata.reset(new RetsMetadata(incrementalFinder));
    }
    else
    {
        RetrieveFullMetadata();
    }
}

void CLASS::RetrieveFullMetadata()
{
    string getMetadataUrl = mCapabilityUrls->GetGetMetadataUrl();
    RetsHttpRequest request;
    request.SetUrl(getMetadataUrl);
    request.SetMethod(mHttpMethod);
    request.SetQueryParameter("Type", "METADATA-SYSTEM");
    request.SetQueryParameter("ID", "*");
    request.SetQueryParameter("Format", "COMPACT");
    RetsHttpResponsePtr httpResponse(DoRequest(&request));

    AssertSuccessfulResponse(httpResponse, getMetadataUrl);

    DefaultMetadataCollectorPtr collector(new DefaultMetadataCollector());
    XmlMetadataParserPtr parser(
        new XmlMetadataParser(collector, mErrorHandler));
    parser->SetEncoding(GetEncoding(httpResponse, mEncoding));
    parser->Parse(httpResponse->GetInputStream());

    mMetadata.reset(new RetsMetadata(collector));
}

SearchRequestAPtr CLASS::CreateSearchRequest(string searchType,
                                             string searchClass,
                                             string query)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    std::auto_ptr<SearchRequest> searchRequest(
        new SearchRequest(searchType, searchClass, query));
    if (mDetectedRetsVersion == RETS_1_0)
    {
        searchRequest->SetQueryType(SearchRequest::DMQL);
    }
    else
    {
        searchRequest->SetQueryType(SearchRequest::DMQL2);
    }
    return searchRequest;
}

SearchResultSetAPtr CLASS::Search(SearchRequest * request)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    string searchUrl = mCapabilityUrls->GetSearchUrl();
    request->SetUrl(searchUrl);
    request->SetMethod(mHttpMethod);
    /*
     * Start the transaction.
     */
    RetsHttpResponsePtr httpResponse = DoRequest(request);

    AssertSuccessfulResponse(httpResponse, searchUrl);

    SearchResultSetAPtr resultSet(new SearchResultSet());
    if (mFlags & MODE_CACHE)
    {
        /*
         * Warning ... must set the caching flag before setting the input stream
         * because that code has the side effecting of initializing the parser and
         * will try to parse the first entry if it exists.
         */
        resultSet->SetCaching(true);
    }
    resultSet->SetEncoding(GetEncoding(httpResponse, mEncoding));
    resultSet->SetInputStream(httpResponse->GetInputStream());

    return resultSet;
}

void CLASS::Search(SearchRequest * request, std::ostream & outputStream)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    string searchUrl = mCapabilityUrls->GetSearchUrl();
    request->SetUrl(searchUrl);
    request->SetMethod(mHttpMethod);
    /*
     * Start the transaction, copy to output stream
     */
    RetsHttpResponsePtr httpResponse = DoRequest(request);

    AssertSuccessfulResponse(httpResponse, searchUrl);

    readUntilEof(httpResponse->GetInputStream(), outputStream);
}

BinaryDataAPtr CLASS::Search_(SearchRequest * request)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    BinaryDataAPtr data(new BinaryData());

    string searchUrl = mCapabilityUrls->GetSearchUrl();
    request->SetUrl(searchUrl);
    request->SetMethod(mHttpMethod);
    /*
     * Start the transaction, copy to output stream
     */
    RetsHttpResponsePtr httpResponse = DoRequest(request);

    AssertSuccessfulResponse(httpResponse, searchUrl);

    data->ReadToEof(httpResponse->GetInputStream());

    return data;
}

istreamPtr CLASS::SearchStream(SearchRequest * request)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    string searchUrl = mCapabilityUrls->GetSearchUrl();
    request->SetUrl(searchUrl);
    request->SetMethod(mHttpMethod);
    /*
     * Start the transaction, copy to output stream
     */
    RetsHttpResponsePtr httpResponse = DoRequest(request);

    AssertSuccessfulResponse(httpResponse, searchUrl);

    return httpResponse->GetInputStream();
}

void CLASS::EnableResponseCaching()
{
    mHttpResponseCaching = true;
}

const RetsHttpResponsePtr& CLASS::GetHttpResponse() const
{
    return mHttpResponse;
}

ServerInformationResponseAPtr CLASS::GetServerInformation(std::string resourceName,
                                                    std::string className,
                                                    bool standardNames)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    ServerInformationRequestAPtr request(new ServerInformationRequest());
    string serverInfoUrl = mCapabilityUrls->GetServerInformationUrl();

    if (serverInfoUrl.empty())
        throw RetsException("The ServerInformation Transaction is not supported.");

    request->SetClassName(className);
    request->SetResourceName(resourceName);
    request->SetStandardNames(standardNames);
    request->SetUrl(serverInfoUrl);
    request->SetMethod(mHttpMethod);

    RetsHttpResponsePtr httpResponse = DoRequest(request.get());

    AssertSuccessfulResponse(httpResponse, serverInfoUrl);

    ServerInformationResponseAPtr serverInformation(new ServerInformationResponse());

    serverInformation->SetEncoding(GetEncoding(httpResponse, mEncoding));
    serverInformation->Parse(httpResponse->GetInputStream());

    return serverInformation;
}

GetObjectResponseAPtr CLASS::GetObject(GetObjectRequest * request)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    RetsHttpRequestPtr httpRequest = request->CreateHttpRequest(mRetsVersion);
    string getObjectUrl = mCapabilityUrls->GetGetObjectUrl();
    httpRequest->SetUrl(getObjectUrl);
    httpRequest->SetMethod(mHttpMethod);

    if (mLogEverything)
      httpRequest->SetLogging();

    RetsHttpResponsePtr httpResponse = DoRequest(httpRequest.get());

    AssertSuccessfulResponse(httpResponse, getObjectUrl);

    GetObjectResponseAPtr response(new GetObjectResponse());
    if (request->HasDefaultObjectKeyAndId())
    {
        response->SetDefaultObjectKeyAndId(request->GetDefaultObjectKey(),
                                           request->GetDefaultObjectId());
    }
    response->SetHttpResponse(httpResponse->GetResponseCode(), httpResponse->GetAdditionalErrorText());
    response->Parse(httpResponse, request->GetIgnoreMalformedHeaders());
    return response;
}

LogoutResponseAPtr CLASS::Logout()
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    mLoggedIn = false;
    LogoutResponseAPtr logoutResponse;
    string logoutUrl = mCapabilityUrls->GetLogoutUrl();
    if (logoutUrl == "")
    {
        return logoutResponse;
    }

    RetsHttpRequest request;
    request.SetUrl(logoutUrl);
    RetsHttpResponsePtr httpResponse(DoRequest(&request));

    AssertSuccessfulResponse(httpResponse, logoutUrl);

    logoutResponse.reset(new LogoutResponse());
    logoutResponse->Parse(httpResponse->GetInputStream(), mDetectedRetsVersion);
    return logoutResponse;
}

void CLASS::SetUserAgent(string userAgent)
{
    mHttpClient->SetUserAgent(userAgent);
    mUserAgentAuthCalculator.SetUserAgent(userAgent);
}

void CLASS::UseHttpGet(bool useHttpGet)
{
    if (useHttpGet)
    {
        mHttpMethod = RetsHttpRequest::GET;
    }
    else
    {
        mHttpMethod = RetsHttpRequest::POST;
    }
}

void CLASS::SetHttpLogger(RetsHttpLogger * logger)
{
    mHttpClient->SetLogger(logger);
}

RetsHttpLogger* CLASS::GetHttpLogger() const
{
    return mHttpClient->GetLogger();
}

void CLASS::SetHttpLogName(std::string logfile)
{
    if (mLogStream->is_open())
    {
        mLogStream->close();
    }

    if (logfile.length() > 0)
    {
        mLogStream->open(logfile.c_str());
        if (mLogStream->is_open())
        {
            mLogger.reset(new StreamHttpLogger(mLogStream.get()));
            SetHttpLogger(mLogger.get());
        }
    }
}

RetsVersion CLASS::GetRetsVersion() const
{
    return mRetsVersion;
}

void CLASS::SetRetsVersion(RetsVersion retsVersion)
{
    mRetsVersion = retsVersion;
}

RetsVersion CLASS::GetDetectedRetsVersion() const
{
    return mDetectedRetsVersion;
}

string CLASS::RetsVersionToString(RetsVersion retsVersion)
{
    if (retsVersion == RETS_1_0)
    {
        return RETS_1_0_STRING;
    }
    else if (retsVersion == RETS_1_5)
    {
        return RETS_1_5_STRING;
    }
    else if (retsVersion == RETS_1_7)
    {
        return RETS_1_7_STRING;
    }
    else if (retsVersion == RETS_1_7_2)
    {
        return RETS_1_7_2_STRING;
    }
    else if (retsVersion == RETS_1_8)
    {
        return RETS_1_8_STRING;
    }
    else if (retsVersion == RETS_1_8_0)
    {
        return RETS_1_8_0_STRING;
    }
    else
    {
        throw RetsException(str_stream() << "Invalid RetsVersion: "
                            << retsVersion);
    }
}

RetsVersion CLASS::RetsVersionFromString(string versionString)
{
    if (versionString == RETS_1_0_STRING)
    {
        return RETS_1_0;
    }
    else if (versionString == RETS_1_5_STRING)
    {
        return RETS_1_5;
    }
    else if (versionString == RETS_1_7_STRING)
    {
        return RETS_1_7;
    }
    else if (versionString == RETS_1_7_2_STRING)
    {
        return RETS_1_7_2;
    }
    else if (versionString == RETS_1_8_STRING)
    {
        return RETS_1_8;
    }
    else if (versionString == RETS_1_8_0_STRING)
    {
        return RETS_1_8_0;
    }
    else if (versionString.empty())
    {
        return RETS_1_0;
    }
    else
    {
        throw RetsException(str_stream() << "Invalid RETS version string: "
                            << versionString);
    }
}

void CLASS::SetErrorHandler(RetsErrorHandler * errorHandler)
{
    mErrorHandler = errorHandler;
}

void CLASS::SetUserAgentAuthType(UserAgentAuthType type)
{
    if (type != USER_AGENT_AUTH_INTEREALTY && type != USER_AGENT_AUTH_RETS_1_7)
    {
        throw RetsException(str_stream()
                            << "Unsupported User-Agent authentication type: "
                            << type);
    }

    mUserAgentAuthCalculator.SetUserAgentAuthType(type);
}

UserAgentAuthType CLASS::GetUserAgentAuthType() const
{
    return mUserAgentAuthCalculator.GetUserAgentAuthType();
}

void CLASS::SetUserAgentPassword(std::string userAgentPassword)
{
    mUserAgentAuthCalculator.SetUserAgentPassword(userAgentPassword);
}

void CLASS::SetDefaultEncoding(EncodingType encoding)
{
    mEncoding    = encoding;
}

void CLASS::Cleanup()
{
    mHttpClient.reset();
}

void CLASS::SetLogEverything(bool logging)
{
    mLogEverything = logging;
}

void CLASS::SetModeFlags(unsigned int flags)
{
    mFlags = flags;

    /*
     * If we are in no streaming mode, the cache is required.
     */
    if (mFlags & MODE_NO_STREAM)
        mFlags |= MODE_CACHE;

    /*
     * If we are disabling SSL verification, tell http client.
     */
    if (mFlags & MODE_NO_SSL_VERIFY)
        mHttpClient->SetModeFlags(MODE_NO_SSL_VERIFY);
}

void CLASS::SetProxy(std::string url, std::string password)
{
    mHttpClient->SetProxy(url,password);
}

void CLASS::SetTimeout(int seconds)
{
    mTimeout = seconds;
    mHttpClient->SetTimeout(mTimeout);
}

string CLASS::GetLibraryVersion()
{
    return LIBRETS_VERSION;
}

UpdateRequestAPtr CLASS::CreateUpdateRequest(string resourceName,
                                             string className)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    std::auto_ptr<UpdateRequest> updateRequest(
        new UpdateRequest(resourceName, className));
    return updateRequest;
}

UpdateResponseAPtr CLASS::Update(UpdateRequest * request)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    string updateUrl = mCapabilityUrls->GetUpdateUrl();
    request->SetUrl(updateUrl);
    request->SetMethod(RetsHttpRequest::POST);
    request->ConstructRequest();
    /*
     * Start the transaction.
     */
    RetsHttpResponsePtr httpResponse = DoRequest(request);

    AssertSuccessfulResponse(httpResponse, updateUrl);

    UpdateResponseAPtr result(new UpdateResponse());
    result->SetEncoding(GetEncoding(httpResponse, mEncoding));
    result->SetInputStream(httpResponse->GetInputStream());

    return result;
}

PayloadListResultSetAPtr CLASS::GetPayloadList(std::string metadataID)
{
    if (!mLoggedIn)
        throw RetsException("You are not logged in");

    PayloadListResultSetAPtr payloadListResultSet;
    string payloadListUrl = mCapabilityUrls->GetPayloadListUrl();
    if (payloadListUrl == "")
    {
        return payloadListResultSet;
    }

    RetsHttpRequest request;
    request.SetUrl(payloadListUrl);
    if (!metadataID.empty())
    {
        request.SetQueryParameter("ID", metadataID);
    }
    RetsHttpResponsePtr httpResponse(DoRequest(&request));

    AssertSuccessfulResponse(httpResponse, payloadListUrl);

    payloadListResultSet.reset(new PayloadListResultSet());
    payloadListResultSet->SetEncoding(GetEncoding(httpResponse, mEncoding));
    payloadListResultSet->Parse(httpResponse->GetInputStream());
    return payloadListResultSet;
}

max_stars_repo_name: SMG-Digital/libRETS

max_issues_repo_name: SMG-Digital/libRETS

max_forks_repo_name: SMG-Digital/libRETS


text:
#include "http/http.h"
#include <boost/foreach.hpp>
#include "error/error.h"
#include "log/log_sysl.h"
#include "iostream"

using namespace pylon ;
using namespace pylon::http ;
using namespace std;
using namespace boost ;

struct socket_stub
{
    socket_stub():_call_times(0) {}
    uint read(char* buf, size_t len )
    {
        static char* block[] = {" GET /test/hi-there.txt HTTP/1.1\r\nAccept: text/*\r\nHost:www.36.cn \r\n\r\n" };
        char* data = block[_call_times];
        strncpy(buf,data,len);
        ++ _call_times ;
        return strlen(data);
    }
    void reset()
    {
        _call_times =0 ;
    }
    uint  _call_times;
};
int main(void )
{

    parser  p;
    socket_stub socket;
    int max = 1000000;
    for (int i=0 ; i< max ; ++i)
    {
        socket.reset();
        request requ;
        buffer_t head_buf= requ.alloc_buffer();
        size_t   read_len   = socket.read(head_buf.unused_begin(), head_buf.unused_size());
        head_buf.mark_used (read_len);
        result_t hr   = p.parse_header(head_buf,requ);
        if(hr.is_end() )
        {
            if (i == 0)
            {
                cout << requ << endl;
            }
            if (i%10000 == 0) cerr << "." ;
        }
    }
    return 0;
}

max_stars_repo_name: xcodecraft/youbar

max_issues_repo_name: xcodecraft/youbar

max_forks_repo_name: xcodecraft/youbar


text:
//  Copyright (c) 2006-2009, Bernhard Reiter
//
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

/**
 * @file coupling_cursor.hpp
 * Coupling cursor implementation
 */

#ifndef BOOST_TREE_COUPLING_CURSOR_HPP
#define BOOST_TREE_COUPLING_CURSOR_HPP

#include <boost/tree/cursor_adaptor.hpp>

namespace boost {
namespace tree {

using boost::iterator_core_access;

/** \addtogroup cursor_adaptors
 *  \@{ */

template <class InCursor, class OutCursor>
class coupling_cursor;

/**
 * @brief Output cursor wrapper around an output iterator.
 *
 * This can be very useful e.g. to have cursor algorithms actually work on
 * iterators, thus permitting some kind of linearization of a given subtree.
 * (Modelled after std::insert_iterator and the like.)
 *
 * For construction, the outputter_cursor_iterator_wrapper might come in useful
 * in saving keystrokes.
 */
// TODO: Complete this.
// Shouldn't we be using cursor_facade?
template <class InCursor, class OutCursor>
class coupling_cursor
: public cursor_adaptor<coupling_cursor<InCursor, OutCursor>
                      , InCursor
//                      , boost::use_default
//                      , boost::use_default
//                      , boost::use_default
    >
 {
protected:
    mutable OutCursor m_out;
public:
    /**
     * For construction, we obviously need a tree and a cursor to work on (i.e., write to).
     */
    explicit coupling_cursor(InCursor i, OutCursor o)
    : coupling_cursor::cursor_adaptor_(i), m_out(o) {}

    // Cursor-specific
    typedef coupling_cursor<InCursor, OutCursor> cursor;
    typedef coupling_cursor<typename InCursor::const_cursor, OutCursor> const_cursor;

//    operator InCursor() {
//        return this->base_reference();
//    }
//

// if InCursor != OutCursor
//    operator OutCursor() {
//        return m_out;
//    }

    InCursor& in()
    {
        return this->base_reference();
    }

    OutCursor& out()
    {
        return m_out;
    }

    bool is_root() const
    {
        return this->base_reference().is_root();
    }

private:
    friend class boost::iterator_core_access;
    friend class boost::tree::cursor_core_access;

    void increment()
    {
        ++this->base_reference();
        ++m_out;
    }

    void decrement()
    {
        --this->base_reference();
        --m_out;
    }

    void left()
    {
        this->base_reference().to_begin();
        m_out.to_begin();
    }

    void right()
    {
        this->base_reference().to_end();
        m_out.to_end();
    }

    void up()
    {
        this->base_reference().to_parent();
        m_out.to_parent();
    }
};

template <class InCursor, class OutCursor>
typename coupling_cursor<InCursor, OutCursor>::size_type
index(coupling_cursor<InCursor, OutCursor> const& cur)
{
    return cur.index();
}

/**
 * @param o    An output iterator.
 * @result    An instance of coupling_cursor working on o.
 *
 * Use as shortcut for cumbersome typenames, just as with std::inserter and the like.
 */
template <class InCursor, class OutCursor>
inline coupling_cursor<InCursor, OutCursor>
make_coupling_cursor(InCursor i, OutCursor o)
{
    return coupling_cursor<InCursor, OutCursor>(i, o);
}

} // namespace tree
} // namespace boost

/** @} */

#endif // BOOST_TREE_COUPLING_CURSOR_HPP

ext: hpp

max_stars_repo_name: grafikrobot/tree

max_issues_repo_name: grafikrobot/tree

max_forks_repo_name: grafikrobot/tree


text:
#include <cstdlib>
#include <fstream>
#include <sstream>

#include <glog/logging.h>

#include <cv_bridge/cv_bridge.h>
#include <tf2_eigen/tf2_eigen.h>
#include <Eigen/Geometry>

#include "asa_ros/asa_ros_node.h"

namespace asa_ros {

AsaRosNode::AsaRosNode(const ros::NodeHandle& nh,
                       const ros::NodeHandle& nh_private)
    : nh_(nh),
      nh_private_(nh_private),
      tf_buffer_(ros::Duration(120.0)),
      tf_listener_(tf_buffer_),
      world_frame_id_("world"),
      camera_frame_id_(""),
      anchor_frame_id_(""),
      broadcast_anchor_tf_(true),
      tf_lookup_timeout_(0.1),
      prev_frame_timestamp_() {
  initFromRosParams();
}

AsaRosNode::~AsaRosNode() {}

void AsaRosNode::initFromRosParams() {

  nh_private_.param("subscriber_queue_size", queue_size_, 1);
  nh_private_.param("use_approx_sync_policy", use_approx_sync_policy_, false);
  nh_private_.param("activate_interface_level_logging",
                    activate_interface_level_logging_,
                    false);
  nh_private_.param("query_last_anchor_id_from_cache",
                    query_last_anchor_id_from_cache_,
                    false);

  // Set anchor id cache path
  std::string last_anchor_cache_path_default;
  // $HOME should be defined, but if not, put it in /tmp
  const char *home_path = getenv("HOME");
  if(home_path) {
    last_anchor_cache_path_default = std::string(home_path) +
                                     "/.ros/last_anchor_id";
  }
  else {
    last_anchor_cache_path_default = "/tmp/last_anchor_id";
  }
  nh_private_.param<std::string>("last_anchor_cache_path",
                                 last_anchor_cache_path_,
                                 last_anchor_cache_path_default);

  if(use_approx_sync_policy_) {
    ROS_INFO_STREAM("Starting image and info subscribers with approximate " <<
                    "time sync, where queue size is " << queue_size_);
  }

  // Subscribe to the camera images.
  image_sub_.subscribe(nh_, "image", queue_size_);
  info_sub_.subscribe(nh_, "camera_info", queue_size_);

  if(use_approx_sync_policy_) {
    image_info_approx_sync_.reset(new message_filters::Synchronizer<CameraSyncPolicy>(CameraSyncPolicy(queue_size_), image_sub_, info_sub_));
    image_info_approx_sync_->registerCallback(boost::bind(&AsaRosNode::imageAndInfoCallback, this, _1, _2));
  } else {
    image_info_sync_.reset(
        new message_filters::TimeSynchronizer<sensor_msgs::Image,
                                              sensor_msgs::CameraInfo>(image_sub_, info_sub_, 10));
    image_info_sync_->registerCallback(
        boost::bind(&AsaRosNode::imageAndInfoCallback, this, _1, _2));
  }

  // Subscribe to transform topics, if any.
  transform_sub_ =
      nh_.subscribe("transform", 1, &AsaRosNode::transformCallback, this);

  // Publishers.
  found_anchor_pub_ =
      nh_private_.advertise<asa_ros_msgs::FoundAnchor>("found_anchor", 1, true);
  created_anchor_pub_ = nh_private_.advertise<asa_ros_msgs::CreatedAnchor>(
      "created_anchor", 1, true);
  feedback_pub_ = nh_private_.advertise<asa_ros_msgs::CreateAnchorFeedback>(
      "create_anchor_feedback", 1, true);

  // Services.
  create_anchor_srv_ = nh_private_.advertiseService(
      "create_anchor", &AsaRosNode::createAnchorCallback, this);
  find_anchor_srv_ = nh_private_.advertiseService(
      "find_anchor", &AsaRosNode::findAnchorCallback, this);
  reset_srv_ =
      nh_private_.advertiseService("reset", &AsaRosNode::resetCallback, this);
  reset_completely_srv_ = nh_private_.advertiseService(
      "reset_completely", &AsaRosNode::resetCompletelyCallback, this);

  // Transform settings.
  nh_private_.param("world_frame_id", world_frame_id_, world_frame_id_);
  nh_private_.param("camera_frame_id", camera_frame_id_, camera_frame_id_);
  nh_private_.param("anchor_frame_id", anchor_frame_id_, anchor_frame_id_);
  nh_private_.param("broadcast_anchor_tf", broadcast_anchor_tf_, broadcast_anchor_tf_);
  nh_private_.param("tf_lookup_timeout", tf_lookup_timeout_,
                    tf_lookup_timeout_);

  // Load ASA config and set it up.
  AsaRosConfig asa_config;

  // Set a small queue size to save RAMs.
  asa_config.max_queue_size = 50;

  // Set up the account IDs.
  nh_private_.param("account_id", asa_config.account_id, asa_config.account_id);
  nh_private_.param("account_key", asa_config.account_key,
                    asa_config.account_key);
  nh_private_.param("account_domain", asa_config.account_domain,
                    asa_config.account_domain);

  ROS_INFO_STREAM("Account domain: " << asa_config.account_domain
                                     << " account ID: " << asa_config.account_id
                                     << " account key: "
                                     << asa_config.account_key);

  interface_.reset(new AzureSpatialAnchorsInterface(asa_config));
  interface_->setCreateAnchorFeedbackCallback(
    std::bind(&AsaRosNode::createAnchorFeedbackCallback, this,
              std::placeholders::_1, std::placeholders::_2,
              std::placeholders::_3));
  if(activate_interface_level_logging_){
    interface_->ActivateInterfaceLevelLogging();
  }
  interface_->start();

  std::string anchor_id;
  nh_private_.param("anchor_id", anchor_id, anchor_id);
  if (!anchor_id.empty()) {
    // Start looking for an anchor immediately if one is given as a param.
    interface_->queryAnchorWithCallback(
        anchor_id, std::bind(&AsaRosNode::anchorFoundCallback, this,
                             std::placeholders::_1, std::placeholders::_2));
  }
  else if(query_last_anchor_id_from_cache_) {
    // Or look for the last created anchor if this flag is set
    const std::string cached_anchor_id = readCachedAnchorId();
    ROS_INFO_STREAM("Querying cached anchor id: " << cached_anchor_id);
    interface_->queryAnchorWithCallback(
        cached_anchor_id, std::bind(&AsaRosNode::anchorFoundCallback, this,
                             std::placeholders::_1, std::placeholders::_2));
  }
}

// Returns true if the camera intrinsics seem to be valid. Does not validate correctness
bool ValidateCameraIntrinsics(const boost::array<double, 9> K, int image_height, int image_width){
  return K.at(0) > 0 && K.at(4) > 0 && K.at(2) >= 0 && K.at(5) >= 0 && image_height > 0 && image_width > 0;
}

void AsaRosNode::imageAndInfoCallback(
    const sensor_msgs::Image::ConstPtr& image,
    const sensor_msgs::CameraInfo::ConstPtr& camera_info) {

  if (camera_frame_id_.empty()) {
    camera_frame_id_ = image->header.frame_id;
    ROS_INFO_STREAM("Set camera frame ID to " << camera_frame_id_);
  }

  if(!ValidateCameraIntrinsics(camera_info->K, image->height, image->width)){
    ROS_WARN_ONCE("The camera_info topic reported invalid values. The anchor creation will fail. Check the camera configuration.");
  }

  // Look up its pose.
  if (tf_buffer_.canTransform(world_frame_id_, camera_frame_id_,
                              image->header.stamp,
                              ros::Duration(tf_lookup_timeout_))) {
    geometry_msgs::TransformStamped transform = tf_buffer_.lookupTransform(
        world_frame_id_, camera_frame_id_, image->header.stamp);

    // Finally and only in this case can we actually add the frame.
    interface_->addFrame(*image, *camera_info, transform);
    prev_frame_timestamp_ = image->header.stamp;
    ROS_INFO_ONCE("Added first frame.");
  } else {
    ROS_WARN_STREAM("Couldn't look up transform from "
                    << world_frame_id_ << " to " << camera_frame_id_
                    << " at timestamp " << image->header.stamp
                    << " and ros::Time::now() " << ros::Time::now());
  }
}

void AsaRosNode::transformCallback(const geometry_msgs::TransformStamped& msg) {
  const std::string kDefaultAuthority = "default_authority";
  const bool kIsStatic = false;

  geometry_msgs::TransformStamped tf_copy = msg;
  tf_copy.header.frame_id = world_frame_id_;
  tf_copy.child_frame_id = camera_frame_id_;
  tf_buffer_.setTransform(tf_copy, kDefaultAuthority, kIsStatic);
}

void AsaRosNode::anchorFoundCallback(
    const std::string& anchor_id,
    const Eigen::Affine3d& anchor_in_world_frame) {
  ROS_INFO_STREAM("Found anchor: " << anchor_id << "\n"
                                   << anchor_in_world_frame.matrix());
  // Here we will just publish a TF frame.
  geometry_msgs::TransformStamped T_W_A_msg =
      tf2::eigenToTransform(anchor_in_world_frame);
  T_W_A_msg.header.frame_id = world_frame_id_;
  T_W_A_msg.header.stamp = ros::Time::now();
  T_W_A_msg.child_frame_id = anchor_frame_id_;
  // If anchor frame ID is empty, just publish the anchor ID.
  if (anchor_frame_id_.empty()) {
    T_W_A_msg.child_frame_id = anchor_id;
  }

  if (broadcast_anchor_tf_) {
    tf_broadcaster_.sendTransform(T_W_A_msg);
  }

  // Also publish this as a topic.
  asa_ros_msgs::FoundAnchor anchor_msg;
  anchor_msg.anchor_id = anchor_id;
  anchor_msg.anchor_in_world_frame = T_W_A_msg;

  found_anchor_pub_.publish(anchor_msg);
}

bool AsaRosNode::createAnchorCallback(asa_ros_msgs::CreateAnchorRequest& req,
                                      asa_ros_msgs::CreateAnchorResponse& res) {
  Eigen::Affine3d anchor_in_target_frame;
  anchor_in_target_frame = tf2::transformToEigen(req.anchor_in_target_frame);

  // Compute anchor in world frame if pose given relative to target frame
  Eigen::Affine3d anchor_in_world_frame;
  if(req.target_frame.empty()) {
    anchor_in_world_frame = anchor_in_target_frame;
  }
  else {
    if (prev_frame_timestamp_ == ros::Time(0))
    {
      ROS_WARN_STREAM("Failed to create anchor: no frames have been added.");
      return false;
    }
    if (tf_buffer_.canTransform(world_frame_id_,
                                req.target_frame,
                                prev_frame_timestamp_,
                                ros::Duration(tf_lookup_timeout_))) {

      geometry_msgs::TransformStamped target_in_world_frame_tf =
          tf_buffer_.lookupTransform(world_frame_id_,
                                     req.target_frame,
                                     prev_frame_timestamp_,
                                     ros::Duration(tf_lookup_timeout_));
      anchor_in_world_frame = tf2::transformToEigen(target_in_world_frame_tf) *
                                  anchor_in_target_frame;
    }
    else {
      ROS_WARN_STREAM("Failed to find target frame in TF tree. " <<
                       "Anchor not created.");
      return false;
    }
  }

  bool success = interface_->createAnchorWithCallback(
      anchor_in_world_frame,
      std::bind(&AsaRosNode::anchorCreatedCallback, this, std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3));
  // If there is not enough "spatial data" (different perspectives on the
  // scene), then anchor creation will fail immediately. This can be fixed by
  // getting more viewpoints.
  // However, this returns true because it's not possible to pass an error
  // message back to the process calling the service, so we just print an
  // error if the create anchor call fails.
  return true;
}

bool AsaRosNode::findAnchorCallback(asa_ros_msgs::FindAnchorRequest& req,
                                    asa_ros_msgs::FindAnchorResponse& res) {
  queryAnchors(req.anchor_id);
  return true;
}

void AsaRosNode::anchorCreatedCallback(bool success,
                                       const std::string& anchor_id,
                                       const std::string& reason) {
  asa_ros_msgs::CreatedAnchor anchor_msg;
  anchor_msg.success = success;
  anchor_msg.anchor_id = anchor_id;
  anchor_msg.failure_reason = reason;

  if (success) {
    ROS_INFO_STREAM("Successfully created an anchor with ID: " << anchor_id);
  } else {
    ROS_WARN_STREAM("Unable to create anchor. Reason: " << reason);
  }
  created_anchor_pub_.publish(anchor_msg);
  if(storeAnchorIdInCache(anchor_id)) {
    ROS_INFO_STREAM("Stored anchor id in cache.");
  }
}

bool AsaRosNode::queryAnchors(const std::string& anchor_ids) {
  anchor_ids_ = anchor_ids;
  if (interface_->queryAnchorWithCallback(
          anchor_ids,
          std::bind(&AsaRosNode::anchorFoundCallback, this,
                    std::placeholders::_1, std::placeholders::_2))) {
    // Only update anchor ID list if it's valid.
    anchor_ids_ = anchor_ids;
    return true;
  }
  return false;
}

void AsaRosNode::createAnchorFeedbackCallback(
    const float ready_for_create_progress,
    const float recommended_for_create_progress,
    const std::string& user_feedback) {

  if(feedback_pub_.getNumSubscribers() > 0) {
    asa_ros_msgs::CreateAnchorFeedback msg;
    msg.ready_for_create_progress = ready_for_create_progress;
    msg.recommended_for_create_progress = recommended_for_create_progress;
    msg.user_feedback = user_feedback;
    feedback_pub_.publish(msg);
  }
}

void AsaRosNode::createAnchorTimerCallback(const ros::TimerEvent& e) {
  std::string id;
  Eigen::Affine3d anchor_in_world_frame = Eigen::Affine3d::Identity();
  interface_->createAnchor(anchor_in_world_frame, &id);
  ROS_INFO_STREAM("Created an anchor with ID: " << id);
}

std::string AsaRosNode::readCachedAnchorId() {
  std::string cached_anchor_id;

  // Try to read cache file
  std::ifstream cache_file(last_anchor_cache_path_.c_str());
  if(cache_file) {
    std::ostringstream string_stream;
    string_stream << cache_file.rdbuf();
    cached_anchor_id = string_stream.str();
    ROS_INFO_STREAM("Read anchor id: " << cached_anchor_id << " from cache");
  }
  else {
    ROS_ERROR_STREAM("Could not read from anchor id cache file: " <<
                      last_anchor_cache_path_);
  }

  return cached_anchor_id;
}

bool AsaRosNode::storeAnchorIdInCache(const std::string& created_anchor_id) {
  std::ofstream cache_file(last_anchor_cache_path_.c_str());
  if(cache_file) {
    cache_file << created_anchor_id;
    cache_file.close();
    return true;
  }
  else {
    ROS_ERROR_STREAM("Could not open anchor cache file for writing: " <<
                     last_anchor_cache_path_);
    return false;
  }
}

// Does a "soft" reset: continues to try to find any anchors that are
// currently being tracked.
bool AsaRosNode::resetCallback(std_srvs::EmptyRequest& req,
                               std_srvs::EmptyResponse& res) {
  interface_->reset();
  // Also re-query last set of anchors.
  queryAnchors(anchor_ids_);
  return true;
}

// Does a "hard" reset: stops tracking any anchors, wipes any session
// information.
bool AsaRosNode::resetCompletelyCallback(std_srvs::EmptyRequest& req,
                                         std_srvs::EmptyResponse& res) {
  interface_->reset();
  return true;
}

}  // namespace asa_ros

int main(int argc, char** argv) {
  google::InitGoogleLogging(argv[0]);
  google::InstallFailureSignalHandler();
  FLAGS_logtostderr = 1;

  ros::init(argc, argv, "asa_ros");

  ros::NodeHandle nh("");
  ros::NodeHandle nh_private("~");

  asa_ros::AsaRosNode node(nh, nh_private);
  ROS_INFO("[Azure Spatial Anchors ROS] Now running.");

  ros::spin();
  return 0;
}


text:
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/flat_tree.hpp>
#include <boost/container/small_vector.hpp>
#include <boost/container/stable_vector.hpp>
#include <boost/container/static_vector.hpp>

#include <iostream>

#include "movable_int.hpp"
#include "dummy_test_allocator.hpp"

using namespace boost::container;

typedef boost::container::dtl::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> pair_t;

namespace boost {
namespace container {

//Explicit instantiation to detect compilation errors

namespace dtl {

template class flat_tree
   < pair_t
   , select1st<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , test::simple_allocator<pair_t>
   >;

template class flat_tree
   < pair_t
   , select1st<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , std::allocator<pair_t>
   >;

template class flat_tree
   < pair_t
   , select1st<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , small_vector<pair_t, 10>
   >;

template class flat_tree
   < pair_t
   , select1st<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , stable_vector<pair_t>
   >;

template class flat_tree
   < test::movable_and_copyable_int
   , identity<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , test::simple_allocator<test::movable_and_copyable_int>
   >;

template class flat_tree
   < test::movable_and_copyable_int
   , identity<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , std::allocator<test::movable_and_copyable_int>
   >;

template class flat_tree
   < test::movable_and_copyable_int
   , identity<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , small_vector<test::movable_and_copyable_int, 10>
   >;

template class flat_tree
   < test::movable_and_copyable_int
   , identity<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , stable_vector<test::movable_and_copyable_int>
   >;

template class flat_tree
< test::movable_and_copyable_int
   , identity<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , static_vector<test::movable_and_copyable_int, 10>
>;

}  //dtl {
}} //boost::container

#if (__cplusplus > 201103L)
#include <vector>

namespace boost{
namespace container{
namespace dtl{

template class flat_tree
< test::movable_and_copyable_int
   , identity<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , std::vector<test::movable_and_copyable_int>
>;

template class flat_tree
< pair_t
   , select1st<test::movable_and_copyable_int>
   , std::less<test::movable_and_copyable_int>
   , std::vector<pair_t>
>;

}  //dtl {
}} //boost::container

#endif

int main ()
{
   ////////////////////////////////////
   //    has_trivial_destructor_after_move testing
   ////////////////////////////////////
   // default
   {
      typedef boost::container::dtl::flat_tree<int, boost::container::dtl::identity<int>,
              std::less<int>, void> tree;
      typedef tree::container_type container_type;
      typedef tree::key_compare key_compare;
      if (boost::has_trivial_destructor_after_move<tree>::value !=
          boost::has_trivial_destructor_after_move<container_type>::value &&
          boost::has_trivial_destructor_after_move<key_compare>::value) {
         std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
         return 1;
      }
   }
   // std::allocator
   {
      typedef boost::container::dtl::flat_tree<int, boost::container::dtl::identity<int>,
              std::less<int>, std::allocator<int> > tree;
      typedef tree::container_type container_type;
      typedef tree::key_compare key_compare;
      if (boost::has_trivial_destructor_after_move<tree>::value !=
          boost::has_trivial_destructor_after_move<container_type>::value &&
          boost::has_trivial_destructor_after_move<key_compare>::value) {
         std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
         return 1;
      }
   }

   return 0;
}


text:
#define BOOST_TEST_MODULE srook_constant_sequence_unit_test
#include <boost/test/included/unit_test.hpp>
#include <algorithm>
#include <srook/config/attribute/maybe_unused.hpp>
#include <srook/mpl/constant_sequence/algorithm.hpp>
// #include <srook/mpl/constant_sequence/equ_sequence.hpp> // [[deprecated]]
#include <srook/mpl/constant_sequence/interval_sequence.hpp>
#include <srook/mpl/constant_sequence/iterator/distance.hpp>
#include <srook/mpl/constant_sequence/iterator/index_sequence_iterator.hpp>
#include <srook/mpl/constant_sequence/iterator/make_index_sequence_iterator_range.hpp>
// #include <srook/mpl/constant_sequence/samevalue_sequence.hpp> // [[deprecated]]
#include <vector>

#define INDEX_SEQUENCE(...) std::index_sequence<__VA_ARGS__>
template <class L, class R>
constexpr void static_type_test()
{
    static_assert(std::is_same_v<L, R>);
}

template <std::size_t v>
using pred = std::integral_constant<bool, (v % 2 == 0)>;

template <std::size_t v>
using function = std::integral_constant<std::size_t, (v * 2)>;

BOOST_AUTO_TEST_CASE(test_op_reportings)
{
    // generating sequence
    using geometric_progression = srook::make_interval_sequence<srook::plus, 10, 10, 5>;
    static_type_test<geometric_progression, INDEX_SEQUENCE(10, 20, 30, 40, 50)>();

    using no_geometric_progression = srook::constant_sequence::insert_t<std::index_sequence<40, 40, 40>, geometric_progression::size() / 2, geometric_progression>;
    static_type_test<no_geometric_progression, INDEX_SEQUENCE(10, 20, 40, 40, 40, 30, 40, 50)>();

    // using samevalue_sequence = srook::constant_sequence::make_samevalue_sequence<4, 42>; // [[deprecated]]
    // static_type_test<samevalue_sequence, INDEX_SEQUENCE(42, 42, 42, 42)>();

    // using equ_sequence = srook::constant_sequence::make_equ_sequence<5>; // [[deprecated]]
    // static_type_test<equ_sequence, INDEX_SEQUENCE(0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5)>();

    // constant sequence iterator
    using constant_sequence_iterator =
	srook::index_sequence_iterator::index_sequence_iterator<geometric_progression>;
    BOOST_TEST((constant_sequence_iterator::value == 10));

    using one_increment = srook::index_sequence_iterator::increment<constant_sequence_iterator>;
    BOOST_TEST((one_increment::value == 20));

    using one_decrement = srook::index_sequence_iterator::decrement<one_increment>;
    BOOST_TEST((one_decrement::value == 10));

    static_type_test<
	srook::constant_sequence::iter_swap_L<
	    srook::index_sequence_iterator::increment<one_increment>,
	    srook::index_sequence_iterator::increment<constant_sequence_iterator>>,
	INDEX_SEQUENCE(10, 20, 20, 40, 50)>();

    constexpr std::size_t distance_result =
	srook::index_sequence_iterator::distance_v<one_increment, srook::index_sequence_iterator::increment<one_increment>>;
    BOOST_TEST((distance_result == 1));

    using make_index_sequence_iterator_range_result =
	srook::index_sequence_iterator::make_index_sequence_iterator_range_t<
	    one_increment,
	    srook::index_sequence_iterator::increment<one_increment>>;
    static_type_test<make_index_sequence_iterator_range_result, INDEX_SEQUENCE(20, 30)>();

    // algorithms
    constexpr std::size_t at_result = srook::constant_sequence::at_v<2, geometric_progression>;
    BOOST_TEST((at_result == 30));

    constexpr bool binary_search_result1 = srook::constant_sequence::binary_search_v<30, geometric_progression>;
    constexpr bool binary_search_result2 = srook::constant_sequence::binary_search_v<42, geometric_progression>;
    BOOST_TEST((binary_search_result1 and !binary_search_result2));

    using concat_result = srook::constant_sequence::concat_t<geometric_progression, std::index_sequence<42, 42>>;
    static_type_test<concat_result, INDEX_SEQUENCE(10, 20, 30, 40, 50, 42, 42)>();

    constexpr std::size_t count_result = srook::constant_sequence::count_v<40, no_geometric_progression>;
    BOOST_TEST((4 == count_result));

    constexpr std::size_t count_if_result = srook::constant_sequence::count_if_v<pred, std::make_index_sequence<10>>;
    BOOST_TEST((5 == count_if_result));

    using no_geometric_progression2 = no_geometric_progression;
    constexpr bool equal_result1 = srook::constant_sequence::equal_v<no_geometric_progression, no_geometric_progression2>;
    constexpr bool equal_result2 = srook::constant_sequence::equal_v<no_geometric_progression, std::index_sequence<1>>;
    BOOST_TEST((equal_result1 and !equal_result2));

    constexpr auto equal_range_result = std::move(srook::constant_sequence::equal_range_v<40, no_geometric_progression>);
    BOOST_TEST((equal_range_result.first == 2 and equal_range_result.second == 7));

    using erase_result = srook::constant_sequence::erase_t<40, no_geometric_progression>;
    static_type_test<erase_result, INDEX_SEQUENCE(10, 20, 40, 40, 30, 40, 50)>();

    using erase_all_result = srook::constant_sequence::erase_all_t<40, no_geometric_progression>;
    static_type_test<erase_all_result, INDEX_SEQUENCE(10, 20, 30, 50)>();

    using erase_duplicate_result = srook::constant_sequence::erase_duplicate_t<no_geometric_progression>;
    static_type_test<erase_duplicate_result, INDEX_SEQUENCE(10, 20, 40, 30, 50)>();

    using erase_if_result = srook::constant_sequence::erase_if_t<pred, std::make_index_sequence<10>>;
    static_type_test<erase_if_result, INDEX_SEQUENCE(0, 2, 4, 6, 8)>();

    using erase_index_result = srook::constant_sequence::erase_index_t<INDEX_SEQUENCE(10, 20), INDEX_SEQUENCE(10, 20, 30, 40)>;
    static_type_test<erase_index_result, INDEX_SEQUENCE(30, 40)>();

    using erase_n_result = srook::constant_sequence::erase_n_t<3, geometric_progression>;
    static_type_test<erase_n_result, INDEX_SEQUENCE(10, 20, 30, 50)>();

    using filter_result = srook::constant_sequence::filter_t<pred, std::make_index_sequence<10>>;
    static_type_test<filter_result, INDEX_SEQUENCE(0, 2, 4, 6, 8)>();

    constexpr int find_result = srook::constant_sequence::find_v<30, geometric_progression>;
    BOOST_TEST((find_result == 2));

    constexpr int find_end_result = srook::constant_sequence::find_end_v<INDEX_SEQUENCE(5, 6), INDEX_SEQUENCE(1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 9)>;
    BOOST_TEST((find_end_result == 8));

    SROOK_ATTRIBUTE_UNUSED constexpr int find_if_result1 = srook::constant_sequence::find_if_v<pred, INDEX_SEQUENCE(1, 1, 1, 1, 1, 2, 1)>;
    // constexpr int find_if_result2 = srook::constant_sequence::find_if_v<pred, srook::constant_sequence::make_samevalue_sequence<4, 1>>; // [[deprecated]]
    // BOOST_TEST((find_if_result1 == 5 and find_if_result2 == -1));

    constexpr int find_if_not_result1 = srook::constant_sequence::find_if_not_v<pred, INDEX_SEQUENCE(2, 2, 2, 2, 1)>;
    constexpr int find_if_not_result2 = srook::constant_sequence::find_if_not_v<pred, geometric_progression>;
    BOOST_TEST((find_if_not_result1 == 4 and find_if_not_result2 == -1));

    using find_index_result = srook::constant_sequence::find_index_t<2, INDEX_SEQUENCE(1, 2, 2, 2, 3, 4)>;
    static_type_test<find_index_result, INDEX_SEQUENCE(1, 2, 3)>();

    using find_if_index_result = srook::constant_sequence::find_if_index_t<pred, INDEX_SEQUENCE(1, 2, 3, 4, 5)>;
    static_type_test<find_if_index_result, INDEX_SEQUENCE(1, 3)>();

    constexpr std::size_t first_result = srook::constant_sequence::first_v<geometric_progression>;
    BOOST_TEST((first_result == 10));

    using for_each_result = srook::constant_sequence::for_each_t<function, geometric_progression>;
    static_type_test<for_each_result, INDEX_SEQUENCE(20, 40, 60, 80, 100)>();

    constexpr bool includes_result1 = srook::constant_sequence::includes_v<geometric_progression, INDEX_SEQUENCE(20, 30, 40)>;
    constexpr bool includes_result2 = srook::constant_sequence::includes_v<geometric_progression, std::make_index_sequence<3>>;
    BOOST_TEST((includes_result1 and !includes_result2));

    using inplace_merge_result = srook::constant_sequence::inplace_merge_t<geometric_progression, INDEX_SEQUENCE(1, 2, 3, 10, 20)>;
    static_type_test<inplace_merge_result, INDEX_SEQUENCE(1, 2, 3, 10, 10, 20, 20, 30, 40, 50)>();

    constexpr bool is_all_less_result = srook::constant_sequence::is_all_less_v<INDEX_SEQUENCE(1, 2), INDEX_SEQUENCE(10, 20)>;
    constexpr bool is_all_greater_result = srook::constant_sequence::is_all_greater_v<INDEX_SEQUENCE(10, 20), INDEX_SEQUENCE(1, 2)>;
    BOOST_TEST((is_all_less_result and is_all_greater_result));

    constexpr bool is_heap_result1 = srook::constant_sequence::is_heap_v<INDEX_SEQUENCE(100, 19, 36, 17, 3, 25, 1, 2, 7)>;
    constexpr bool is_heap_result2 = srook::constant_sequence::is_heap_v<INDEX_SEQUENCE(1, 2, 3, 17, 19, 36, 7, 25, 100), srook::constant_sequence::less>;
    BOOST_TEST((is_heap_result1 and is_heap_result2));

    constexpr bool is_partitioned_result1 = srook::constant_sequence::is_partitioned_v<pred, INDEX_SEQUENCE(1, 3, 5, 7, 9, 2, 4, 6)>;
    constexpr bool is_partitioned_result2 = srook::constant_sequence::is_partitioned_v<pred, INDEX_SEQUENCE(1, 2, 3)>;
    BOOST_TEST((is_partitioned_result1 and !is_partitioned_result2));

    constexpr bool is_permutation_result = srook::constant_sequence::is_permutation_v<INDEX_SEQUENCE(10, 20, 30), INDEX_SEQUENCE(20, 10, 30)>;
    BOOST_TEST((is_permutation_result));

    constexpr int search_result = srook::constant_sequence::search_v<INDEX_SEQUENCE(40, 50), geometric_progression>;
    BOOST_TEST((search_result == 3));

    constexpr int search_n_result = srook::constant_sequence::search_n_v<INDEX_SEQUENCE(1, 2, 3, 2, 2, 3, 1, 2, 3, 3, 3, 4, 1, 2, 3), 3, 3>;
    BOOST_TEST((search_n_result == 8));

    constexpr bool is_sorted_result1 = srook::constant_sequence::is_sorted_v<geometric_progression>;
    constexpr bool is_sorted_result2 = srook::constant_sequence::is_sorted_v<srook::constant_sequence::reverse_t<geometric_progression>, srook::constant_sequence::greater>;
    BOOST_TEST((is_sorted_result1 and is_sorted_result2));

    constexpr std::size_t is_sorted_until_result1 = srook::constant_sequence::is_sorted_until_v<INDEX_SEQUENCE(2, 3, 4, 1, 5, 6, 7), srook::constant_sequence::less>;
    constexpr std::size_t is_sorted_until_result2 = srook::constant_sequence::is_sorted_until_v<INDEX_SEQUENCE(6, 5, 4, 7), srook::constant_sequence::greater>;
    BOOST_TEST((is_sorted_until_result1 == 3 and is_sorted_until_result2 == 3));

    constexpr std::size_t last_result = srook::constant_sequence::last_v<geometric_progression>;
    BOOST_TEST((last_result == 50));

    constexpr std::size_t length_result = srook::constant_sequence::length_v<geometric_progression>;
    BOOST_TEST((length_result == 5));

    constexpr int lower_bound_result1 = srook::constant_sequence::lower_bound_v<40, no_geometric_progression>;
    constexpr int lower_bound_result2 = srook::constant_sequence::lower_bound_v<100, no_geometric_progression>;
    BOOST_TEST(((lower_bound_result1 == 2) and (lower_bound_result2 == -1)));

    using nth_element_result = srook::constant_sequence::nth_element_t<3, INDEX_SEQUENCE(20, 10, 40, 30, 50)>;
    constexpr std::size_t nth_min_point =
	srook::constant_sequence::find_v<srook::constant_sequence::nth_min_v<3, nth_element_result>, nth_element_result>;
    BOOST_TEST((
	srook::constant_sequence::is_permutation_v<
	    srook::constant_sequence::partial_head_t<nth_min_point + 1, nth_element_result>,
	    INDEX_SEQUENCE(10, 20, 30)> and
	srook::constant_sequence::is_permutation_v<
	    srook::constant_sequence::partial_tail_t<nth_min_point + 1, nth_element_result>,
	    INDEX_SEQUENCE(40, 50)>));

    constexpr std::size_t nth_max_result = srook::constant_sequence::nth_max_v<3, geometric_progression>;
    constexpr std::size_t nth_min_result = srook::constant_sequence::nth_min_v<3, geometric_progression>;
    BOOST_TEST((nth_max_result == 30 and nth_min_result == 30));

    constexpr bool none_of_result = srook::constant_sequence::none_of_v<pred, INDEX_SEQUENCE(1, 3, 5, 7)>;
    BOOST_TEST(none_of_result);

    constexpr std::size_t min_result = srook::constant_sequence::min_v<geometric_progression>;
    BOOST_TEST((min_result == 10));

    constexpr std::size_t max_result = srook::constant_sequence::max_v<geometric_progression>;
    BOOST_TEST((max_result == 50));

    using merge_result = srook::constant_sequence::merge_t<geometric_progression, INDEX_SEQUENCE(30, 40, 50, 70)>;
    static_type_test<merge_result, INDEX_SEQUENCE(10, 20, 30, 30, 40, 40, 50, 50, 70)>();

    constexpr int mismatch_result1 = srook::constant_sequence::mismatch_v<geometric_progression, INDEX_SEQUENCE(10, 20, 30, 60)>;
    constexpr int mismatch_result2 = srook::constant_sequence::mismatch_v<geometric_progression, geometric_progression>;
    BOOST_TEST((mismatch_result1 == 3 and mismatch_result2 == -1));

    using partial_head_result = srook::constant_sequence::partial_head_t<geometric_progression::size() / 2, geometric_progression>;
    static_type_test<partial_head_result, INDEX_SEQUENCE(10, 20)>();

    using partial_tail_result = srook::constant_sequence::partial_tail_t<geometric_progression::size() / 2, geometric_progression>;
    static_type_test<partial_tail_result, INDEX_SEQUENCE(30, 40, 50)>();

    using prev_rotate_result = srook::constant_sequence::prev_rotate_t<geometric_progression>;
    static_type_test<prev_rotate_result, INDEX_SEQUENCE(20, 30, 40, 50, 10)>();

    using pop_back_result = srook::constant_sequence::pop_back_t<geometric_progression>;
    static_type_test<pop_back_result, INDEX_SEQUENCE(10, 20, 30, 40)>();

    using pop_front_result = srook::constant_sequence::pop_front_t<geometric_progression>;
    static_type_test<pop_front_result, INDEX_SEQUENCE(20, 30, 40, 50)>();

    using replace_result = srook::constant_sequence::replace_t<40, 42, no_geometric_progression>;
    static_type_test<replace_result, INDEX_SEQUENCE(10, 20, 42, 40, 40, 30, 40, 50)>();

    using replace_all_result = srook::constant_sequence::replace_all_t<40, 42, no_geometric_progression>;
    static_type_test<replace_all_result, INDEX_SEQUENCE(10, 20, 42, 42, 42, 30, 42, 50)>();

    using reverse_result = srook::constant_sequence::reverse_t<geometric_progression>;
    static_type_test<reverse_result, INDEX_SEQUENCE(50, 40, 30, 20, 10)>();

    using rotate_result = srook::constant_sequence::rotate_t<geometric_progression>;
    static_type_test<rotate_result, INDEX_SEQUENCE(50, 10, 20, 30, 40)>();

    using set_difference_result = srook::constant_sequence::set_difference_t<INDEX_SEQUENCE(1, 2, 3, 4, 5), INDEX_SEQUENCE(1, 2, 5, 6, 7)>;
    static_type_test<set_difference_result, INDEX_SEQUENCE(3, 4, 6, 7)>();

    using set_intersection_result = srook::constant_sequence::set_intersection_t<INDEX_SEQUENCE(1, 2, 3, 4, 5), INDEX_SEQUENCE(1, 2, 5, 6, 7)>;
    static_type_test<set_intersection_result, INDEX_SEQUENCE(1, 2, 5)>();

    constexpr std::size_t size_result = srook::constant_sequence::size<geometric_progression>;
    BOOST_TEST((size_result == srook::constant_sequence::length_v<geometric_progression>));

    using random_sequence = INDEX_SEQUENCE(30, 20, 42, 19, 22, 2, 8, 45, 10);
    using sort_less_result = srook::constant_sequence::sort_t<random_sequence>;
    static_type_test<sort_less_result, INDEX_SEQUENCE(2, 8, 10, 19, 20, 22, 30, 42, 45)>();

    constexpr std::size_t summation_result = srook::constant_sequence::summation_v<geometric_progression>;
    BOOST_TEST((summation_result == 110));

    using swap_L_result = srook::constant_sequence::swap_L<3, geometric_progression, random_sequence>;
    using swap_R_result = srook::constant_sequence::swap_R<3, geometric_progression, random_sequence>;
    static_type_test<swap_L_result, INDEX_SEQUENCE(10, 20, 30, 19, 50)>();
    static_type_test<swap_R_result, INDEX_SEQUENCE(30, 20, 42, 40, 22, 2, 8, 45, 10)>();

    using swap_at_L_result = srook::constant_sequence::swap_at_L<2, geometric_progression, 4, random_sequence>;
    using swap_at_R_result = srook::constant_sequence::swap_at_R<2, geometric_progression, 4, random_sequence>;
    static_type_test<swap_at_L_result, INDEX_SEQUENCE(10, 20, 22, 40, 50)>();
    static_type_test<swap_at_R_result, INDEX_SEQUENCE(30, 20, 42, 19, 30, 2, 8, 45, 10)>();

    // const auto test_range = std::move(srook::constant_sequence::transfer<std::vector, geometric_progression>::value);
    // decltype(test_range) comparison{10, 20, 30, 40, 50};
    // BOOST_TEST(std::equal(test_range.begin(), test_range.end(), comparison.begin()));

    const auto test_array = std::move(srook::constant_sequence::transfer_array<geometric_progression>::value);
    decltype(test_array) comparison_ar{{10, 20, 30, 40, 50}};
    BOOST_TEST(std::equal(test_array.begin(), test_array.end(), comparison_ar.begin()));

    constexpr int upper_bound_result1 = srook::constant_sequence::upper_bound_v<40, no_geometric_progression>;
    constexpr int upper_bound_result2 = srook::constant_sequence::upper_bound_v<100, no_geometric_progression>;
    BOOST_TEST(((upper_bound_result1 == 7) and (upper_bound_result2 == -1)));
}

max_stars_repo_name: falgon/srookCppLibraries

max_issues_repo_name: falgon/srookCppLibraries

max_forks_repo_name: falgon/srookCppLibraries


text:
#include <boost/thread.hpp>
#include <boost/thread.hpp>
#include "caffe/layer.hpp"

namespace caffe {

template <typename Dtype>
void Layer<Dtype>::InitMutex() {
  forward_mutex_.reset(new boost::mutex());
}

template <typename Dtype>
void Layer<Dtype>::Lock() {
  if (IsShared()) {
    forward_mutex_->lock();
  }
}

template <typename Dtype>
void Layer<Dtype>::Unlock() {
  if (IsShared()) {
    forward_mutex_->unlock();
  }
}

/*
 * 聚类的目的是得到各个weight属于的中心以及这个中心的值
 */
template<typename Dtype>
void Layer<Dtype>::kmeans_cluster(vector<int> &cLabel, vector<Dtype> &cCentro, Dtype *cWeights, int nWeights, \
  vector<bool> &mask, int nCluster,  int max_iter){

  Dtype maxWeight = std::numeric_limits<Dtype>::min();
  Dtype minWeight = std::numeric_limits<Dtype>::max();

  //find min max
  for(int k = 0; k < nWeights; ++k){
    if(mask[k]){
      if(cWeights[k] > maxWeight)
        maxWeight = cWeights[k];
      if(cWeights[k] < minWeight)
        minWeight = cWeights[k];
    }
    cLabel[k] = -1; //initialize all label to -1
  }

  // generate initial centroids linearly
  for (int k = 0; k < nCluster; k++)
    cCentro[k] = minWeight + (maxWeight - minWeight) * k / (nCluster - 1);

  Dtype *ptrC = new Dtype[nCluster]; // 用来存各个中心的权重的和，和下面的相除得到各个中心新的值
  int *ptrS = new int[nCluster]; // 用来存各个中心的权重的个数
  int iter = 0;
  double mCurDistance = 0.0;
  double mPreDistance = std::numeric_limits<double>::max();
  Dtype distance, mindistance; // 临时变量，用于存每个weight到中心的距离和最短距离

  // clustering
  while (iter < max_iter)
  {
    // check convergence
    if (fabs(mPreDistance - mCurDistance) / mPreDistance < 0.01)  break;
    mPreDistance = mCurDistance; mCurDistance = 0.0;
    for (int n = 0; n < nWeights; n++){
      if (!mask[n])  continue; // 如果mask为0，则跳过这个值
      mindistance = std::numeric_limits<Dtype>::max();
      for (int k = 0; k < nCluster; k++){
        distance = fabs(cWeights[n] - cCentro[k]);
        if (distance < mindistance){
          mindistance = distance;
          cLabel[n] = k;
        }
      }
      mCurDistance = mCurDistance + mindistance;
    }

    // 更新中心，初始化为0
    for (int k = 0; k < nCluster; k++){
      ptrC[k] = 0.f;
      ptrS[k] = 0;
    }

    for (int n = 0; n < nWeights; n++){
      if (mask[n]){
        ptrC[cLabel[n]] += cWeights[n];
        ptrS[cLabel[n]] += 1;
      }
    }

    for (int k = 0; k < nCluster; k++)
      cCentro[k] = ptrC[k]/ptrS[k]; // 更新中心值

    iter++;
  }
  delete[] ptrC; delete[] ptrS;
}

  INSTANTIATE_CLASS(Layer);

}  // namespace caffe