<commit_before>#include "kernel.h"
#include "raster.h"
#include "gridcoverage.h"
#include "pixeliterator.h"
#include "connectorinterface.h"
#include "symboltable.h"
#include "domainitem.h"
#include "itemdomain.h"
#include "numericitem.h"
#include "numericitemrange.h"
#include "ilwisoperation.h"

quint64 Ilwis::GridBlockInternal::_blockid = 0;

using namespace Ilwis;

GridCoverage::GridCoverage()
{
}

GridCoverage::GridCoverage(const Resource& res) : Coverage(res){

}

GridCoverage::~GridCoverage()
{
}

const IGeoReference& GridCoverage::georeference() const
{
    return _georef;
}

void GridCoverage::georeference(const IGeoReference &grf)
{
    _georef = grf;
    if ( _grid.isNull() == false) { // remove the current grid, all has become uncertain
        _grid.reset(0);

    }
    if ( _georef.isValid()) {
        _georef->compute();
        setCoordinateSystem(grf->coordinateSystem()); // mandatory
    }
}

IlwisTypes GridCoverage::ilwisType() const
{
    return itGRID;
}

GridCoverage *GridCoverage::copy()
{
    GridCoverage *gc = new GridCoverage();
    copyTo(gc);
    return gc;

}

void GridCoverage::copyBinary(const IGridCoverage& gc, int index) {
    IGridCoverage gcNew;
    gcNew.set(this);
    Size inputSize =  gc->size();
    Size sz(inputSize.xsize(),inputSize.ysize(), 1);
    gcNew->georeference()->size(sz);
    PixelIterator iterIn(gc, Box3D<>(Voxel(0,0,index), Voxel(inputSize.xsize(), inputSize.ysize(), index + 1)));
    PixelIterator iterOut(gcNew, Box3D<>(Size(inputSize.xsize(), inputSize.ysize(), 1)));
    for_each(iterOut, iterOut.end(), [&](double& v){
         v = *iterIn;
        ++iterIn;
    });
}

IGridCoverage GridCoverage::get(quint32 index1, quint32 index2)
{
    IGridCoverage gcovParent;
    gcovParent.set(this);
    IGridCoverage gcov = OperationHelperRaster::initialize(gcovParent,itGRID, itDOMAIN | itCOORDSYSTEM | itGEOREF);
    gcov->size(Size(size().xsize(), size().ysize()));
    gcov->_grid.reset(gcov->_grid->clone(index1, index2));

    return gcov;

}

IGridCoverage GridCoverage::get(const QString &item1, const QString &item2)
{
    IDomain indexDomain = datadef().domain(DataDefinition::daINDEX);
    if (!indexDomain.isValid())
        return IGridCoverage();
    if ( indexDomain->valueType() == itNUMERICITEM)  {
        double item1Index = item1.toDouble();
        INumericItemDomain numdom = indexDomain.get<NumericItemDomain>();
        SPNumericItemRange numrange = numdom->range<NumericItemRange>();
        double index1 = numrange->index(item1Index);
        double rest1 = index1 - (int)index1;
        if ( std::abs(rest1) > EPS8 && numrange->isContinous()) {
            int lowerIndex = std::floor(index1);
            double rest2 = 1.0 - rest1;
            QString expr = numrange->interpolation();
            QString nm = name();
            int ind = 0;
            if( (ind=nm.lastIndexOf(".")) != -1){
                nm = nm.left(ind);
            }
            nm = QString("%1_%2_%3").arg(nm).arg(lowerIndex).arg(lowerIndex+1);
            expr = nm + "=" + expr.arg(QString("%1*%2[%3]").arg(rest2).arg(name()).arg(lowerIndex)).arg(QString("%1*%2[%3]").arg(rest1).arg(name()).arg(lowerIndex+1));
            IGridCoverage mp = Operation::execute<IGridCoverage>(expr);
            if ( mp.isValid())
                return mp;
        }
    }
    return IGridCoverage();
}

Grid *GridCoverage::grid()
{
    Locker lock(_mutex);
    if ( _georef->isValid() && !connector().isNull()) {
        if ( _grid.isNull()) {
            _grid.reset(connector()->loadGridData(this));
            if (_grid.isNull())
                return 0;
        }
        Grid *grd = _grid.data();
        return grd;
    }
    return 0;
}

void GridCoverage::copyTo(IlwisObject *obj)
{
    Locker lock(_mutex);
    Coverage::copyTo(obj);
    GridCoverage *gc = static_cast<GridCoverage *>(obj);
    gc->_georef = _georef;
    if ( _grid) {
        gc->_grid.reset(_grid->clone());
    }

}

Resource GridCoverage::resource(int mode) const
{
    Resource res = Coverage::resource(mode);
    if ( mode & IlwisObject::cmEXTENDED) {
        res["georeference()"] = georeference()->id();
        res.setExtendedType( res.extendedType() | itGEOREF);
    }
    return res;
}

Size GridCoverage::size() const
{
    if (_size.isValid() && !_size.isNull())
        return _size;
    if (!_grid.isNull())
        const_cast<GridCoverage *>(this)->_size = _grid->size();
    else if ( _georef.isValid())
        const_cast<GridCoverage *>(this)->_size = _georef->size();

    return _size;

}

void GridCoverage::size(const Size &sz)
{
    // size must always be positive or undefined
    if (sz.xsize() > 0 && sz.ysize() > 0) {
        _size = sz;
        if (!_grid.isNull())
            _grid->setSize(sz);
        if (_georef.isValid())
            _georef->size(sz);
    }

}

<commit_msg>changed the function call to create a map from an expression<commit_after>#include "kernel.h"
#include "raster.h"
#include "gridcoverage.h"
#include "pixeliterator.h"
#include "connectorinterface.h"
#include "symboltable.h"
#include "domainitem.h"
#include "itemdomain.h"
#include "numericitem.h"
#include "numericitemrange.h"
#include "ilwisoperation.h"

quint64 Ilwis::GridBlockInternal::_blockid = 0;

using namespace Ilwis;

GridCoverage::GridCoverage()
{
}

GridCoverage::GridCoverage(const Resource& res) : Coverage(res){

}

GridCoverage::~GridCoverage()
{
}

const IGeoReference& GridCoverage::georeference() const
{
    return _georef;
}

void GridCoverage::georeference(const IGeoReference &grf)
{
    _georef = grf;
    if ( _grid.isNull() == false) { // remove the current grid, all has become uncertain
        _grid.reset(0);

    }
    if ( _georef.isValid()) {
        _georef->compute();
        setCoordinateSystem(grf->coordinateSystem()); // mandatory
    }
}

IlwisTypes GridCoverage::ilwisType() const
{
    return itGRID;
}

GridCoverage *GridCoverage::copy()
{
    GridCoverage *gc = new GridCoverage();
    copyTo(gc);
    return gc;

}

void GridCoverage::copyBinary(const IGridCoverage& gc, int index) {
    IGridCoverage gcNew;
    gcNew.set(this);
    Size inputSize =  gc->size();
    Size sz(inputSize.xsize(),inputSize.ysize(), 1);
    gcNew->georeference()->size(sz);
    PixelIterator iterIn(gc, Box3D<>(Voxel(0,0,index), Voxel(inputSize.xsize(), inputSize.ysize(), index + 1)));
    PixelIterator iterOut(gcNew, Box3D<>(Size(inputSize.xsize(), inputSize.ysize(), 1)));
    for_each(iterOut, iterOut.end(), [&](double& v){
         v = *iterIn;
        ++iterIn;
    });
}

IGridCoverage GridCoverage::get(quint32 index1, quint32 index2)
{
    IGridCoverage gcovParent;
    gcovParent.set(this);
    IGridCoverage gcov = OperationHelperRaster::initialize(gcovParent,itGRID, itDOMAIN | itCOORDSYSTEM | itGEOREF);
    gcov->size(Size(size().xsize(), size().ysize()));
    gcov->_grid.reset(gcov->_grid->clone(index1, index2));

    return gcov;

}

IGridCoverage GridCoverage::get(const QString &item1, const QString &item2)
{
    IDomain indexDomain = datadef().domain(DataDefinition::daINDEX);
    if (!indexDomain.isValid())
        return IGridCoverage();
    if ( indexDomain->valueType() == itNUMERICITEM)  {
        double item1Index = item1.toDouble();
        INumericItemDomain numdom = indexDomain.get<NumericItemDomain>();
        SPNumericItemRange numrange = numdom->range<NumericItemRange>();
        double index1 = numrange->index(item1Index);
        double rest1 = index1 - (int)index1;
        if ( std::abs(rest1) > EPS8 && numrange->isContinous()) {
            int lowerIndex = std::floor(index1);
            double rest2 = 1.0 - rest1;
            QString expr = numrange->interpolation();
            QString nm = name();
            int ind = 0;
            if( (ind=nm.lastIndexOf(".")) != -1){
                nm = nm.left(ind);
            }
            nm = QString("%1_%2_%3").arg(nm).arg(lowerIndex).arg(lowerIndex+1);
            expr = nm + "=" + expr.arg(QString("%1*%2[%3]").arg(rest2).arg(name()).arg(lowerIndex)).arg(QString("%1*%2[%3]").arg(rest1).arg(name()).arg(lowerIndex+1));
            IGridCoverage mp = Operation::calculate<IGridCoverage>(nm,expr);
            if ( mp.isValid())
                return mp;
        }
    }
    return IGridCoverage();
}

Grid *GridCoverage::grid()
{
    Locker lock(_mutex);
    if ( _georef->isValid() && !connector().isNull()) {
        if ( _grid.isNull()) {
            _grid.reset(connector()->loadGridData(this));
            if (_grid.isNull())
                return 0;
        }
        Grid *grd = _grid.data();
        return grd;
    }
    return 0;
}

void GridCoverage::copyTo(IlwisObject *obj)
{
    Locker lock(_mutex);
    Coverage::copyTo(obj);
    GridCoverage *gc = static_cast<GridCoverage *>(obj);
    gc->_georef = _georef;
    if ( _grid) {
        gc->_grid.reset(_grid->clone());
    }

}

Resource GridCoverage::resource(int mode) const
{
    Resource res = Coverage::resource(mode);
    if ( mode & IlwisObject::cmEXTENDED) {
        res["georeference()"] = georeference()->id();
        res.setExtendedType( res.extendedType() | itGEOREF);
    }
    return res;
}

Size GridCoverage::size() const
{
    if (_size.isValid() && !_size.isNull())
        return _size;
    if (!_grid.isNull())
        const_cast<GridCoverage *>(this)->_size = _grid->size();
    else if ( _georef.isValid())
        const_cast<GridCoverage *>(this)->_size = _georef->size();

    return _size;

}

void GridCoverage::size(const Size &sz)
{
    // size must always be positive or undefined
    if (sz.xsize() > 0 && sz.ysize() > 0) {
        _size = sz;
        if (!_grid.isNull())
            _grid->setSize(sz);
        if (_georef.isValid())
            _georef->size(sz);
    }

}

<|endoftext|>


<commit_before>#include "style/polygonStyle.h"

#include "gl/mesh.h"
#include "gl/shaderProgram.h"
#include "map.h"
#include "marker/marker.h"
#include "material.h"
#include "platform.h"
#include "scene/drawRule.h"
#include "tile/tile.h"
#include "util/builders.h"
#include "util/extrude.h"

#include "glm/vec2.hpp"
#include "glm/vec3.hpp"
#include "glm/gtc/type_precision.hpp"
#include <cmath>

#include "polygon_fs.h"
#include "polygon_vs.h"

constexpr float position_scale = 8192.0f;
constexpr float texture_scale = 65535.0f;
constexpr float normal_scale = 127.0f;

namespace Tangram {

struct PolygonVertexNoUVs {

    PolygonVertexNoUVs(glm::vec3 position, uint32_t order, glm::vec3 normal, glm::vec2 uv, GLuint abgr, GLuint selection)
        : pos(glm::i16vec4{ glm::round(position * position_scale), order }),
          norm(normal * normal_scale),
          abgr(abgr),
          selection(selection) {}

    glm::i16vec4 pos; // pos.w contains layer (params.order)
    glm::i8vec3 norm;
    uint8_t padding = 0;
    GLuint abgr;
    GLuint selection;
};

struct PolygonVertex : PolygonVertexNoUVs {

    PolygonVertex(glm::vec3 position, uint32_t order, glm::vec3 normal, glm::vec2 uv, GLuint abgr, GLuint selection)
        : PolygonVertexNoUVs(position, order, normal, uv, abgr, selection), texcoord(uv * texture_scale) {}

    glm::u16vec2 texcoord;
};

PolygonStyle::PolygonStyle(std::string _name, Blending _blendMode, GLenum _drawMode, bool _selection)
    : Style(_name, _blendMode, _drawMode, _selection)
{}

void PolygonStyle::constructVertexLayout() {

    if (m_texCoordsGeneration) {
        m_vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
            {"a_position", 4, GL_SHORT, false, 0},
            {"a_normal", 4, GL_BYTE, true, 0}, // The 4th byte is for padding
            {"a_color", 4, GL_UNSIGNED_BYTE, true, 0},
            {"a_selection_color", 4, GL_UNSIGNED_BYTE, true, 0},
            {"a_texcoord", 2, GL_UNSIGNED_SHORT, true, 0},
        }));
    } else {
        m_vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
            {"a_position", 4, GL_SHORT, false, 0},
            {"a_normal", 4, GL_BYTE, true, 0},
            {"a_color", 4, GL_UNSIGNED_BYTE, true, 0},
            {"a_selection_color", 4, GL_UNSIGNED_BYTE, true, 0},
        }));
    }

}

void PolygonStyle::constructShaderProgram() {

    m_shaderSource->setSourceStrings(SHADER_SOURCE(polygon_fs),
                                      SHADER_SOURCE(polygon_vs));

    if (m_texCoordsGeneration) {
        m_shaderSource->addSourceBlock("defines", "#define TANGRAM_USE_TEX_COORDS\n");
    }
}

template <class V>
struct PolygonStyleBuilder : public StyleBuilder {

public:

    struct {
        uint32_t order = 0;
        uint32_t color = 0xffffffff;
        glm::vec2 extrude;
        float height;
        float minHeight;
        uint32_t selectionColor = 0;
    } m_params;

    void setup(const Tile& _tile) override {
        m_tileUnitsPerMeter = _tile.getInverseScale();
        m_zoom = _tile.getID().z;
        m_meshData.clear();
    }

    void setup(const Marker& _marker, int zoom) override {
        m_zoom = zoom;
        m_tileUnitsPerMeter = 1.f / _marker.extent();
        m_meshData.clear();
    }

    bool addPolygon(const Polygon& _polygon, const Properties& _props, const DrawRule& _rule) override;

    const Style& style() const override { return m_style; }

    std::unique_ptr<StyledMesh> build() override;

    PolygonStyleBuilder(const PolygonStyle& _style) : m_style(_style) {}

    void parseRule(const DrawRule& _rule, const Properties& _props);

    PolygonBuilder& polygonBuilder() { return m_builder; }

private:

    const PolygonStyle& m_style;

    PolygonBuilder m_builder;

    MeshData<V> m_meshData;

    float m_tileUnitsPerMeter = 0;
    int m_zoom = 0;

};

template <class V>
std::unique_ptr<StyledMesh> PolygonStyleBuilder<V>::build() {
    if (m_meshData.vertices.empty()) { return nullptr; }

    auto mesh = std::make_unique<Mesh<V>>(m_style.vertexLayout(),
                                                      m_style.drawMode());
    mesh->compile(m_meshData);
    m_meshData.clear();

    return std::move(mesh);
}

template <class V>
void PolygonStyleBuilder<V>::parseRule(const DrawRule& _rule, const Properties& _props) {
    _rule.get(StyleParamKey::color, m_params.color);
    _rule.get(StyleParamKey::extrude, m_params.extrude);
    _rule.get(StyleParamKey::order, m_params.order);

    if (Tangram::getDebugFlag(Tangram::DebugFlags::proxy_colors)) {
        m_params.color <<= (m_zoom % 6);
    }

    auto& extrude = m_params.extrude;
    m_params.minHeight = getLowerExtrudeMeters(extrude, _props) * m_tileUnitsPerMeter;
    m_params.height = getUpperExtrudeMeters(extrude, _props) * m_tileUnitsPerMeter;

    m_params.selectionColor = _rule.selectionColor;
}

template <class V>
bool PolygonStyleBuilder<V>::addPolygon(const Polygon& _polygon, const Properties& _props, const DrawRule& _rule) {

    parseRule(_rule, _props);

    m_builder.addVertex = [this](const glm::vec3& coord,
                                 const glm::vec3& normal,
                                 const glm::vec2& uv) {
        m_meshData.vertices.push_back({ coord, m_params.order, normal, uv, m_params.color, m_params.selectionColor });
    };

    if (m_params.minHeight != m_params.height) {
        Builders::buildPolygonExtrusion(_polygon, m_params.minHeight,
                                        m_params.height, m_builder);
    }

    Builders::buildPolygon(_polygon, m_params.height, m_builder);

    m_meshData.indices.insert(m_meshData.indices.end(),
                              m_builder.indices.begin(),
                              m_builder.indices.end());

    m_meshData.offsets.emplace_back(m_builder.indices.size(),
                                    m_builder.numVertices);
    m_builder.clear();

    return true;
}

std::unique_ptr<StyleBuilder> PolygonStyle::createBuilder() const {
    if (m_texCoordsGeneration) {
        auto builder = std::make_unique<PolygonStyleBuilder<PolygonVertex>>(*this);
        builder->polygonBuilder().useTexCoords = true;
        return std::move(builder);
    } else {
        auto builder = std::make_unique<PolygonStyleBuilder<PolygonVertexNoUVs>>(*this);
        builder->polygonBuilder().useTexCoords = false;
        return std::move(builder);
    }
}

}
<commit_msg>Fix: clean parameter set for polygon style builder (#1651)<commit_after>#include "style/polygonStyle.h"

#include "gl/mesh.h"
#include "gl/shaderProgram.h"
#include "map.h"
#include "marker/marker.h"
#include "material.h"
#include "platform.h"
#include "scene/drawRule.h"
#include "tile/tile.h"
#include "util/builders.h"
#include "util/extrude.h"

#include "glm/vec2.hpp"
#include "glm/vec3.hpp"
#include "glm/gtc/type_precision.hpp"
#include <cmath>

#include "polygon_fs.h"
#include "polygon_vs.h"

constexpr float position_scale = 8192.0f;
constexpr float texture_scale = 65535.0f;
constexpr float normal_scale = 127.0f;

namespace Tangram {

struct PolygonVertexNoUVs {

    PolygonVertexNoUVs(glm::vec3 position, uint32_t order, glm::vec3 normal, glm::vec2 uv, GLuint abgr, GLuint selection)
        : pos(glm::i16vec4{ glm::round(position * position_scale), order }),
          norm(normal * normal_scale),
          abgr(abgr),
          selection(selection) {}

    glm::i16vec4 pos; // pos.w contains layer (params.order)
    glm::i8vec3 norm;
    uint8_t padding = 0;
    GLuint abgr;
    GLuint selection;
};

struct PolygonVertex : PolygonVertexNoUVs {

    PolygonVertex(glm::vec3 position, uint32_t order, glm::vec3 normal, glm::vec2 uv, GLuint abgr, GLuint selection)
        : PolygonVertexNoUVs(position, order, normal, uv, abgr, selection), texcoord(uv * texture_scale) {}

    glm::u16vec2 texcoord;
};

PolygonStyle::PolygonStyle(std::string _name, Blending _blendMode, GLenum _drawMode, bool _selection)
    : Style(_name, _blendMode, _drawMode, _selection)
{}

void PolygonStyle::constructVertexLayout() {

    if (m_texCoordsGeneration) {
        m_vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
            {"a_position", 4, GL_SHORT, false, 0},
            {"a_normal", 4, GL_BYTE, true, 0}, // The 4th byte is for padding
            {"a_color", 4, GL_UNSIGNED_BYTE, true, 0},
            {"a_selection_color", 4, GL_UNSIGNED_BYTE, true, 0},
            {"a_texcoord", 2, GL_UNSIGNED_SHORT, true, 0},
        }));
    } else {
        m_vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
            {"a_position", 4, GL_SHORT, false, 0},
            {"a_normal", 4, GL_BYTE, true, 0},
            {"a_color", 4, GL_UNSIGNED_BYTE, true, 0},
            {"a_selection_color", 4, GL_UNSIGNED_BYTE, true, 0},
        }));
    }

}

void PolygonStyle::constructShaderProgram() {

    m_shaderSource->setSourceStrings(SHADER_SOURCE(polygon_fs),
                                      SHADER_SOURCE(polygon_vs));

    if (m_texCoordsGeneration) {
        m_shaderSource->addSourceBlock("defines", "#define TANGRAM_USE_TEX_COORDS\n");
    }
}

template <class V>
struct PolygonStyleBuilder : public StyleBuilder {

public:

    struct Parameters {
        uint32_t order = 0;
        uint32_t color = 0xffffffff;
        glm::vec2 extrude;
        float height;
        float minHeight;
        uint32_t selectionColor = 0;
    };

    void setup(const Tile& _tile) override {
        m_tileUnitsPerMeter = _tile.getInverseScale();
        m_zoom = _tile.getID().z;
        m_meshData.clear();
    }

    void setup(const Marker& _marker, int zoom) override {
        m_zoom = zoom;
        m_tileUnitsPerMeter = 1.f / _marker.extent();
        m_meshData.clear();
    }

    bool addPolygon(const Polygon& _polygon, const Properties& _props, const DrawRule& _rule) override;

    const Style& style() const override { return m_style; }

    std::unique_ptr<StyledMesh> build() override;

    PolygonStyleBuilder(const PolygonStyle& _style) : m_style(_style) {}

    Parameters parseRule(const DrawRule& _rule, const Properties& _props);

    PolygonBuilder& polygonBuilder() { return m_builder; }

private:

    const PolygonStyle& m_style;

    PolygonBuilder m_builder;

    MeshData<V> m_meshData;

    float m_tileUnitsPerMeter = 0;
    int m_zoom = 0;

};

template <class V>
std::unique_ptr<StyledMesh> PolygonStyleBuilder<V>::build() {
    if (m_meshData.vertices.empty()) { return nullptr; }

    auto mesh = std::make_unique<Mesh<V>>(m_style.vertexLayout(),
                                                      m_style.drawMode());
    mesh->compile(m_meshData);
    m_meshData.clear();

    return std::move(mesh);
}

template <class V>
auto PolygonStyleBuilder<V>::parseRule(const DrawRule& _rule, const Properties& _props) -> Parameters {
    Parameters p;
    _rule.get(StyleParamKey::color, p.color);
    _rule.get(StyleParamKey::extrude, p.extrude);
    _rule.get(StyleParamKey::order, p.order);

    if (Tangram::getDebugFlag(Tangram::DebugFlags::proxy_colors)) {
        p.color <<= (m_zoom % 6);
    }

    auto& extrude = p.extrude;
    p.minHeight = getLowerExtrudeMeters(extrude, _props) * m_tileUnitsPerMeter;
    p.height = getUpperExtrudeMeters(extrude, _props) * m_tileUnitsPerMeter;

    p.selectionColor = _rule.selectionColor;
    return p;
}

template <class V>
bool PolygonStyleBuilder<V>::addPolygon(const Polygon& _polygon, const Properties& _props, const DrawRule& _rule) {

    auto p = parseRule(_rule, _props);

    m_builder.addVertex = [this, p](const glm::vec3& coord,
                                 const glm::vec3& normal,
                                 const glm::vec2& uv) {
        m_meshData.vertices.push_back({ coord, p.order, normal, uv, p.color, p.selectionColor });
    };

    if (p.minHeight != p.height) {
        Builders::buildPolygonExtrusion(_polygon, p.minHeight,
                                        p.height, m_builder);
    }

    Builders::buildPolygon(_polygon, p.height, m_builder);

    m_meshData.indices.insert(m_meshData.indices.end(),
                              m_builder.indices.begin(),
                              m_builder.indices.end());

    m_meshData.offsets.emplace_back(m_builder.indices.size(),
                                    m_builder.numVertices);
    m_builder.clear();

    return true;
}

std::unique_ptr<StyleBuilder> PolygonStyle::createBuilder() const {
    if (m_texCoordsGeneration) {
        auto builder = std::make_unique<PolygonStyleBuilder<PolygonVertex>>(*this);
        builder->polygonBuilder().useTexCoords = true;
        return std::move(builder);
    } else {
        auto builder = std::make_unique<PolygonStyleBuilder<PolygonVertexNoUVs>>(*this);
        builder->polygonBuilder().useTexCoords = false;
        return std::move(builder);
    }
}

}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_FUN_CHOLESKY_DECOMPOSE_HPP
#define STAN_MATH_PRIM_MAT_FUN_CHOLESKY_DECOMPOSE_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/err/check_pos_definite.hpp>
#include <stan/math/prim/mat/err/check_square.hpp>
#include <stan/math/prim/mat/err/check_symmetric.hpp>
#ifdef STAN_OPENCL
#include <stan/math/gpu/cholesky_decompose.hpp>
#endif

#include <cmath>

namespace stan {
namespace math {

/**
 * Return the lower-triangular Cholesky factor (i.e., matrix
 * square root) of the specified square, symmetric matrix.  The return
 * value \f$L\f$ will be a lower-traingular matrix such that the
 * original matrix \f$A\f$ is given by
 * <p>\f$A = L \times L^T\f$.
 * @param m Symmetrix matrix.
 * @return Square root of matrix.
 * @throw std::domain_error if m is not a symmetric matrix or
 *   if m is not positive definite (if m has more than 0 elements)
 */
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> cholesky_decompose(
    const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& m) {
  check_square("cholesky_decompose", "m", m);
  check_symmetric("cholesky_decompose", "m", m);
#ifdef STAN_OPENCL
  if (m.rows() > 1800) {
    matrix_gpu m_gpu(m);
    Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> m_chol(m.rows(), m.cols());
    cholesky_decompose(m_gpu, floor(m.rows() / 2), 2, 100);
    copy(m_chol, m_gpu);  // NOLINT
    return m_chol;
  } else {
#endif
    Eigen::LLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > llt(m.rows());
    llt.compute(m);
    check_pos_definite("cholesky_decompose", "m", llt);
    return llt.matrixL();
#ifdef STAN_OPENCL
  }
#endif
#ifdef STAN_OPENCL
  }
#endif
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (tags/RELEASE_500/final)<commit_after>#ifndef STAN_MATH_PRIM_MAT_FUN_CHOLESKY_DECOMPOSE_HPP
#define STAN_MATH_PRIM_MAT_FUN_CHOLESKY_DECOMPOSE_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/err/check_pos_definite.hpp>
#include <stan/math/prim/mat/err/check_square.hpp>
#include <stan/math/prim/mat/err/check_symmetric.hpp>
#ifdef STAN_OPENCL
#include <stan/math/gpu/cholesky_decompose.hpp>
#endif

#include <cmath>

namespace stan {
namespace math {

/**
 * Return the lower-triangular Cholesky factor (i.e., matrix
 * square root) of the specified square, symmetric matrix.  The return
 * value \f$L\f$ will be a lower-traingular matrix such that the
 * original matrix \f$A\f$ is given by
 * <p>\f$A = L \times L^T\f$.
 * @param m Symmetrix matrix.
 * @return Square root of matrix.
 * @throw std::domain_error if m is not a symmetric matrix or
 *   if m is not positive definite (if m has more than 0 elements)
 */
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> cholesky_decompose(
    const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& m) {
  check_square("cholesky_decompose", "m", m);
  check_symmetric("cholesky_decompose", "m", m);
#ifdef STAN_OPENCL
  if (m.rows() > 1800) {
    matrix_gpu m_gpu(m);
    Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> m_chol(m.rows(), m.cols());
    cholesky_decompose(m_gpu, floor(m.rows() / 2), 2, 100);
    copy(m_chol, m_gpu);  // NOLINT
    return m_chol;
  } else {
#endif
    Eigen::LLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > llt(m.rows());
    llt.compute(m);
    check_pos_definite("cholesky_decompose", "m", llt);
    return llt.matrixL();
#ifdef STAN_OPENCL
  }
#endif
#ifdef STAN_OPENCL
}
#endif
}  // namespace math

}  // namespace stan
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#include "llvm/Support/Host.h"

#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseAST.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/LangOptions.h"

#include <vector>
#include <string>
#include <set>
#include <iostream>
#include <sstream>

using namespace std;
using namespace clang;
using namespace llvm;

template<class... Args, template<class...> class Associative>
bool contains(const Associative<Args...>& container, const typename Associative<Args...>::key_type& key)
{
	auto it = container.find(key);
	return (it != container.end());
}

template<class... Args, template<class...> class Container>
std::string join(const Container<Args...>& container, const std::string& separator)
{
	if (container.empty()) {
		return "";
	} else {

		auto it = container.begin();

		std::string ret = *it;

		++it;
		for (; it != container.end(); ++it) {
			ret += separator + *it;
		}
		return ret;
	}
}

class MyASTConsumer
{
	bool m_inClass = false;
	list<string> m_namespaces;
	list<CXXRecordDecl*> m_visitLater;
	stringstream out;
	set<string> m_sourceFiles;
	SourceManager* m_sourceManager;

public:

	MyASTConsumer(SourceManager* sm) : m_sourceManager(sm) {

		FileID mainID = sm->getMainFileID();
		const FileEntry* entry = sm->getFileEntryForID(mainID);
		m_sourceFiles.insert(entry->getName());
	}

	ostream& print(ostream& os) {

		os << "#include \"reflection_impl.h\"" << endl;

		for(const string& filename: m_sourceFiles) {
			os << "#include \"" << filename << "\"" << endl;
		}

		os << endl << out.str() << endl;
		return os;
	}

	void handleDecl(Decl* decl)
	{
		if (decl == nullptr) {
			return;
		}

		AccessSpecifier as = decl->getAccess();

		if (as == AS_protected || as == AS_private) {
			return;
		}

		if (NamespaceDecl* nd = dyn_cast<NamespaceDecl>(decl)) {
			if (nd->isAnonymousNamespace()) {
				return; // no interest in hidden symbols
			}

			m_namespaces.push_back(nd->getDeclName().getAsString());
			// recurse
			for (DeclContext::decl_iterator it = nd->decls_begin(); it != nd->decls_end(); ++it) {
				clang::Decl* subdecl = *it;
				handleDecl(subdecl);
			}
			m_namespaces.pop_back();

		} else if (FieldDecl *fd = dyn_cast<FieldDecl>(decl)) {
			out << "ATTRIBUTE(" << fd->getDeclName().getAsString() << ")" << endl;

		} else if (RecordDecl* rd = dyn_cast<RecordDecl>(decl)) {

			if (CXXRecordDecl* crd = dyn_cast<CXXRecordDecl>(rd)) {
				if (crd->hasDefinition()) {
					crd = crd->getDefinition();

					if (m_inClass) {
						m_visitLater.push_back(crd);
						return;
					}

					m_namespaces.push_back(crd->getDeclName().getAsString());

					m_inClass = true;

					out << "BEGIN_CLASS(" << join(m_namespaces, "::") << ")" << endl;

					for (auto it = crd->bases_begin(); it != crd->bases_end(); ++it) {
						QualType t = it->getType();
						out << "SUPER_CLASS(" << t.getAsString() << ")" << endl;
					}

					// recurse
					for (DeclContext::decl_iterator it = crd->decls_begin(); it != crd->decls_end(); ++it) {
						clang::Decl* subdecl = *it;
						handleDecl(subdecl);
					}
					m_inClass = false;
					out << "END_CLASS" << endl << endl;

					while( !m_visitLater.empty() ) {
						CXXRecordDecl* nested = m_visitLater.front();
						m_visitLater.pop_front();
						handleDecl(nested);
					}

					m_namespaces.pop_back();
				}
			} /*else {
				// don't know what to do with this, the only possibility left are unions, right?
			}*/

		} /*else if (VarDecl *vd = llvm::dyn_cast<clang::VarDecl>(decl)) {
			std::cout << vd << std::endl;
			if( vd->isFileVarDecl() && vd->hasExternalStorage() )
			{
				std::cerr << "Read top-level variable decl: '";
				std::cerr << vd->getDeclName().getAsString() ;
				std::cerr << std::endl;
			}

		}*/ else if (FunctionDecl* fd = llvm::dyn_cast<FunctionDecl>(decl)) {

			const string name = fd->getDeclName().getAsString();
			QualType qt = fd->getResultType();
			const string returnType =  qt.getAsString();

			list<string> args;

			for (auto it = fd->param_begin(); it != fd->param_end(); ++it) {
				QualType pt = (*it)->getType();
				// if we should need the names, this is how we get them *it)->getDeclName().getAsString()
				args.push_back(pt.getAsString());
			}

			const string argstr = join(args, ", ");

			if (CXXMethodDecl* md = dyn_cast<CXXMethodDecl>(decl)) {

				if (!m_inClass) {
					// out-of-class definitions are of no interest to us
					return;
				}

				if (dyn_cast<CXXConstructorDecl>(decl)) {
					if (args.empty()) {
						out << "DEFAULT_CONSTRUCTOR()" << endl;
					} else {
						out << "CONSTRUCTOR(" << argstr << ")" << endl;
					}
				} else if (dyn_cast<CXXConversionDecl>(decl)) {
					// ex: operator bool();
					// dont't know what to do with this yet
				} else if (dyn_cast<CXXDestructorDecl>(decl)) {
					// this is pretty much expected :)
				} else {

					QualType mqt = md->getType();
					// this prints the method type: mqt.getAsString()

					const FunctionProtoType* proto = dyn_cast<const FunctionProtoType>(mqt.getTypePtr());

					Qualifiers quals = Qualifiers::fromCVRMask(proto->getTypeQuals());

					const bool isStatic   = md->isStatic();
					const bool isVirtual  = md->isVirtual();
					const bool isConst    = quals.hasConst();
					const bool isVolatile = quals.hasVolatile();

					if (isVirtual && (md->size_overridden_methods() > 0)) {
						return; // we don't need to repeat this
					}

					string a = string(args.empty() ? "" : ", ") + argstr;

					if (isStatic) {
						out << "STATIC_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else if (isConst && isVolatile) {
						out << "CONST_VOLATILE_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else if (isConst) {
						out << "CONST_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else if (isVolatile) {
						out << "VOLATILE_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else {
						out << "METHOD(" << name << ", " << returnType << a << ")" << endl;
					}
				}
			} else if (fd->hasLinkage() && fd->getLinkage() == ExternalLinkage) {
				// is not a method
				string a = string(args.empty() ? "" : ", ") + argstr;
				out << "FUNCTION(" << name << ", " << returnType << a << ")" << endl;

			}
		} else if (clang::ClassTemplateDecl* td = llvm::dyn_cast<clang::ClassTemplateDecl>(decl)) {
			for (clang::ClassTemplateDecl::spec_iterator it = td->spec_begin(); it != td->spec_end(); ++it) {
				//specializations are classes too
				clang::ClassTemplateSpecializationDecl* spec = *it;
				handleDecl(spec);
			}
		}
	}
};

int main(int argc, const char* argv[])
{
	vector<const char*> args;
	bool foundCpp = false;
	bool foundCpp11 = false;
	bool foundSpellChecking = false;

	for (int i = 1; i < argc; ++i) {
		if (strcmp(argv[i], "-std=c++11") == 0) {
			foundCpp11 = true;
		} else if (strcmp(argv[i], "-x") == 0) {
			if (((i+1) < argc) && (strcmp(argv[i+1], "c++") == 0)) {
				foundCpp = true;
			}
		} else if (strcmp(argv[i], "-xc++") == 0) {
			foundCpp = true;
		} else if (strcmp(argv[i], "-fno-spell-checking") == 0) {
			foundSpellChecking = true;
		} else if (strcmp(argv[i], "-fspell-checking") == 0) {
			foundSpellChecking = true;
		}
	}

	args.push_back(argv[0]);

	if (!foundCpp) {
		args.push_back("-xc++");
	}

	if (!foundCpp11) {
		args.push_back("-std=c++11");
	}

	if (!foundSpellChecking) {
		args.push_back("-fno-spell-checking");
	}

	args.push_back("-I/usr/lib/clang/3.1/include"); // why can't clang find this from the resource path?
	args.push_back("-Qunused-arguments"); // why do I keep getting warnings about the unused linker if I'm only creating an ASTunit

	for (int i = 1; i < argc; ++i) {
		args.push_back(argv[i]);
	}

	DiagnosticOptions options;
	options.ShowCarets = 1;
	options.ShowColors = 1;

	TextDiagnosticPrinter *DiagClient =	new TextDiagnosticPrinter(llvm::errs(), options);

	llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
	llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(new DiagnosticsEngine(DiagID, DiagClient));

	llvm::OwningPtr<ASTUnit> unit(ASTUnit::LoadFromCommandLine(&args[0], &args[0]+args.size(), Diags, "/usr/lib/clang/3.1/", /*OnlyLocalDecls=*/false, /*CaptureDiagnostics=*/false, 0, 0, true, /*PrecompilePreamble=*/false, /*TUKind=*/TU_Complete, /*CacheCodeCompletionResults=*/false, /*AllowPCHWithCompilerErrors=*/false));

	if (DiagClient->getNumErrors() > 0) {
		return 1;
	}

	ASTContext& astContext = unit->getASTContext();
	MyASTConsumer astConsumer(&unit->getSourceManager());

	for (auto it = astContext.getTranslationUnitDecl()->decls_begin(); it != astContext.getTranslationUnitDecl()->decls_end(); ++it) {
		Decl* subdecl = *it;
		SourceLocation location = subdecl->getLocation();

		if (unit->isInMainFileID(location)) {
			astConsumer.handleDecl(subdecl);
		}
	}

	astConsumer.print(cout);

	return 0;
}
<commit_msg>Correct printing of bools<commit_after>#include "llvm/Support/Host.h"

#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseAST.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/LangOptions.h"

#include <vector>
#include <string>
#include <set>
#include <iostream>
#include <sstream>

using namespace std;
using namespace clang;
using namespace llvm;

template<class... Args, template<class...> class Associative>
bool contains(const Associative<Args...>& container, const typename Associative<Args...>::key_type& key)
{
	auto it = container.find(key);
	return (it != container.end());
}

template<class... Args, template<class...> class Container>
std::string join(const Container<Args...>& container, const std::string& separator)
{
	if (container.empty()) {
		return "";
	} else {

		auto it = container.begin();

		std::string ret = *it;

		++it;
		for (; it != container.end(); ++it) {
			ret += separator + *it;
		}
		return ret;
	}
}

class MyASTConsumer
{
	bool m_inClass = false;
	list<string> m_namespaces;
	list<CXXRecordDecl*> m_visitLater;
	stringstream out;
	set<string> m_sourceFiles;
	SourceManager* m_sourceManager;
	PrintingPolicy m_printPol;

public:

	MyASTConsumer(SourceManager* sm, LangOptions opts) : m_sourceManager(sm), m_printPol(opts) {
		m_printPol.Bool = 1;
		FileID mainID = sm->getMainFileID();
		const FileEntry* entry = sm->getFileEntryForID(mainID);
		m_sourceFiles.insert(entry->getName());
	}

	ostream& print(ostream& os) {

		os << "#include \"reflection_impl.h\"" << endl;

		for(const string& filename: m_sourceFiles) {
			os << "#include \"" << filename << "\"" << endl;
		}

		os << endl << out.str() << endl;
		return os;
	}

	void handleDecl(Decl* decl)
	{
		if (decl == nullptr) {
			return;
		}

		AccessSpecifier as = decl->getAccess();

		if (as == AS_protected || as == AS_private) {
			return;
		}

		if (NamespaceDecl* nd = dyn_cast<NamespaceDecl>(decl)) {
			if (nd->isAnonymousNamespace()) {
				return; // no interest in hidden symbols
			}

			m_namespaces.push_back(nd->getDeclName().getAsString());
			// recurse
			for (DeclContext::decl_iterator it = nd->decls_begin(); it != nd->decls_end(); ++it) {
				clang::Decl* subdecl = *it;
				handleDecl(subdecl);
			}
			m_namespaces.pop_back();

		} else if (FieldDecl *fd = dyn_cast<FieldDecl>(decl)) {
			out << "ATTRIBUTE(" << fd->getDeclName().getAsString() << ")" << endl;

		} else if (RecordDecl* rd = dyn_cast<RecordDecl>(decl)) {

			if (CXXRecordDecl* crd = dyn_cast<CXXRecordDecl>(rd)) {
				if (crd->hasDefinition()) {
					crd = crd->getDefinition();

					if (m_inClass) {
						m_visitLater.push_back(crd);
						return;
					}

					m_namespaces.push_back(crd->getDeclName().getAsString());

					m_inClass = true;

					out << "BEGIN_CLASS(" << join(m_namespaces, "::") << ")" << endl;

					for (auto it = crd->bases_begin(); it != crd->bases_end(); ++it) {
						QualType t = it->getType();
						out << "SUPER_CLASS(" << t.getAsString(m_printPol) << ")" << endl;
					}

					// recurse
					for (DeclContext::decl_iterator it = crd->decls_begin(); it != crd->decls_end(); ++it) {
						clang::Decl* subdecl = *it;
						handleDecl(subdecl);
					}
					m_inClass = false;
					out << "END_CLASS" << endl << endl;

					while( !m_visitLater.empty() ) {
						CXXRecordDecl* nested = m_visitLater.front();
						m_visitLater.pop_front();
						handleDecl(nested);
					}

					m_namespaces.pop_back();
				}
			} /*else {
				// don't know what to do with this, the only possibility left are unions, right?
			}*/

		} /*else if (VarDecl *vd = llvm::dyn_cast<clang::VarDecl>(decl)) {
			std::cout << vd << std::endl;
			if( vd->isFileVarDecl() && vd->hasExternalStorage() )
			{
				std::cerr << "Read top-level variable decl: '";
				std::cerr << vd->getDeclName().getAsString(m_printPol) ;
				std::cerr << std::endl;
			}

		}*/ else if (FunctionDecl* fd = llvm::dyn_cast<FunctionDecl>(decl)) {

			const string name = fd->getDeclName().getAsString();
			QualType qt = fd->getResultType();
			const string returnType =  qt.getAsString(m_printPol);

			list<string> args;

			for (auto it = fd->param_begin(); it != fd->param_end(); ++it) {
				QualType pt = (*it)->getType();
				// if we should need the names, this is how we get them *it)->getDeclName().getAsString(m_printPol)
				args.push_back(pt.getAsString(m_printPol));
			}

			const string argstr = join(args, ", ");

			if (CXXMethodDecl* md = dyn_cast<CXXMethodDecl>(decl)) {

				if (!m_inClass) {
					// out-of-class definitions are of no interest to us
					return;
				}

				if (dyn_cast<CXXConstructorDecl>(decl)) {
					if (args.empty()) {
						out << "DEFAULT_CONSTRUCTOR()" << endl;
					} else {
						out << "CONSTRUCTOR(" << argstr << ")" << endl;
					}
				} else if (dyn_cast<CXXConversionDecl>(decl)) {
					// ex: operator bool();
					// dont't know what to do with this yet
				} else if (dyn_cast<CXXDestructorDecl>(decl)) {
					// this is pretty much expected :)
				} else {

					QualType mqt = md->getType();
					// this prints the method type: mqt.getAsString(m_printPol)

					const FunctionProtoType* proto = dyn_cast<const FunctionProtoType>(mqt.getTypePtr());

					Qualifiers quals = Qualifiers::fromCVRMask(proto->getTypeQuals());

					const bool isStatic   = md->isStatic();
					const bool isVirtual  = md->isVirtual();
					const bool isConst    = quals.hasConst();
					const bool isVolatile = quals.hasVolatile();

					if (isVirtual && (md->size_overridden_methods() > 0)) {
						return; // we don't need to repeat this
					}

					string a = string(args.empty() ? "" : ", ") + argstr;

					if (isStatic) {
						out << "STATIC_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else if (isConst && isVolatile) {
						out << "CONST_VOLATILE_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else if (isConst) {
						out << "CONST_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else if (isVolatile) {
						out << "VOLATILE_METHOD(" << name << ", " << returnType << a << ")" << endl;
					} else {
						out << "METHOD(" << name << ", " << returnType << a << ")" << endl;
					}
				}
			} else if (fd->hasLinkage() && fd->getLinkage() == ExternalLinkage) {
				// is not a method
				string a = string(args.empty() ? "" : ", ") + argstr;
				out << "FUNCTION(" << name << ", " << returnType << a << ")" << endl;

			}
		} else if (clang::ClassTemplateDecl* td = llvm::dyn_cast<clang::ClassTemplateDecl>(decl)) {
			for (clang::ClassTemplateDecl::spec_iterator it = td->spec_begin(); it != td->spec_end(); ++it) {
				//specializations are classes too
				clang::ClassTemplateSpecializationDecl* spec = *it;
				handleDecl(spec);
			}
		}
	}
};

int main(int argc, const char* argv[])
{
	vector<const char*> args;
	bool foundCpp = false;
	bool foundCpp11 = false;
	bool foundSpellChecking = false;

	for (int i = 1; i < argc; ++i) {
		if (strcmp(argv[i], "-std=c++11") == 0) {
			foundCpp11 = true;
		} else if (strcmp(argv[i], "-x") == 0) {
			if (((i+1) < argc) && (strcmp(argv[i+1], "c++") == 0)) {
				foundCpp = true;
			}
		} else if (strcmp(argv[i], "-xc++") == 0) {
			foundCpp = true;
		} else if (strcmp(argv[i], "-fno-spell-checking") == 0) {
			foundSpellChecking = true;
		} else if (strcmp(argv[i], "-fspell-checking") == 0) {
			foundSpellChecking = true;
		}
	}

	args.push_back(argv[0]);

	if (!foundCpp) {
		args.push_back("-xc++");
	}

	if (!foundCpp11) {
		args.push_back("-std=c++11");
	}

	if (!foundSpellChecking) {
		args.push_back("-fno-spell-checking");
	}

	args.push_back("-I/usr/lib/clang/3.1/include"); // why can't clang find this from the resource path?
	args.push_back("-Qunused-arguments"); // why do I keep getting warnings about the unused linker if I'm only creating an ASTunit

	for (int i = 1; i < argc; ++i) {
		args.push_back(argv[i]);
	}

	DiagnosticOptions options;
	options.ShowCarets = 1;
	options.ShowColors = 1;

	TextDiagnosticPrinter *DiagClient =	new TextDiagnosticPrinter(llvm::errs(), options);

	llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
	llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(new DiagnosticsEngine(DiagID, DiagClient));

	llvm::OwningPtr<ASTUnit> unit(ASTUnit::LoadFromCommandLine(&args[0], &args[0]+args.size(), Diags, "/usr/lib/clang/3.1/", /*OnlyLocalDecls=*/false, /*CaptureDiagnostics=*/false, 0, 0, true, /*PrecompilePreamble=*/false, /*TUKind=*/TU_Complete, /*CacheCodeCompletionResults=*/false, /*AllowPCHWithCompilerErrors=*/false));

	if (DiagClient->getNumErrors() > 0) {
		return 1;
	}

	ASTContext& astContext = unit->getASTContext();
	MyASTConsumer astConsumer(&unit->getSourceManager(), astContext.getLangOpts());

	for (auto it = astContext.getTranslationUnitDecl()->decls_begin(); it != astContext.getTranslationUnitDecl()->decls_end(); ++it) {
		Decl* subdecl = *it;
		SourceLocation location = subdecl->getLocation();

		if (unit->isInMainFileID(location)) {
			astConsumer.handleDecl(subdecl);
		}
	}

	astConsumer.print(cout);

	return 0;
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "NetworkServer.hpp"

NetworkWorker* NetworkWorker::singleton = nullptr;
NetworkWorker::NetworkWorker()
{
	if(singleton) exit(-1);
	singleton = this;
}

AnnVect3 NetworkWorker::getDistantPosition()
{
	return distantPosition;
}

void NetworkWorker::setLocalPositon(AnnVect3 position)
{
	localPosiion = position;
}

NetworkServer::NetworkServer() : NetworkWorker(),
	port(ANVPORT)
{
	//Singleton check

	myType = SERVER;

}

NetworkWorker* NetworkWorker::getSingleton()
{
	return singleton;
}

workerType NetworkWorker::getType()
{
	return myType;
}

int NetworkServer::initialize(int port)
{
	std::stringstream ss;
	if(port < netNS::MIN_PORT)
	{
		AnnDebug() << "Invalid port number";
		return netNS::NET_ERROR;
	}
	// ------ init network stuff -------
	error = net.createServer(port, netNS::UDP);
	if(error != netNS::NET_OK)
	{
		AnnDebug() << net.getError(error);
		return netNS::NET_ERROR;
	}

	for (int i=0; i<MAX_CLIENT; i++)
	{
		player[i].setConnected(false);
		player[i].setActive(false);
	}

	AnnDebug() << "---- Server ----";
	net.getLocalIP(localIP);
	ss << "Server IP: " << localIP;
	AnnDebug() << ss.str();
	ss.str("");
	ss << "Port: " << port;
	AnnDebug() << ss.str();
	return netNS::NET_OK;
}

// --- Do network communications ---
void NetworkServer::communicate(float frameTime)
{
	// communicate with client
	doClientCommunication();
	// Calculate elapsed time for network communications
	netTime += frameTime;
	if(netTime < netNS::NET_TIMER)
		return;

	netTime -= netNS::NET_TIMER;
	// check for inactive clients, called every NET_TIMER seconds
	checkNetworkTimeout();
}

// --- Check for network timeout ---

void NetworkServer::checkNetworkTimeout()
{
	std::stringstream ss;
	for (int i=0; i<MAX_CLIENT; i++)
	{
		if (player[i].getConnected())
		{
			player[i].incTimeout();
			// if communication timout
			if (player[i].getTimeout() > netNS::MAX_ERRORS)
			{
				player[i].setActive(false);
				ss << "***** Player " << i << " disconnected. *****";
				AnnDebug() << ss.str();
			}
		}
	}
}

void NetworkServer::doClientCommunication()
{
	int playN;
	int size;
	prepareDataForClient();
	for (int i=0; i<MAX_CLIENT; i++)
	{
		size = sizeof(toServerData);
		if(net.readData((char*) &toServerData, size, remoteIP, port) == netNS::NET_OK)
		{
					AnnDebug() << "Got " << size << " bytes from the network";
			if(size > 0)
			{
				/*AnnDebug() << "there are things here...";
				//AnnDebug() << (char*) &toServerData;
				AnnDebug() << "player n : " << toServerData.playerN;
				AnnDebug() << "x " << toServerData.x;
				AnnDebug() << "y " << toServerData.y;
				AnnDebug() << "z " << toServerData.z;*/
				playN = toServerData.playerN;
				if (playN == 255)
				{
					clientWantToJoin();
				}
				else
				{
					AnnDebug() << "got this : " << toServerData.ClientPaddlePos;
					distantPosition = toServerData.ClientPaddlePos;
					if (player[playN].getConnected())
					{
						if (player[playN].getActive());
							//player[playN].setButtons(toServerData.buttons);
						size = sizeof(toClientData);
						// send player the latest game data
						net.sendData((char*) &toClientData, size, player[i].getNetIP(), port);
						player[playN].setTimeout(0);
						player[playN].setCommWarnings(0);
					}
				}
			}
		}
		else    // No more incomming data ? break !!
		{
			break;
		}
	}
}

void NetworkServer::prepareDataForClient()
{
	/*for (int i=0; i<MAX_CLIENT; i++)
	{
		toClientData.player[i].playerData = player[i].getNetData();
	}*/

	//toClientDafta.puckPosition = AnnVect3(5,5,5);
	//toClientData.serverPaddlePos = AnnVect3(10, 10, 10);
	toClientData.postition = localPosiion;
	toClientData.PuckPos = referencePuckPosiion;
}

//========================================================================
// Client is requesting to join game
//========================================================================

void NetworkServer::clientWantToJoin()
{
	std::stringstream ss;
	int size;
	int status;
	connectResponse.number = 255;
	if (playerCount == 0)
	{
		roundOver = true; // this needs to reset the game states !! I don't know how :/
		// score system goes here (TODO)
	}
	AnnDebug() << "Player requesting to join.";
	// find available player position to use
	for(int i=0; i<MAX_CLIENT; i++) // search all player position
	{
		if (player[i].getConnected() == false) // if this position available
		{
			player[i].setConnected(true);
			player[i].setTimeout(0);
			player[i].setCommWarnings(0);
			player[i].setNetIP(remoteIP); // save player's IP
			player[i].setCommErrors(0); // clear old errors
			// send SERVER_ID adn player number to client
			strcpy_s(connectResponse.response, netNS::SERVER_ID);
			connectResponse.number = (UCHAR)i;
			size = sizeof(connectResponse);
			status = net.sendData((char*) &connectResponse, size, remoteIP, port);
			if (status == netNS::NET_ERROR)
			{
				AnnDebug() << net.getError(status); // display error
				return;
			}
			toServerData.playerN = i; // clear join request from
									 //  input buffer
			ss << "Connected player as number: " << i;
			AnnDebug() << ss.str(); // found available player
			return;
		}
	}
	// send SERVER_FULL to client
	strcpy_s(connectResponse.response, netNS::SERVER_FULL);
	size = sizeof(connectResponse);
	status = net.sendData((char*)&connectResponse, size, remoteIP, port);
	AnnDebug() << "server full.";
}

void NetworkServer::update()
{
	countDownTimer = COUNT_DOWN;
    countDownOn = true;
    roundOver = false;

	// set the state to indicate new round
    toClientData.gameState |= ROUND_START_BIT;

	float frameTime = AnnEngine::Instance()->getTimeFromStartUp();
	communicate(frameTime);
}

void NetworkServer::setRefPuckPosition(AnnVect3 position)
{
	referencePuckPosiion = position;
}

<commit_msg>remove server side useless logging<commit_after>#include "stdafx.h"
#include "NetworkServer.hpp"

NetworkWorker* NetworkWorker::singleton = nullptr;
NetworkWorker::NetworkWorker()
{
	if(singleton) exit(-1);
	singleton = this;
}

AnnVect3 NetworkWorker::getDistantPosition()
{
	return distantPosition;
}

void NetworkWorker::setLocalPositon(AnnVect3 position)
{
	localPosiion = position;
}

NetworkServer::NetworkServer() : NetworkWorker(),
	port(ANVPORT)
{
	//Singleton check

	myType = SERVER;

}

NetworkWorker* NetworkWorker::getSingleton()
{
	return singleton;
}

workerType NetworkWorker::getType()
{
	return myType;
}

int NetworkServer::initialize(int port)
{
	std::stringstream ss;
	if(port < netNS::MIN_PORT)
	{
		AnnDebug() << "Invalid port number";
		return netNS::NET_ERROR;
	}
	// ------ init network stuff -------
	error = net.createServer(port, netNS::UDP);
	if(error != netNS::NET_OK)
	{
		AnnDebug() << net.getError(error);
		return netNS::NET_ERROR;
	}

	for (int i=0; i<MAX_CLIENT; i++)
	{
		player[i].setConnected(false);
		player[i].setActive(false);
	}

	AnnDebug() << "---- Server ----";
	net.getLocalIP(localIP);
	ss << "Server IP: " << localIP;
	AnnDebug() << ss.str();
	ss.str("");
	ss << "Port: " << port;
	AnnDebug() << ss.str();
	return netNS::NET_OK;
}

// --- Do network communications ---
void NetworkServer::communicate(float frameTime)
{
	// communicate with client
	doClientCommunication();
	// Calculate elapsed time for network communications
	netTime += frameTime;
	if(netTime < netNS::NET_TIMER)
		return;

	netTime -= netNS::NET_TIMER;
	// check for inactive clients, called every NET_TIMER seconds
	checkNetworkTimeout();
}

// --- Check for network timeout ---

void NetworkServer::checkNetworkTimeout()
{
	std::stringstream ss;
	for (int i=0; i<MAX_CLIENT; i++)
	{
		if (player[i].getConnected())
		{
			player[i].incTimeout();
			// if communication timout
			if (player[i].getTimeout() > netNS::MAX_ERRORS)
			{
				player[i].setActive(false);
				ss << "***** Player " << i << " disconnected. *****";
				AnnDebug() << ss.str();
			}
		}
	}
}

void NetworkServer::doClientCommunication()
{
	int playN;
	int size;
	prepareDataForClient();
	for (int i=0; i<MAX_CLIENT; i++)
	{
		size = sizeof(toServerData);
		if(net.readData((char*) &toServerData, size, remoteIP, port) == netNS::NET_OK)
		{
			//AnnDebug() << "Got " << size << " bytes from the network";
			if(size > 0)
			{
				/*AnnDebug() << "there are things here...";
				//AnnDebug() << (char*) &toServerData;
				AnnDebug() << "player n : " << toServerData.playerN;
				AnnDebug() << "x " << toServerData.x;
				AnnDebug() << "y " << toServerData.y;
				AnnDebug() << "z " << toServerData.z;*/
				playN = toServerData.playerN;
				if (playN == 255)
				{
					clientWantToJoin();
				}
				else
				{
					//AnnDebug() << "got this : " << toServerData.ClientPaddlePos;
					distantPosition = toServerData.ClientPaddlePos;
					if (player[playN].getConnected())
					{
						if (player[playN].getActive());
							//player[playN].setButtons(toServerData.buttons);
						size = sizeof(toClientData);
						// send player the latest game data
						net.sendData((char*) &toClientData, size, player[i].getNetIP(), port);
						player[playN].setTimeout(0);
						player[playN].setCommWarnings(0);
					}
				}
			}
		}
		else    // No more incomming data ? break !!
		{
			break;
		}
	}
}

void NetworkServer::prepareDataForClient()
{
	/*for (int i=0; i<MAX_CLIENT; i++)
	{
		toClientData.player[i].playerData = player[i].getNetData();
	}*/

	//toClientDafta.puckPosition = AnnVect3(5,5,5);
	//toClientData.serverPaddlePos = AnnVect3(10, 10, 10);
	toClientData.postition = localPosiion;
	toClientData.PuckPos = referencePuckPosiion;
}

//========================================================================
// Client is requesting to join game
//========================================================================

void NetworkServer::clientWantToJoin()
{
	std::stringstream ss;
	int size;
	int status;
	connectResponse.number = 255;
	if (playerCount == 0)
	{
		roundOver = true; // this needs to reset the game states !! I don't know how :/
		// score system goes here (TODO)
	}
	AnnDebug() << "Player requesting to join.";
	// find available player position to use
	for(int i=0; i<MAX_CLIENT; i++) // search all player position
	{
		if (player[i].getConnected() == false) // if this position available
		{
			player[i].setConnected(true);
			player[i].setTimeout(0);
			player[i].setCommWarnings(0);
			player[i].setNetIP(remoteIP); // save player's IP
			player[i].setCommErrors(0); // clear old errors
			// send SERVER_ID adn player number to client
			strcpy_s(connectResponse.response, netNS::SERVER_ID);
			connectResponse.number = (UCHAR)i;
			size = sizeof(connectResponse);
			status = net.sendData((char*) &connectResponse, size, remoteIP, port);
			if (status == netNS::NET_ERROR)
			{
				AnnDebug() << net.getError(status); // display error
				return;
			}
			toServerData.playerN = i; // clear join request from
									 //  input buffer
			ss << "Connected player as number: " << i;
			AnnDebug() << ss.str(); // found available player
			return;
		}
	}
	// send SERVER_FULL to client
	strcpy_s(connectResponse.response, netNS::SERVER_FULL);
	size = sizeof(connectResponse);
	status = net.sendData((char*)&connectResponse, size, remoteIP, port);
	AnnDebug() << "server full.";
}

void NetworkServer::update()
{
	countDownTimer = COUNT_DOWN;
    countDownOn = true;
    roundOver = false;

	// set the state to indicate new round
    toClientData.gameState |= ROUND_START_BIT;

	float frameTime = AnnEngine::Instance()->getTimeFromStartUp();
	communicate(frameTime);
}

void NetworkServer::setRefPuckPosition(AnnVect3 position)
{
	referencePuckPosiion = position;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: documentcloser.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2006-02-09 13:58:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_UTIL_XCLOSEBROADCASTER_HPP_
#include <com/sun/star/util/XCloseBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
#include <com/sun/star/util/XCloseable.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_DOUBLEINITIALIZATIONEXCEPTION_HPP_
#include <com/sun/star/frame/DoubleInitializationException.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_DOUBLEINITIALIZATIONEXCEPTION_HPP_
#include <com/sun/star/frame/DoubleInitializationException.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XVCLWINDOWPEER_HPP_
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#endif

#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <vcl/dialog.hxx>
#include <tools/link.hxx>
#include <toolkit/helper/vclunohelper.hxx>

#include "documentcloser.hxx"

using namespace ::com::sun::star;

// ====================================================================
// MainThreadFrameCloserRequest
// ====================================================================

class MainThreadFrameCloserRequest
{
    uno::Reference< frame::XFrame > m_xFrame;

    public:
        MainThreadFrameCloserRequest( const uno::Reference< frame::XFrame >& xFrame )
        : m_xFrame( xFrame )
        {}

        DECL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest* );

        static void Start( MainThreadFrameCloserRequest* pRequest );
};

// --------------------------------------------------------
void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest* pMTRequest )
{
    if ( pMTRequest )
    {
        if ( Application::GetMainThreadIdentifier() == osl_getThreadIdentifier( NULL ) )
        {
            // this is the main thread
            worker( NULL, pMTRequest );
        }
        else
            Application::PostUserEvent( STATIC_LINK( NULL, MainThreadFrameCloserRequest, worker ), pMTRequest );
    }
}

// --------------------------------------------------------
IMPL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest*, pMTRequest )
{
    if ( pMTRequest )
    {
        if ( pMTRequest->m_xFrame.is() )
        {
            // this is the main thread, the solar mutex must be locked
            ::vos::OGuard aGuard( Application::GetSolarMutex() );

            try
            {
                uno::Reference< awt::XWindow > xWindow = pMTRequest->m_xFrame->getContainerWindow();
                uno::Reference< awt::XVclWindowPeer > xWinPeer( xWindow, uno::UNO_QUERY_THROW );

                xWindow->setVisible( sal_False );

                // reparent the window
                xWinPeer->setProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginParent" ) ),
                                        uno::makeAny( (sal_Int64) 0 ) );

                Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                if ( pWindow )
                    Dialog::EndAllDialogs( pWindow );
            }
            catch( uno::Exception& )
            {
                // ignore all the errors
            }

            try
            {
                uno::Reference< util::XCloseable > xCloseable( pMTRequest->m_xFrame, uno::UNO_QUERY_THROW );
                xCloseable->close( sal_True );
            }
            catch( uno::Exception& )
            {
                // ignore all the errors
            }
        }

        delete pMTRequest;
    }

    return 0;
}

// ====================================================================
// ODocumentCloser
// ====================================================================

// --------------------------------------------------------
ODocumentCloser::ODocumentCloser( const uno::Reference< uno::XComponentContext >& xContext )
: m_xContext( xContext )
, m_pListenersContainer( NULL )
, m_bDisposed( sal_False )
, m_bInitialized( sal_False )
{
}

// --------------------------------------------------------
ODocumentCloser::~ODocumentCloser()
{
    if ( m_pListenersContainer )
    {
        delete m_pListenersContainer;
        m_pListenersContainer = NULL;
    }
}

// XComponent
// --------------------------------------------------------
void SAL_CALL ODocumentCloser::dispose()
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if ( m_bDisposed )
        throw lang::DisposedException();

       lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
    if ( m_pListenersContainer )
        m_pListenersContainer->disposeAndClear( aSource );

    // TODO: trigger a main thread execution to close the frame
    if ( m_xFrame.is() )
    {
        // the created object will be deleted after thread execution
        MainThreadFrameCloserRequest* pCloser = new MainThreadFrameCloserRequest( m_xFrame );
        MainThreadFrameCloserRequest::Start( pCloser );
    }

    m_bDisposed = sal_True;
}

// --------------------------------------------------------
void SAL_CALL ODocumentCloser::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_pListenersContainer )
        m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );

    m_pListenersContainer->addInterface( xListener );
}

// --------------------------------------------------------
void SAL_CALL ODocumentCloser::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_pListenersContainer )
        m_pListenersContainer->removeInterface( xListener );
}

// XInitialization
// --------------------------------------------------------
void SAL_CALL ODocumentCloser::initialize( const uno::Sequence< uno::Any >& aArguments )
    throw (uno::Exception, uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bInitialized )
        throw frame::DoubleInitializationException();

    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_refCount )
        throw uno::RuntimeException(); // the object must be refcounted already!

    sal_Int32 nLen = aArguments.getLength();
    if ( nLen != 1 )
        throw lang::IllegalArgumentException(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ),
                        uno::Reference< uno::XInterface >(),
                        0 );

    if ( !( aArguments[0] >>= m_xFrame ) || !m_xFrame.is() )
        throw lang::IllegalArgumentException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ),
                uno::Reference< uno::XInterface >(),
                0 );

    m_bInitialized = sal_True;
}

// XServiceInfo
// --------------------------------------------------------
::rtl::OUString SAL_CALL ODocumentCloser::getImplementationName(  )
    throw (uno::RuntimeException)
{
    return impl_staticGetImplementationName();
}

// --------------------------------------------------------
::sal_Bool SAL_CALL ODocumentCloser::supportsService( const ::rtl::OUString& ServiceName )
    throw (uno::RuntimeException)
{
    uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();

    for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
        if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
            return sal_True;

    return sal_False;
}

// --------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::getSupportedServiceNames()
    throw (uno::RuntimeException)
{
    return impl_staticGetSupportedServiceNames();
}

// Static methods
// --------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::impl_staticGetSupportedServiceNames()
{
    const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.DocumentCloser" ) );
    return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
}

// --------------------------------------------------------
::rtl::OUString SAL_CALL ODocumentCloser::impl_staticGetImplementationName()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.DocumentCloser" ) );
}

// --------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL ODocumentCloser::impl_staticCreateSelfInstance(
                                const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
{
    uno::Reference< uno::XComponentContext > xContext;
    uno::Reference< beans::XPropertySet > xPropSet( xServiceManager, uno::UNO_QUERY );
    if ( xPropSet.is() )
        xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;

    if ( !xContext.is() )
    {
        throw uno::RuntimeException(
            rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain component context from service manager!" ) ),
            uno::Reference< uno::XInterface >() );
    }

    return static_cast< cppu::OWeakObject * >( new ODocumentCloser( xContext ) );
}

<commit_msg>INTEGRATION: CWS warnings01 (1.2.48); FILE MERGED 2006/04/20 14:51:15 sb 1.2.48.1: #i53898# Made code compile and/or warning-free again after resync to SRC680m162.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: documentcloser.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 21:09:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_UTIL_XCLOSEBROADCASTER_HPP_
#include <com/sun/star/util/XCloseBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_
#include <com/sun/star/util/XCloseable.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_DOUBLEINITIALIZATIONEXCEPTION_HPP_
#include <com/sun/star/frame/DoubleInitializationException.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_DOUBLEINITIALIZATIONEXCEPTION_HPP_
#include <com/sun/star/frame/DoubleInitializationException.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XVCLWINDOWPEER_HPP_
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#endif

#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <vcl/dialog.hxx>
#include <tools/link.hxx>
#include <toolkit/helper/vclunohelper.hxx>

#include "documentcloser.hxx"

using namespace ::com::sun::star;

// ====================================================================
// MainThreadFrameCloserRequest
// ====================================================================

class MainThreadFrameCloserRequest
{
    uno::Reference< frame::XFrame > m_xFrame;

    public:
        MainThreadFrameCloserRequest( const uno::Reference< frame::XFrame >& xFrame )
        : m_xFrame( xFrame )
        {}

        DECL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest* );

        static void Start( MainThreadFrameCloserRequest* pRequest );
};

// --------------------------------------------------------
void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest* pMTRequest )
{
    if ( pMTRequest )
    {
        if ( Application::GetMainThreadIdentifier() == osl_getThreadIdentifier( NULL ) )
        {
            // this is the main thread
            worker( NULL, pMTRequest );
        }
        else
            Application::PostUserEvent( STATIC_LINK( NULL, MainThreadFrameCloserRequest, worker ), pMTRequest );
    }
}

// --------------------------------------------------------
IMPL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest*, pMTRequest )
{
    (void) pThis; // unused
    if ( pMTRequest )
    {
        if ( pMTRequest->m_xFrame.is() )
        {
            // this is the main thread, the solar mutex must be locked
            ::vos::OGuard aGuard( Application::GetSolarMutex() );

            try
            {
                uno::Reference< awt::XWindow > xWindow = pMTRequest->m_xFrame->getContainerWindow();
                uno::Reference< awt::XVclWindowPeer > xWinPeer( xWindow, uno::UNO_QUERY_THROW );

                xWindow->setVisible( sal_False );

                // reparent the window
                xWinPeer->setProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginParent" ) ),
                                        uno::makeAny( (sal_Int64) 0 ) );

                Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                if ( pWindow )
                    Dialog::EndAllDialogs( pWindow );
            }
            catch( uno::Exception& )
            {
                // ignore all the errors
            }

            try
            {
                uno::Reference< util::XCloseable > xCloseable( pMTRequest->m_xFrame, uno::UNO_QUERY_THROW );
                xCloseable->close( sal_True );
            }
            catch( uno::Exception& )
            {
                // ignore all the errors
            }
        }

        delete pMTRequest;
    }

    return 0;
}

// ====================================================================
// ODocumentCloser
// ====================================================================

// --------------------------------------------------------
ODocumentCloser::ODocumentCloser( const uno::Reference< uno::XComponentContext >& xContext )
: m_xContext( xContext )
, m_pListenersContainer( NULL )
, m_bDisposed( sal_False )
, m_bInitialized( sal_False )
{
}

// --------------------------------------------------------
ODocumentCloser::~ODocumentCloser()
{
    if ( m_pListenersContainer )
    {
        delete m_pListenersContainer;
        m_pListenersContainer = NULL;
    }
}

// XComponent
// --------------------------------------------------------
void SAL_CALL ODocumentCloser::dispose()
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    if ( m_bDisposed )
        throw lang::DisposedException();

       lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
    if ( m_pListenersContainer )
        m_pListenersContainer->disposeAndClear( aSource );

    // TODO: trigger a main thread execution to close the frame
    if ( m_xFrame.is() )
    {
        // the created object will be deleted after thread execution
        MainThreadFrameCloserRequest* pCloser = new MainThreadFrameCloserRequest( m_xFrame );
        MainThreadFrameCloserRequest::Start( pCloser );
    }

    m_bDisposed = sal_True;
}

// --------------------------------------------------------
void SAL_CALL ODocumentCloser::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_pListenersContainer )
        m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );

    m_pListenersContainer->addInterface( xListener );
}

// --------------------------------------------------------
void SAL_CALL ODocumentCloser::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_pListenersContainer )
        m_pListenersContainer->removeInterface( xListener );
}

// XInitialization
// --------------------------------------------------------
void SAL_CALL ODocumentCloser::initialize( const uno::Sequence< uno::Any >& aArguments )
    throw (uno::Exception, uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bInitialized )
        throw frame::DoubleInitializationException();

    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_refCount )
        throw uno::RuntimeException(); // the object must be refcounted already!

    sal_Int32 nLen = aArguments.getLength();
    if ( nLen != 1 )
        throw lang::IllegalArgumentException(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ),
                        uno::Reference< uno::XInterface >(),
                        0 );

    if ( !( aArguments[0] >>= m_xFrame ) || !m_xFrame.is() )
        throw lang::IllegalArgumentException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ),
                uno::Reference< uno::XInterface >(),
                0 );

    m_bInitialized = sal_True;
}

// XServiceInfo
// --------------------------------------------------------
::rtl::OUString SAL_CALL ODocumentCloser::getImplementationName(  )
    throw (uno::RuntimeException)
{
    return impl_staticGetImplementationName();
}

// --------------------------------------------------------
::sal_Bool SAL_CALL ODocumentCloser::supportsService( const ::rtl::OUString& ServiceName )
    throw (uno::RuntimeException)
{
    uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();

    for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
        if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
            return sal_True;

    return sal_False;
}

// --------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::getSupportedServiceNames()
    throw (uno::RuntimeException)
{
    return impl_staticGetSupportedServiceNames();
}

// Static methods
// --------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::impl_staticGetSupportedServiceNames()
{
    const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.DocumentCloser" ) );
    return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
}

// --------------------------------------------------------
::rtl::OUString SAL_CALL ODocumentCloser::impl_staticGetImplementationName()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.DocumentCloser" ) );
}

// --------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL ODocumentCloser::impl_staticCreateSelfInstance(
                                const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
{
    uno::Reference< uno::XComponentContext > xContext;
    uno::Reference< beans::XPropertySet > xPropSet( xServiceManager, uno::UNO_QUERY );
    if ( xPropSet.is() )
        xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;

    if ( !xContext.is() )
    {
        throw uno::RuntimeException(
            rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain component context from service manager!" ) ),
            uno::Reference< uno::XInterface >() );
    }

    return static_cast< cppu::OWeakObject * >( new ODocumentCloser( xContext ) );
}

<|endoftext|>


<commit_before>/*

  First and second derivatives of thermal functions with respect to y^2.

  The Bessel representation is differentiated analytically and numerically.

*/

#include <derivatives.h>
#include <zeta.h>
#include <thermal_funcs.h>

#include <gsl/gsl_sf.h>
#include <gsl/gsl_deriv.h>
#include <gsl/gsl_errno.h>
#include <stdexcept>
#include <algorithm>

// First derivatives of thermal functions with respect to y^2 at y^2 -> 0.
// Found in Mathematica:

// -Sum[1/n^2*Limit[D[xsq*BesselK[2,Sqrt[xsq]*n],xsq],xsq->0],{n,1,Infinity}]
// -Sum[(-1)^n/n^2*Limit[D[xsq*BesselK[2, Sqrt[xsq]*n], xsq], xsq -> 0], {n, 1, Infinity}]

const double D1_J_B_0 = pow(M_PI, 2) / 12.;
const double D1_J_F_0 = -pow(M_PI, 2) / 24.;
const double INF = 1E10;

// Bessel function representation of derivatives with respect to y^2.

double K1(cdouble x, bool fast = false) {
  /**
      @returns K1 Bessel function.
      Utilize fact that

      to define K1 for imaginary arguments.
  */
  gsl_set_error_handler_off();  // Default handler aborts

  if (real(x) != 0. && imag(x) != 0.) {
    #ifdef THROW
      throw std::invalid_argument("K1 only implemented for x real or imaginary");
    #endif
  } else  if (std::abs(x) == 0.) {
    #ifdef THROW
      throw std::invalid_argument("K1 diverges for |x| = 0");
    #endif
  } else if (real(x) != 0.) {
    return gsl_sf_bessel_Kn(1, real(x));
  } else if (imag(x) != 0.) {
      return -0.5 * M_PI * gsl_sf_bessel_Yn(1, imag(x));
  }
}

double K0(cdouble x, bool fast = false) {
  /**
      @returns K0 Bessel function.
      Utilize fact that

      to define K0 for imaginary arguments.
  */
  gsl_set_error_handler_off();  // Default handler aborts

  if (real(x) != 0. && imag(x) != 0.) {
    #ifdef THROW
      throw std::invalid_argument("K0 only implemented for x real or imaginary");
    #endif
  } else  if (std::abs(x) == 0.) {
    #ifdef THROW
      throw std::invalid_argument("K0 diverges for |x| = 0");
    #endif
  } else if (real(x) != 0.) {
    return gsl_sf_bessel_Kn(0, real(x));
  } else if (imag(x) != 0.) {
      return -0.5 * M_PI * gsl_sf_bessel_Yn(0, imag(x));
  }
}

double D1_bessel_sum(double y_squared, double abs_error, double rel_error,
                     int max_n, bool bosonic) {
  /**
      @returns First derivative thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */
  #ifdef THROW
    if (y_squared == 0.) {
      throw std::invalid_argument("y_squared == 0 invalid");
    }
  #endif

  const double sign = 2. * static_cast<double>(bosonic) - 1.;
  const cdouble y = sqrt(cdouble(y_squared));
  const double abs_y = std::abs(y);
  double factor = 0.5 * abs_y * sign;
  double sum = factor * K1(y);

  for (int n = 2; n <= max_n; n += 1) {
    const double n_double = static_cast<double>(n);
    factor *= sign * (n_double - 1.) / n_double;
    const double term = factor * K1(n_double * y);
    sum += term;

    #ifdef DEBUG
      printf("term_%d = %e and sum = %e\n", n, term, sum);
    #endif

    if (std::abs(term) < std::max(abs_error, rel_error * std::abs(sum))) {
      #ifdef DEBUG
        printf("number of terms in sum = %d\n", n);
      #endif
      break;
    } else if (std::isinf(sum)) {
      #ifdef THROW
        throw std::runtime_error("sum diverging");
      #endif
      break;
    }

    #ifdef DEBUG
    if (n == max_n) {
      printf("reached max number of terms in sum = %d\n", n);
    }
    #endif
  }

  return sum;
}

double D2_bessel_sum(double y_squared, double abs_error, double rel_error,
                     int max_n, bool bosonic) {
  //
  /**
      @returns Second derivative thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  #ifdef THROW
    if (y_squared == 0.) {
      throw std::invalid_argument("y_squared == 0 invalid");
    }
  #endif

  const double sign = 2. * static_cast<double>(bosonic) - 1.;
  const cdouble y = sqrt(cdouble(y_squared));
  double factor = -0.25 * sign;
  double sum = factor * K0(y);

  for (int n = 2; n <= max_n; n += 1) {
    const double n_double = static_cast<double>(n);
    factor *= sign;
    const double term = factor * K0(n_double * y);
    sum += term;

    #ifdef DEBUG
      printf("term_%d = %e and sum = %e\n", n, term, sum);
    #endif

    if (std::abs(term) < std::max(abs_error, rel_error * std::abs(sum))) {
      #ifdef DEBUG
        printf("number of terms in sum = %d\n", n);
      #endif
      break;
    } else if (std::isinf(sum)) {
      #ifdef THROW
        throw std::runtime_error("sum diverging");
      #endif
      break;
    }

    #ifdef DEBUG
    if (n == max_n) {
      printf("reached max number of terms in sum = %d\n", n);
    }
    #endif
  }

  return sum;
}

double D1_J_F_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns First derivative fermionic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    return D1_J_F_0;
  }
  return D1_bessel_sum(y_squared, abs_error, rel_error, max_n, false);
}

double D1_J_B_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns First derivative bosonic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    return D1_J_B_0;
  }
  return D1_bessel_sum(y_squared, abs_error, rel_error, max_n, true);
}

double D2_J_F_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns Second derivative fermionic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    #ifdef THROW
      throw std::runtime_error("second derivative diverges at 0.");
    #endif
    return INF;
  }
  return D2_bessel_sum(y_squared, abs_error, rel_error, max_n, false);
}

double D2_J_B_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns Second derivative bosonic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    #ifdef THROW
      throw std::runtime_error("second derivative diverges at 0.");
    #endif
    return INF;
  }
  return D2_bessel_sum(y_squared, abs_error, rel_error, max_n, true);
}

// Numerical derivatives of thermal functions with respect to y^2.

struct J_params {
  bool bosonic;
  double abs_error;
  double rel_error;
  int max_n;
};

double J_wrapper(double y_squared, void *p) {
  /**
     Wrapper for thermal functions with signature required by numerical
     differentiation.
  */
  const struct J_params *params = (struct J_params *)p;
  const bool bosonic = params->bosonic;
  const double abs_error = params->abs_error;
  const double rel_error = params->rel_error;
  const int max_n = params->max_n;

  if (bosonic) {
    return J_B_bessel(y_squared, abs_error, rel_error, max_n);
  } else {
    return J_F_bessel(y_squared, abs_error, rel_error, max_n);
  }
}

double D1_J_approx(double y_squared, double step, bool bosonic,
                   double abs_error, double rel_error, int max_n) {
  /**
     @returns Numerical derivative of thermal function.
  */
  gsl_function J;
  double derivative;
  double abs_err;

  J.function = &J_wrapper;
  struct J_params params = {bosonic, abs_error, rel_error, max_n};
  J.params = &params;

  gsl_deriv_central(&J, y_squared, step, &derivative, &abs_err);

  return derivative;
}

struct D_params {
  double step;
  bool bosonic;
  double abs_error;
  double rel_error;
  int max_n;
};

double D1_J_wrapper(double y_squared, void *p) {
  /**
     Wrapper for first derivative of thermal functions with signature required
     by numerical differentiation.
  */
  const struct D_params *params = (struct D_params *)p;
  const double step = params->step;
  const bool bosonic = params->bosonic;
  const double abs_error = params->abs_error;
  const double rel_error = params->rel_error;
  const int max_n = params->max_n;
  return D1_J_approx(y_squared, step, bosonic, abs_error, rel_error, max_n);
}

double D2_J_approx(double y_squared, double step, bool bosonic,
                   double abs_error, double rel_error, int max_n) {
  /**
     @returns Numerical second derivative of thermal function.
  */
  gsl_function D1_J;
  double derivative;
  double abs_err;

  D1_J.function = &D1_J_wrapper;
  struct D_params params = {step, bosonic, abs_error, rel_error, max_n};
  D1_J.params = &params;

  gsl_deriv_central(&D1_J, y_squared, step, &derivative, &abs_err);

  return derivative;
}

double D1_J_B_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical derivative of bosonic thermal function.
  */
  return D1_J_approx(y_squared, step, true, abs_error, rel_error, max_n);
}

double D1_J_F_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical derivative of fermionic thermal function.
  */
  return D1_J_approx(y_squared, step, false, abs_error, rel_error, max_n);
}

double D2_J_B_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical second derivative of bosonic thermal function.
  */
  return D2_J_approx(y_squared, step, true, abs_error, rel_error, max_n);
}

double D2_J_F_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical second derivative of fermionic thermal function.
  */
  return D2_J_approx(y_squared, step, false, abs_error, rel_error, max_n);
}
<commit_msg>Removed unused argument<commit_after>/*

  First and second derivatives of thermal functions with respect to y^2.

  The Bessel representation is differentiated analytically and numerically.

*/

#include <derivatives.h>
#include <zeta.h>
#include <thermal_funcs.h>

#include <gsl/gsl_sf.h>
#include <gsl/gsl_deriv.h>
#include <gsl/gsl_errno.h>
#include <stdexcept>
#include <algorithm>

// First derivatives of thermal functions with respect to y^2 at y^2 -> 0.
// Found in Mathematica:

// -Sum[1/n^2*Limit[D[xsq*BesselK[2,Sqrt[xsq]*n],xsq],xsq->0],{n,1,Infinity}]
// -Sum[(-1)^n/n^2*Limit[D[xsq*BesselK[2, Sqrt[xsq]*n], xsq], xsq -> 0], {n, 1, Infinity}]

const double D1_J_B_0 = pow(M_PI, 2) / 12.;
const double D1_J_F_0 = -pow(M_PI, 2) / 24.;
const double INF = 1E10;

// Bessel function representation of derivatives with respect to y^2.

double K1(cdouble x) {
  /**
      @returns K1 Bessel function.
      Utilize fact that

      to define K1 for imaginary arguments.
  */
  gsl_set_error_handler_off();  // Default handler aborts

  if (real(x) != 0. && imag(x) != 0.) {
    #ifdef THROW
      throw std::invalid_argument("K1 only implemented for x real or imaginary");
    #endif
  } else  if (std::abs(x) == 0.) {
    #ifdef THROW
      throw std::invalid_argument("K1 diverges for |x| = 0");
    #endif
  } else if (real(x) != 0.) {
    return gsl_sf_bessel_Kn(1, real(x));
  } else if (imag(x) != 0.) {
      return -0.5 * M_PI * gsl_sf_bessel_Yn(1, imag(x));
  }
}

double K0(cdouble x) {
  /**
      @returns K0 Bessel function.
      Utilize fact that

      to define K0 for imaginary arguments.
  */
  gsl_set_error_handler_off();  // Default handler aborts

  if (real(x) != 0. && imag(x) != 0.) {
    #ifdef THROW
      throw std::invalid_argument("K0 only implemented for x real or imaginary");
    #endif
  } else  if (std::abs(x) == 0.) {
    #ifdef THROW
      throw std::invalid_argument("K0 diverges for |x| = 0");
    #endif
  } else if (real(x) != 0.) {
    return gsl_sf_bessel_Kn(0, real(x));
  } else if (imag(x) != 0.) {
      return -0.5 * M_PI * gsl_sf_bessel_Yn(0, imag(x));
  }
}

double D1_bessel_sum(double y_squared, double abs_error, double rel_error,
                     int max_n, bool bosonic) {
  /**
      @returns First derivative thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */
  #ifdef THROW
    if (y_squared == 0.) {
      throw std::invalid_argument("y_squared == 0 invalid");
    }
  #endif

  const double sign = 2. * static_cast<double>(bosonic) - 1.;
  const cdouble y = sqrt(cdouble(y_squared));
  const double abs_y = std::abs(y);
  double factor = 0.5 * abs_y * sign;
  double sum = factor * K1(y);

  for (int n = 2; n <= max_n; n += 1) {
    const double n_double = static_cast<double>(n);
    factor *= sign * (n_double - 1.) / n_double;
    const double term = factor * K1(n_double * y);
    sum += term;

    #ifdef DEBUG
      printf("term_%d = %e and sum = %e\n", n, term, sum);
    #endif

    if (std::abs(term) < std::max(abs_error, rel_error * std::abs(sum))) {
      #ifdef DEBUG
        printf("number of terms in sum = %d\n", n);
      #endif
      break;
    } else if (std::isinf(sum)) {
      #ifdef THROW
        throw std::runtime_error("sum diverging");
      #endif
      break;
    }

    #ifdef DEBUG
    if (n == max_n) {
      printf("reached max number of terms in sum = %d\n", n);
    }
    #endif
  }

  return sum;
}

double D2_bessel_sum(double y_squared, double abs_error, double rel_error,
                     int max_n, bool bosonic) {
  //
  /**
      @returns Second derivative thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  #ifdef THROW
    if (y_squared == 0.) {
      throw std::invalid_argument("y_squared == 0 invalid");
    }
  #endif

  const double sign = 2. * static_cast<double>(bosonic) - 1.;
  const cdouble y = sqrt(cdouble(y_squared));
  double factor = -0.25 * sign;
  double sum = factor * K0(y);

  for (int n = 2; n <= max_n; n += 1) {
    const double n_double = static_cast<double>(n);
    factor *= sign;
    const double term = factor * K0(n_double * y);
    sum += term;

    #ifdef DEBUG
      printf("term_%d = %e and sum = %e\n", n, term, sum);
    #endif

    if (std::abs(term) < std::max(abs_error, rel_error * std::abs(sum))) {
      #ifdef DEBUG
        printf("number of terms in sum = %d\n", n);
      #endif
      break;
    } else if (std::isinf(sum)) {
      #ifdef THROW
        throw std::runtime_error("sum diverging");
      #endif
      break;
    }

    #ifdef DEBUG
    if (n == max_n) {
      printf("reached max number of terms in sum = %d\n", n);
    }
    #endif
  }

  return sum;
}

double D1_J_F_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns First derivative fermionic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    return D1_J_F_0;
  }
  return D1_bessel_sum(y_squared, abs_error, rel_error, max_n, false);
}

double D1_J_B_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns First derivative bosonic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    return D1_J_B_0;
  }
  return D1_bessel_sum(y_squared, abs_error, rel_error, max_n, true);
}

double D2_J_F_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns Second derivative fermionic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    #ifdef THROW
      throw std::runtime_error("second derivative diverges at 0.");
    #endif
    return INF;
  }
  return D2_bessel_sum(y_squared, abs_error, rel_error, max_n, false);
}

double D2_J_B_bessel(double y_squared, double abs_error, double rel_error,
                     int max_n) {
  /**
      @returns Second derivative bosonic thermal function with respect to y^2.
      Found by summing Bessel functions.

      @param y_squared Argment of thermal function
  */

  // If y_squared = 0, known limit returned.
  if (y_squared == 0.) {
    #ifdef THROW
      throw std::runtime_error("second derivative diverges at 0.");
    #endif
    return INF;
  }
  return D2_bessel_sum(y_squared, abs_error, rel_error, max_n, true);
}

// Numerical derivatives of thermal functions with respect to y^2.

struct J_params {
  bool bosonic;
  double abs_error;
  double rel_error;
  int max_n;
};

double J_wrapper(double y_squared, void *p) {
  /**
     Wrapper for thermal functions with signature required by numerical
     differentiation.
  */
  const struct J_params *params = (struct J_params *)p;
  const bool bosonic = params->bosonic;
  const double abs_error = params->abs_error;
  const double rel_error = params->rel_error;
  const int max_n = params->max_n;

  if (bosonic) {
    return J_B_bessel(y_squared, abs_error, rel_error, max_n);
  } else {
    return J_F_bessel(y_squared, abs_error, rel_error, max_n);
  }
}

double D1_J_approx(double y_squared, double step, bool bosonic,
                   double abs_error, double rel_error, int max_n) {
  /**
     @returns Numerical derivative of thermal function.
  */
  gsl_function J;
  double derivative;
  double abs_err;

  J.function = &J_wrapper;
  struct J_params params = {bosonic, abs_error, rel_error, max_n};
  J.params = &params;

  gsl_deriv_central(&J, y_squared, step, &derivative, &abs_err);

  return derivative;
}

struct D_params {
  double step;
  bool bosonic;
  double abs_error;
  double rel_error;
  int max_n;
};

double D1_J_wrapper(double y_squared, void *p) {
  /**
     Wrapper for first derivative of thermal functions with signature required
     by numerical differentiation.
  */
  const struct D_params *params = (struct D_params *)p;
  const double step = params->step;
  const bool bosonic = params->bosonic;
  const double abs_error = params->abs_error;
  const double rel_error = params->rel_error;
  const int max_n = params->max_n;
  return D1_J_approx(y_squared, step, bosonic, abs_error, rel_error, max_n);
}

double D2_J_approx(double y_squared, double step, bool bosonic,
                   double abs_error, double rel_error, int max_n) {
  /**
     @returns Numerical second derivative of thermal function.
  */
  gsl_function D1_J;
  double derivative;
  double abs_err;

  D1_J.function = &D1_J_wrapper;
  struct D_params params = {step, bosonic, abs_error, rel_error, max_n};
  D1_J.params = &params;

  gsl_deriv_central(&D1_J, y_squared, step, &derivative, &abs_err);

  return derivative;
}

double D1_J_B_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical derivative of bosonic thermal function.
  */
  return D1_J_approx(y_squared, step, true, abs_error, rel_error, max_n);
}

double D1_J_F_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical derivative of fermionic thermal function.
  */
  return D1_J_approx(y_squared, step, false, abs_error, rel_error, max_n);
}

double D2_J_B_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical second derivative of bosonic thermal function.
  */
  return D2_J_approx(y_squared, step, true, abs_error, rel_error, max_n);
}

double D2_J_F_approx(double y_squared, double step, double abs_error,
                     double rel_error, int max_n) {
  /**
     @returns Numerical second derivative of fermionic thermal function.
  */
  return D2_J_approx(y_squared, step, false, abs_error, rel_error, max_n);
}
<|endoftext|>