text:
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <imgui/imgui.h>
// #include "imgui/imgui_impl_glfw.h"
// #include "imgui/imgui_impl_opengl3.h"
// #include <boost/gil.hpp>
#include <Eigen/Dense>

#include <iostream>
#include <optional>
#include <algorithm>
#include <filesystem>
#include <ranges>

#include <config/data.hpp>
#include <config/type.hpp>
#include <config/gl.hpp>
#include <version/version.hpp>

#include <shader.hpp>
#include <program.hpp>
#include <uniform.hpp>

#include <bound.hpp>
#include <polygon.hpp>
#include <convex.hpp>
#include <canvas.hpp>

#include <model/canvasGen.hpp>
#include <model/canvasOp.hpp>

static void glfw_error_callback(int error, const char *description);
static void
framebuffer_size_callback(GLFWwindow *window, int width, int height);
static void processInput(GLFWwindow *window, const ImGuiIO &io);

static GLFWwindow *initWindow();
static ImGuiIO &initImGui(GLFWwindow *window);

namespace Work {

using namespace Config::Type;

int verticesNum, queryPolygonsNum;

Color3f pointColor(1.0f, 0.5f, 0.2f);
Color3f polygonColor(1.0f, 1.0f, 0.5f);
Color3f polygon1Color(1.0f, 0.5f, 0.5f);
Color3f polygon2Color(0.5f, 0.5f, 1.0f);

GLuint pointsVBO, pointsVAO;
Program pointProgram, canvasGenProgram;
UCanvasGen uCanvasGen;
Config::Type::SData mouseSData;
Config::Type::Offset2D mouse, mouseLast;
float pointSize = 10.0f;
int customColorLocation = -1;
Bound2D bound2D;

Polygon::Polygon p0, p1, p2;

static void inputPoints();
static void inputPolygons();
static void input();
static void workloadPoints();
static void workloadPolygons();
static void workload();

} // namespace Work

int main() {
    GLFWwindow *window = initWindow();
    ImGuiIO &io = initImGui(window);
    printGLVersion();
    logGlIsEnabled(GL_SCISSOR_TEST);

    // Our state
    bool show_demo_window = false;
    // bool show_another_window = false;
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);

    checkGlError(Work::input());

    // glEnable(GL_PROGRAM_POINT_SIZE);

    // Main loop
    while (!glfwWindowShouldClose(window)) {
        // Poll and handle events (inputs, window resize, etc.)
        // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to
        // tell if dear imgui wants to use your inputs.
        // - When io.WantCaptureMouse is true, do not dispatch mouse input data
        // to your main application.
        // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input
        // data to your main application. Generally you may always pass all
        // inputs to dear imgui, and hide them from your application based on
        // those two flags.
        glfwPollEvents();

        // Start the Dear ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // 1. Show the big demo window (Most of the sample code is in
        // ImGui::ShowDemoWindow()! You can browse its code to learn more about
        // Dear ImGui!).
        if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window);

        // 2. Show a simple window that we create ourselves. We use a Begin/End
        // pair to created a named window.
        {
            // static float f = 0.0f;
            // static int counter = 0;
            ImGui::Begin("Debug Info"); // Create a window called "Hello,
                                        // world!" and append into it.

            ImGui::Checkbox(
                "Demo Window", &show_demo_window); // Edit bools storing our
                                                   // window open/close state

            // ImGui::Checkbox("Another Window", &show_another_window);

            ImGui::SliderFloat(
                "Point size",
                &Work::pointSize,
                1.0f,
                10.0f); // Edit 1 float using a slider from 0.0f to 1.0f

            ImGui::ColorEdit3(
                "Point color",
                Work::pointColor.data()); // Edit 3 floats representing a color

            ImGui::ColorEdit3(
                "Polygon color",
                Work::polygonColor
                    .data()); // Edit 3 floats representing a color
            ImGui::ColorEdit3(
                "Polygon1 color",
                Work::polygon1Color
                    .data()); // Edit 3 floats representing a color
            ImGui::ColorEdit3(
                "Polygon2 color",
                Work::polygon2Color
                    .data()); // Edit 3 floats representing a color

            ImGui::ColorEdit3(
                "Clear color",
                (float *)&clear_color); // Edit 3 floats representing a color

            ImGui::Text(
                "Application average %.3f ms/frame (%.1f FPS)",
                1000.0f / ImGui::GetIO().Framerate,
                ImGui::GetIO().Framerate);
            ImGui::Text("glfwGetTime %.3f s", glfwGetTime());

            if (int mx = (int)io.MousePos.x, my = (int)io.MousePos.y;
                ImGui::IsMousePosValid() && !io.WantCaptureMouse && 0 <= mx
                && mx < Config::SCR_WIDTH && 0 <= my
                && my < Config::SCR_HEIGHT) {
                using namespace Work;
                mouse.x = mx;
                mouse.y = Config::SCR_HEIGHT - 1 - my;
                ImGui::Text("Mouse pos: (%d, %d)", mouse.x, mouse.y);
                ImGui::Text(
                    "[%4d%4d%4d]\n[%4d%4d%4d]\n[%4d%4d%4d]",
                    mouseSData.coeff(0, 0),
                    mouseSData.coeff(0, 1),
                    mouseSData.coeff(0, 2),
                    mouseSData.coeff(1, 0),
                    mouseSData.coeff(1, 1),
                    mouseSData.coeff(1, 2),
                    mouseSData.coeff(2, 0),
                    mouseSData.coeff(2, 1),
                    mouseSData.coeff(2, 2));
            } else {
                ImGui::Text("Mouse pos: <INVALID>");
            }
            ImGui::End();
        }

        // Rendering
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(
            clear_color.x * clear_color.w,
            clear_color.y * clear_color.w,
            clear_color.z * clear_color.w,
            clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);

        // IMPORTENT: Entrance to workload
        checkGlError(Work::workload());

        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

namespace Work {

static void workloadPoints() {
    static Canvas canvas;

    showGlError();

    // clang-format off
    static const int sData[3][3] = {
        {1, 1, 0},
        {2, 1, 0},
        {3, 1, 0},
    };
    // clang-format on

    uCanvasGen.useProgram();
    uCanvasGen.sendCustomColor(polygonColor.data()).setS(sData).sendS();
    showGlError();
    checkGlError(canvas.bind(0, Access::writeOnly));
    // draw convexs
    p0.draw();

    showGlError();

    pointProgram.use();
    glUniform3fv(customColorLocation, 1, pointColor.data());
    // draw points
    {
        glBindVertexArray(pointsVAO);
        glPointSize(pointSize);
        glDrawArrays(GL_POINTS, 0, verticesNum);
    }

    showGlError();

    if (mouse != mouseLast) {
        mouseSData = canvas.readS(mouse.x, mouse.y);
        mouseLast = mouse;
    }
}

static void workloadPolygons() {
    static Canvas result, blend1, blend2;
    showGlError();
    // clang-format off
    static const int sData1[3][3] = {
        {0, 0, 0},
        {0, 0, 0},
        {1, 1, 0},
    };
    static const int sData2[3][3] = {
        {0, 0, 0},
        {0, 0, 0},
        {2, 1, 0},
    };
    // clang-format on

    // canvas for blend1
    uCanvasGen.useProgram();
    uCanvasGen.sendCustomColor(polygon1Color.data()).setS(sData1).sendS();
    showGlError();
    checkGlError(blend1.bind(0, Access::writeOnly));
    p1.draw();
    showGlError();

    // canvas for blend2
    uCanvasGen.useProgram();
    uCanvasGen.sendCustomColor(polygon2Color.data()).setS(sData2).sendS();
    showGlError();
    checkGlError(blend2.bind(0, Access::writeOnly));
    p2.draw();
    showGlError();

    CanvasOp::blendPolygons(result, blend1, blend2);
    if (mouse != mouseLast) {
        mouseSData = result.readS(mouse.x, mouse.y);
        mouseLast = mouse;
    }
}

static void workload() {
    // workloadPoints();
    workloadPolygons();
}

static void inputPoints() {
    using namespace std::views;
    constexpr int MAX_VERT = 32;
    static Point points[MAX_VERT];

    FILE *in = fopen("data/select_points.txt", "r");

    // input points to be queried
    fscanf(in, "%d", &verticesNum);
    for (float x, y; auto &point : points | take(verticesNum)) {
        fscanf(in, "%f%f", &x, &y);
        point << x, y;
        bound2D.bounds[0].merge(x);
        bound2D.bounds[1].merge(y);
    }

    // input querying polygons, which are made convexs
    p0 = Polygon::Polygon::fromInput(in);
    bound2D.merge(p0.bound());

    bound2D.slack(Config::BOUND_SLACK);
    const real ratio = (real)std::min<double>(
        1.0 / (bound2D.bounds[0].length()) * (1.0 - (-1.0)),
        1.0 / (bound2D.bounds[1].length()) * (1.0 - (-1.0)));

    // scale all coordinates to [-1.0, 1.0]
    const auto &lerp = [&](Point &point) {
        for (int i = 0; i < 2; ++i) {
            point[i] = (point[i] - bound2D.bounds[i].lowerBound) * ratio - 1.0f;
        }
    };

    std::for_each_n(points, verticesNum, lerp);
    p0.adjustVertices(lerp).genVAO();

    glGenBuffers(1, &pointsVBO);
    glGenVertexArrays(1, &pointsVAO);
    glBindVertexArray(pointsVAO);

    glBindBuffer(GL_ARRAY_BUFFER, pointsVBO);
    glBufferData(
        GL_ARRAY_BUFFER, verticesNum * sizeof(Point), points, GL_STATIC_DRAW);
    // glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
    // GL_STATIC_DRAW);

    glVertexAttribPointer(
        0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(real), (void *)0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // You can unbind the VAO afterwards so other VAO calls won't accidentally
    // modify this VAO, but this rarely happens. Modifying other VAOs requires a
    // call to glBindVertexArray anyways so we generally don't unbind VAOs (nor
    // VBOs) when it's not directly necessary.
    glBindVertexArray(0);
}

static void inputPolygons() {
    FILE *in = fopen("data/select_polygons.txt", "r");
    p1 = Polygon::Polygon::fromInput(in);
    p2 = Polygon::Polygon::fromInput(in);
    bound2D.merge(p1.bound());
    bound2D.merge(p2.bound());
    bound2D.slack(Config::BOUND_SLACK);

    const real ratio = (real)std::min<double>(
        1.0 / (bound2D.bounds[0].length()) * (1.0 - (-1.0)),
        1.0 / (bound2D.bounds[1].length()) * (1.0 - (-1.0)));
    // scale all coordinates to [-1.0, 1.0]
    const auto &lerp = [&](Point &point) {
        for (int i = 0; i < 2; ++i) {
            point[i] = (point[i] - bound2D.bounds[i].lowerBound) * ratio - 1.0f;
        }
    };
    p1.adjustVertices(lerp).genVAO();
    p2.adjustVertices(lerp).genVAO();
}

static void input() {
    CanvasOp::fullScreenConvex.genVAO();

    // construct shader and program
    VertexShader pointVShader("shader/point.vert");
    FragmentShader pointFShader("shader/point.frag");
    pointProgram.init()
        .attachAndLink(pointVShader, pointFShader)
        .assertAvailable();

    VertexShader canvasGenVShader("shader/canvasGen.vert");
    FragmentShader canvasGenFShader("shader/canvasGen.frag");
    canvasGenProgram.init()
        .attachAndLink(canvasGenVShader, canvasGenFShader)
        .assertAvailable();

    // prepare to set color uniform
    customColorLocation = glGetUniformLocation(pointProgram, "customColor");
    uCanvasGen.setProgram(canvasGenProgram);

    // inputPoints();
    inputPolygons();
}

} // namespace Work

// process all input: query GLFW whether relevant keys are pressed/released this
// frame and react accordingly
// -----------------------------------------------------------------------------
static void processInput(GLFWwindow *window, const ImGuiIO &io) {
    if (!io.WantCaptureKeyboard) {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);
    }
}

// glfw: whenever the window size changed (by OS or user resize) this callback
// function executes
// -----------------------------------------------------------------------------
static void
framebuffer_size_callback(GLFWwindow *window, int width, int height) {
    // make sure the viewport matches the new window dimensions; note that width
    // and height will be significantly larger than specified on retina
    // displays.
    glViewport(0, 0, width, height);
}

static void glfw_error_callback(int error, const char *description) {
    fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}

static GLFWwindow *initWindow() {
    // glfw: initialize and configure
    // ------------------------------
    glfwSetErrorCallback(glfw_error_callback);
    if (!glfwInit()) return nullptr;
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    if constexpr (Config::ENABLE_MSAA) { glfwWindowHint(GLFW_SAMPLES, 4); }

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    // glfw window creation
    // --------------------
    GLFWwindow *window = glfwCreateWindow(
        Config::SCR_WIDTH, Config::SCR_HEIGHT, "OpenGL", NULL, NULL);
    if (window == NULL) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        // return -1;
        return nullptr;
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1); // Enable vsync
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "Failed to initialize GLAD" << std::endl;
        // return -1;
        return nullptr;
    }

    if constexpr (Config::ENABLE_MSAA) { logGlEnable(GL_MULTISAMPLE); }

    glViewport(0, 0, Config::SCR_WIDTH, Config::SCR_HEIGHT);

    return window;
}

static ImGuiIO &initImGui(GLFWwindow *window) {
    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO &io = ImGui::GetIO();

    // io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable
    // Keyboard Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; //
    // Enable Gamepad Controls

    // Setup Dear ImGui style
    ImGui::StyleColorsDark();
    // ImGui::StyleColorsClassic();

    // Setup Platform/Renderer backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 460");

    // Load Fonts
    // - If no fonts are loaded, dear imgui will use the default font. You can
    // also load multiple fonts and use ImGui::PushFont()/PopFont() to select
    // them.
    // - AddFontFromFileTTF() will return the ImFont* so you can store it if you
    // need to select the font among multiple.
    // - If the file cannot be loaded, the function will return NULL. Please
    // handle those errors in your application (e.g. use an assertion, or
    // display an error and quit).
    // - The fonts will be rasterized at a given size (w/ oversampling) and
    // stored into a texture when calling
    // ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame
    // below will call.
    // - Read 'docs/FONTS.md' for more instructions and details.
    // - Remember that in C/C++ if you want to include a backslash \ in a string
    // literal you need to write a double backslash \\ !

    {
        bool found = false;
        auto exists = [&io](const char *filename) {
            return std::filesystem::exists(filename)
                   && io.Fonts->AddFontFromFileTTF(filename, 18.0f) != nullptr;
        };
        using namespace std::views;
        for (auto filename :
             Config::Data::fontFamily | filter(exists) | take(1)) {
            found = true;
        }
        if (!found) io.Fonts->AddFontDefault();
    }

    return io;
}

max_stars_repo_name: Codesire-Deng/gsq

max_issues_repo_name: Codesire-Deng/gsq

max_forks_repo_name: Codesire-Deng/gsq


text:
#include <boost/range/counting_range.hpp>
#include <boost/range/algorithm_ext/push_back.hpp>
#include <boost/range.hpp>

#include <queue>
#include <stack>

#include "../parallel/tbb.h"
#include "../../def_debug_ws.h"

template<class T>
hera::ws::dnn::KDTree<T>::
KDTree(const Traits& traits, HandleContainer&& handles, double _wassersteinPower):
    traits_(traits), tree_(std::move(handles)), wassersteinPower(_wassersteinPower)
{ assert(wassersteinPower >= 1.0); init(); }

template<class T>
template<class Range>
hera::ws::dnn::KDTree<T>::
KDTree(const Traits& traits, const Range& range, double _wassersteinPower):
    traits_(traits), wassersteinPower(_wassersteinPower)
{
    assert( wassersteinPower >= 1.0);
    init(range);
}

template<class T>
template<class Range>
void
hera::ws::dnn::KDTree<T>::
init(const Range& range)
{
    size_t sz = std::distance(std::begin(range), std::end(range));
    tree_.reserve(sz);
    weights_.resize(sz, 0);
    subtree_weights_.resize(sz, 0);
    for (PointHandle h : range)
        tree_.push_back(h);
    init();
}

template<class T>
void
hera::ws::dnn::KDTree<T>::
init()
{
    if (tree_.empty())
        return;

#if defined(TBB)
    task_group g;
    g.run(OrderTree(tree_.begin(), tree_.end(), 0, traits()));
    g.wait();
#else
    OrderTree(tree_.begin(), tree_.end(), 0, traits()).serial();
#endif

    for (size_t i = 0; i < tree_.size(); ++i)
        indices_[tree_[i]] = i;
}

template<class T>
struct
hera::ws::dnn::KDTree<T>::OrderTree
{
                OrderTree(HCIterator b_, HCIterator e_, size_t i_, const Traits& traits_):
                    b(b_), e(e_), i(i_), traits(traits_)            {}

    void        operator()() const
    {
        if (e - b < 1000)
        {
            serial();
            return;
        }

        HCIterator m = b + (e - b)/2;
        CoordinateComparison cmp(i, traits);
        std::nth_element(b,m,e, cmp);
        size_t next_i = (i + 1) % traits.dimension();

        task_group g;
        if (b < m - 1)  g.run(OrderTree(b,   m, next_i, traits));
        if (e > m + 2)  g.run(OrderTree(m+1, e, next_i, traits));
        g.wait();
    }

    void        serial() const
    {
        std::queue<KDTreeNode> q;
        q.push(KDTreeNode(b,e,i));
        while (!q.empty())
        {
            HCIterator b, e; size_t i;
            std::tie(b,e,i) = q.front();
            q.pop();
            HCIterator m = b + (e - b)/2;

            CoordinateComparison cmp(i, traits);
            std::nth_element(b,m,e, cmp);
            size_t next_i = (i + 1) % traits.dimension();

            // Replace with a size condition instead?
            if (b < m - 1)  q.push(KDTreeNode(b,   m, next_i));
            if (e - m > 2)  q.push(KDTreeNode(m+1, e, next_i));
        }
    }

    HCIterator      b, e;
    size_t          i;
    const Traits&   traits;
};

template<class T>
template<class ResultsFunctor>
void
hera::ws::dnn::KDTree<T>::
search(PointHandle q, ResultsFunctor& rf) const
{
    typedef         typename HandleContainer::const_iterator        HCIterator;
    typedef         std::tuple<HCIterator, HCIterator, size_t>      KDTreeNode;

    if (tree_.empty())
        return;

    DistanceType    D  = std::numeric_limits<DistanceType>::max();

    // TODO: use tbb::scalable_allocator for the queue
    std::queue<KDTreeNode>  nodes;

    nodes.push(KDTreeNode(tree_.begin(), tree_.end(), 0));

    while (!nodes.empty())
    {
        HCIterator b, e; size_t i;
        std::tie(b,e,i) = nodes.front();
        nodes.pop();

        CoordinateComparison cmp(i, traits());
        i = (i + 1) % traits().dimension();

        HCIterator   m    = b + (e - b)/2;

        DistanceType dist = (wassersteinPower == 1.0) ?  traits().distance(q, *m) + weights_[m - tree_.begin()] : std::pow(traits().distance(q, *m), wassersteinPower) + weights_[m - tree_.begin()];

        D = rf(*m, dist);

        // we are really searching w.r.t L_\infty ball; could prune better with an L_2 ball
        Coordinate diff = cmp.diff(q, *m);     // diff returns signed distance

        DistanceType diffToWasserPower = (wassersteinPower == 1.0) ? diff : ((diff > 0 ? 1.0 : -1.0) * std::pow(fabs(diff), wassersteinPower));

        size_t       lm   = m + 1 + (e - (m+1))/2 - tree_.begin();
        if (e > m + 1 && diffToWasserPower - subtree_weights_[lm] >= -D) {
            nodes.push(KDTreeNode(m+1, e, i));
        }

        size_t       rm   = b + (m - b) / 2 - tree_.begin();
        if (b < m && diffToWasserPower + subtree_weights_[rm] <= D) {
            nodes.push(KDTreeNode(b,   m, i));
        }
    }
}

template<class T>
void
hera::ws::dnn::KDTree<T>::
adjust_weights(DistanceType delta)
{
    for(auto& w : weights_)
        w -= delta;

    for(auto& sw : subtree_weights_)
        sw -= delta;
}

template<class T>
void
hera::ws::dnn::KDTree<T>::
change_weight(PointHandle p, DistanceType w)
{
    size_t idx = indices_[p];

    if ( weights_[idx] == w ) {
        return;
    }

    bool weight_increases = ( weights_[idx] < w );
    weights_[idx] = w;

    typedef     std::tuple<HCIterator, HCIterator>      KDTreeNode;

    // find the path down the tree to this node
    // not an ideal strategy, but // it's not clear how to move up from the node in general
    std::stack<KDTreeNode>  s;
    s.push(KDTreeNode(tree_.begin(),tree_.end()));

    do
    {
        HCIterator b,e;
        std::tie(b,e) = s.top();

        size_t im = b + (e - b)/2 - tree_.begin();

        if (idx == im)
            break;
        else if (idx < im)
            s.push(KDTreeNode(b, tree_.begin() + im));
        else    // idx > im
            s.push(KDTreeNode(tree_.begin() + im + 1, e));
    } while(1);

    // update subtree_weights_ on the path to the root
    DistanceType min_w = w;
    while (!s.empty())
    {
        HCIterator b,e;
        std::tie(b,e) = s.top();
        HCIterator m  = b + (e - b)/2;
        size_t     im = m - tree_.begin();
        s.pop();

        // left and right children
        if (b < m)
        {
            size_t lm = b + (m - b)/2 - tree_.begin();
            if (subtree_weights_[lm] < min_w)
                min_w = subtree_weights_[lm];
        }

        if (e > m + 1)
        {
            size_t rm = m + 1 + (e - (m+1))/2 - tree_.begin();
            if (subtree_weights_[rm] < min_w)
                min_w = subtree_weights_[rm];
        }

        if (weights_[im] < min_w) {
            min_w = weights_[im];
        }

        if (weight_increases) {

            if (subtree_weights_[im] < min_w )   // increase weight
                subtree_weights_[im] = min_w;
            else
                break;

        } else {

            if (subtree_weights_[im] > min_w )   // decrease weight
                subtree_weights_[im] = min_w;
            else
                break;

        }
    }
}

template<class T>
typename hera::ws::dnn::KDTree<T>::HandleDistance
hera::ws::dnn::KDTree<T>::
find(PointHandle q) const
{
    hera::ws::dnn::NNRecord<HandleDistance> nn;
    search(q, nn);
    return nn.result;
}

template<class T>
typename hera::ws::dnn::KDTree<T>::Result
hera::ws::dnn::KDTree<T>::
findR(PointHandle q, DistanceType r) const
{
    hera::ws::dnn::rNNRecord<HandleDistance> rnn(r);
    search(q, rnn);
    std::sort(rnn.result.begin(), rnn.result.end());
    return rnn.result;
}

template<class T>
typename hera::ws::dnn::KDTree<T>::Result
hera::ws::dnn::KDTree<T>::
findK(PointHandle q, size_t k) const
{
    hera::ws::dnn::kNNRecord<HandleDistance> knn(k);
    search(q, knn);
    std::sort(knn.result.begin(), knn.result.end());
    return knn.result;
}

template<class T>
struct hera::ws::dnn::KDTree<T>::CoordinateComparison
{
                CoordinateComparison(size_t i, const Traits& traits):
                    i_(i), traits_(traits)                              {}

    bool        operator()(PointHandle p1, PointHandle p2) const        { return coordinate(p1) < coordinate(p2); }
    Coordinate  diff(PointHandle p1, PointHandle p2) const              { return coordinate(p1) - coordinate(p2); }

    Coordinate  coordinate(PointHandle p) const                         { return traits_.coordinate(p, i_); }
    size_t      axis() const                                            { return i_; }

    private:
        size_t          i_;
        const Traits&   traits_;
};

template<class T>
void
hera::ws::dnn::KDTree<T>::
printWeights(void)
{
#ifndef FOR_R_TDA
    std::cout << "weights_:" << std::endl;
    for(const auto ph : indices_) {
        std::cout << "idx = " << ph.second << ": (" << (ph.first)->at(0) << ", " << (ph.first)->at(1) << ") weight = " << weights_[ph.second] << std::endl;
    }
    std::cout << "subtree_weights_:" << std::endl;
    for(size_t idx = 0; idx < subtree_weights_.size(); ++idx) {
        std::cout << idx << " : " << subtree_weights_[idx] << std::endl;
    }
#endif
}

ext: hpp

max_stars_repo_name: gtauzin/giotto-learn


text:
// Boost test for Conan package
// Dmitriy Vetutnev, Odant, 2020

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_set.hpp>

#include <cstdlib>

int main(int, char**) {

    const auto sp = boost::make_shared<int>();
    boost::weak_ptr<int> wp = sp;
    boost::unordered_set<boost::weak_ptr<int>> set;
    set.insert(wp);

    return EXIT_SUCCESS;
}

ext: cpp

max_stars_repo_name: odant/conan-boost

max_issues_repo_name: odant/conan-boost

max_forks_repo_name: odant/conan-boost


text:
// -*- mode:c++; c-style:k&r; c-basic-offset:4; indent-tabs-mode: nil; -*-
// vi:set et cin sw=4 cino=>se0n0f0{0}0^0\:0=sl1g0hspst0+sc3C0/0(0u0U0w0m0:

#ifndef __TILE_HPP__
#define __TILE_HPP__

#include <vector>
#include <boost/shared_ptr.hpp>
#include "cstdint.hpp"
#include "node_id.hpp"
#include "pe.hpp"
#include "node.hpp"
#include "arbiter.hpp"
#include "bridge.hpp"
#include "logger.hpp"
#include "statistics.hpp"

using namespace std;
//using namespace boost;

typedef node_id tile_id;

class tile {
public:
    tile(const tile_id &id, const uint32_t num_tiles,
         const uint64_t &init_time, const uint64_t &stats_start_time,
         boost::shared_ptr<flow_rename_table> flow_renames, logger &log) throw();
    void add(boost::shared_ptr<pe> p) throw();
    void add(boost::shared_ptr<bridge> p) throw();
    void add(boost::shared_ptr<node> p) throw();
    void add(boost::shared_ptr<arbiter> a) throw();
    const uint64_t &get_time() const throw();
    boost::shared_ptr<tile_statistics> get_statistics() const throw();
    boost::shared_ptr<id_factory<packet_id> > get_packet_id_factory() const throw();
    void tick_positive_edge() throw(err);
    void tick_negative_edge() throw(err);
    void fast_forward_time(uint64_t new_time) throw();
    bool is_ready_to_offer() const throw();
    bool is_drained() const throw();
    bool work_queued() const throw();
    uint64_t next_pkt_time() const throw();
private:
    typedef vector<boost::shared_ptr<pe> > pes_t;
    typedef vector<boost::shared_ptr<node> > nodes_t;
    typedef vector<boost::shared_ptr<bridge> > bridges_t;
    typedef vector<boost::shared_ptr<arbiter> > arbiters_t;
private:
    const tile_id id;
    uint64_t time;
    pes_t pes;
    nodes_t nodes;
    bridges_t bridges;
    arbiters_t arbiters;
    boost::shared_ptr<tile_statistics> stats;
    boost::shared_ptr<id_factory<packet_id> > pid_factory;
    logger &log;
};

#endif // __TILE_HPP__

max_stars_repo_name: rikygege/Hornet

max_issues_repo_name: rikygege/Hornet

max_forks_repo_name: rikygege/Hornet


text:
#include <fast_asio/fast_asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
#include <memory>
#include "root_certificates.hpp"

using namespace boost::asio;
using namespace boost::asio::ip;

// socket type
typedef ssl::stream<tcp::socket> ssl_socket;
typedef fast_asio::packet_stream<ssl_socket> socket_t;
typedef std::shared_ptr<socket_t> socket_ptr;

ssl::context ctx{ssl::context::sslv23_client};

void onReceive(socket_ptr socket, boost::system::error_code ec, const_buffer* buf_begin, const_buffer* buf_end) {
    if (ec) {
        std::cout << "disconnected, reason:" << ec.message() << std::endl;
        return ;
    }

    for (const_buffer* it = buf_begin; it != buf_end; ++it) {
        const_buffer body = fast_asio::default_packet_policy::get_body(*it);
        std::cout << "onReceive:" << std::string((const char*)body.data(), body.size()) << std::endl;
    }

    // 关闭连接
//    boost::system::error_code ignore_ec;
//    socket->shutdown(ignore_ec);
}

int main() {
    load_root_certificates(ctx);
    ctx.set_verify_mode(ssl::verify_none);

    io_context ioc;

    socket_ptr socket(new socket_t(ioc, ctx));

    // 1.设置拆包函数 (默认函数就是这个, 可以不写这一行)
    socket->set_packet_splitter(&fast_asio::default_packet_policy::split);

    // 2.连接
    tcp::endpoint addr(address::from_string("127.0.0.1"), 1234);
    socket->next_layer().next_layer().async_connect(addr,
            [socket](boost::system::error_code ec) {
                if (ec) {
                    std::cout << "connect error:" << ec.message() << std::endl;
                    return ;
                }

                std::cout << "connect success" << std::endl;

                // 握手(为了方便写个同步的)
                socket->next_layer().handshake(boost::asio::ssl::stream_base::handshake_type::client, ec);
                if (ec) {
                    std::cout << "handshake error:" << ec.message() << std::endl;
                    return ;
                }

                // 3.连接成功, 发起读操作
                socket->async_read_some(std::bind(&onReceive, socket,
                            std::placeholders::_1,
                            std::placeholders::_2,
                            std::placeholders::_3));

                // 4.发一个包
                char buf[] = "Hello fast_asio!";
                std::string packet = fast_asio::default_packet_policy::serialize_to_string(buffer(buf, sizeof(buf)));

                socket->async_write_some(buffer(packet), [](boost::system::error_code ec, size_t){
                            std::cout << "ping " << ec.message() << std::endl;
                        });
            });

    ioc.run();

    std::cout << socket.use_count() << std::endl;
}

ext: cc

max_stars_repo_name: brinkqiang/dmlibgo

max_issues_repo_name: brinkqiang/dmlibgo

max_forks_repo_name: brinkqiang/dmlibgo


text:
//  Copyright (c) 2021 DNV AS
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt

#include <jsScript/jsMath.h>
#include <jsScript/jsClass.h>
#include <jsScript/jsUnitValue.h>
#include <jsScript/jsQuantity.h>
#include <limits>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include "Units/Angle.h"
#include "Units/Runtime/DynamicQuantity.h"
#include "Units/Math.h"
#include "Reflection/Classes/Class.h"
#include "Reflection/Attributes/ExampleAttribute.h"
#include <Reflection/Containers/ReflectVector.h>
#include "Reflection/Members/GlobalType.h"
#include "jsMathImpl.h"

/*#include <boost/math/special_functions/acosh.hpp>
#include <boost/math/special_functions/asinh.hpp>
#include <boost/math/special_functions/atanh.hpp>*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace DNVS::MoFa::Units;
using namespace DNVS::MoFa::Units::Runtime;
using namespace DNVS::MoFa::Reflection::Classes;
using namespace std;

void jsMath::init(jsTypeLibrary& typeLibrary)
{
    srand((unsigned)time(NULL));

    using namespace DNVS::MoFa::Reflection::Classes;
    Class<jsMath> cls(typeLibrary.GetReflectionTypeLibrary(), "Math");
    cls.AddDocumentation("The Math object - methods");

    cls.StaticFunction("timer", [](long t0) { return long(time(nullptr) - t0); })
        .AddDocumentation("for performance test, returns the lapsed time in seconds since t0")
        .AddSignature("t0")
        .AddAttribute<ExampleAttribute>(
            "Math.timer(0); //Returns time in seconds since 1. January 1970\n"
            "t0 = Math.timer(0);  //Initialises the variable a\n"
            "t  = Math.timer(t0); //Computes time difference in seconds since when variable t0 was set\n"
            "print(t);            //Writes lapsed time to the journal file window\n");

    cls.StaticGet("E", 2.7182818284590452354)
        .AddDocumentation("The number value for e, the base of the natural logarithms, which is approximately 2.7182818284590452354")
        .AddAttribute<ExampleAttribute>(
            "Math.ln(E); //Returns 1"
            "Math.pow(E,5); //The same as Math.exp(5)");
    cls.StaticGet("LN10", 2.302585092994046).AddDocumentation("The number value for the natural logarithm of 10, which is approximately 2.302585092994046");
    cls.StaticGet("LN2", 0.6931471805599453).AddDocumentation("The number value for the natural logarithm of 2, which is approximately 0.6931471805599453");
    cls.StaticGet("LOG2E", 1.4426950408889634).AddDocumentation("The number value for the base-2 logarithm of e, the base of the natural logarithms; this value is approximately 1.4426950408889634");
    cls.StaticGet("LOG10E", 0.4342944819032518).AddDocumentation("The number value for the base-10 logarithm of e, the base of the natural logarithms; this value is approximately 0.4342944819032518");
    cls.StaticGet("PI", 3.1415926535897932).AddDocumentation("The number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932");
    cls.StaticGet("SQRT1_2", 0.7071067811865476).AddDocumentation("The number value for the square root of 1/2, which is approximately 0.7071067811865476");
    cls.StaticGet("SQRT2", 1.4142135623730951).AddDocumentation("The number value for the square root of 2, which is approximately 1.4142135623730951");

    Class<DNVS::MoFa::Reflection::Members::GlobalType>(typeLibrary.GetReflectionTypeLibrary(), "")
        .StaticGet("Math", jsMath());
    InitFunctionsForDouble<double>(cls);
    InitFunctionsForUnits<DynamicQuantity>(cls);

}

max_stars_repo_name: dnv-opensource/Reflection

max_issues_repo_name: dnv-opensource/Reflection

max_forks_repo_name: dnv-opensource/Reflection


text:
/***********************************************************************************************************************
*  OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC, and other contributors. All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
*  following conditions are met:
*
*  (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*  disclaimer.
*
*  (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
*  disclaimer in the documentation and/or other materials provided with the distribution.
*
*  (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse or promote products
*  derived from this software without specific prior written permission from the respective party.
*
*  (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other derivative works
*  may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar designation without specific prior
*  written permission from Alliance for Sustainable Energy, LLC.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
*  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE UNITED STATES GOVERNMENT, OR THE UNITED
*  STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
*  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
*  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
*  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
*  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************************************************************/

#include "stdlib.h"
#include "System.hpp"

#include <boost/thread.hpp>
#include <boost/numeric/ublas/lu.hpp>

namespace openstudio{

#if (defined (_WIN32) || defined (_WIN64))

  #define _WIN32_WINNT 0x0500

  #include <windows.h>

  /// return the amount of time that the system has been idle
  boost::optional<Time> System::systemIdleTime()
  {
    boost::optional<Time> result;

    LASTINPUTINFO lastInput;
    lastInput.cbSize = sizeof(LASTINPUTINFO);
    if (GetLastInputInfo(&lastInput)){
      // current system up time in MS, lastInput is referenced to this
      // maximum value is 49.7 days, how telling.....
      DWORD tickCount = GetTickCount();

      // idle milliseconds
      unsigned idleMS = boost::lexical_cast<unsigned>(tickCount-lastInput.dwTime);

      // use integer division like a pro
      result = Time(0,0,0,idleMS/1000);
    }
    return result;
  }

#else

  /// return the amount of time that the system has been idle
  boost::optional<Time> System::systemIdleTime()
  {
    return boost::optional<Time>();
  }

#endif

  void System::msleep(int msecs)
  {
    boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time();

    int remainingtime = msecs;
    while ( remainingtime > 0 )
    {
      // TODO: QT-Separation-Move
      //bool didwork = openstudio::Application::instance().processEvents(remainingtime);
      bool didwork = false;
      remainingtime = msecs - (int)(boost::posix_time::microsec_clock::universal_time() - start).total_milliseconds();
//      std::cout << "time " << msecs << " remainingtime " << remainingtime << std::endl;

      int timetosleep = 0;

      if (remainingtime > 0)
      {
        if (didwork)
        {
          timetosleep = 1; // it was working, let it keep processing after a yield
        } else {
          timetosleep = remainingtime<10?remainingtime:10;
        }
      }

#if (defined (_WIN32) || defined (_WIN64))
        Sleep(timetosleep);
#else
        usleep(timetosleep * 1000);
#endif
    }

    // TODO: QT-Separation-Move
    //openstudio::Application::instance().processEvents(); // process any outstanding events
  }

  /// \note not using string_view because we need null terminated strings
  boost::optional<std::string> System::getenv(const std::string &name) noexcept
  {
    const char *ptr = std::getenv(name.c_str());
    if (ptr) {
      return std::string{ptr};
    } else {
      return {};
    }
  }

  /// \note not using string_view because we need null terminated strings
  void System::setenv(const std::string &name, const std::string &value)
  {
#if (defined (_WIN32) || defined (_WIN64))
    if (const auto result = ::_putenv_s(name.c_str(), value.c_str()); result != 0) {
      throw std::runtime_error("Unable to set environment variable: unknown error");
    }
#else
    if (const auto result = ::setenv(name.c_str(), value.c_str(), 1); result == EINVAL) {
      throw std::runtime_error("Unable to set environment variable: invalid value: " + name);
    } else if (result == ENOMEM) {
      throw std::runtime_error("Unable to set environment variable: insufficient memory");
    } else if (result != 0) {
      throw std::runtime_error("Unable to set environment variable: unknown error");
    }
#endif

  }

  unsigned System::numberOfProcessors()
  {
    unsigned numberOfProcessors = boost::thread::hardware_concurrency();
    if (numberOfProcessors < 1){
      numberOfProcessors = 1;
    }
    return numberOfProcessors;
  }

  void System::testExceptions1()
  {
    try {
      std::cout << "testExceptions1: Test 1" << std::endl;
      throw std::exception();
    } catch (const std::exception &) {
    }

    try {
      std::cout << "testExceptions1: Test 2" << std::endl;
      throw std::exception();
    } catch (...) {
    }
  }

  void System::testExceptions2()
  {
    try {
      std::cout << "testExceptions2: Test 1" << std::endl;
      throw std::runtime_error("test");
    } catch (const std::runtime_error &) {
    }

    try {
      std::cout << "testExceptions2: Test 2" << std::endl;
      throw std::runtime_error("test");
    } catch (const std::exception &) {
    }

    try {
      std::cout << "testExceptions2: Test 3" << std::endl;
      throw std::runtime_error("test");
    } catch (...) {
    }
  }

  void System::testExceptions5()
  {
    using namespace boost::numeric::ublas;
    using namespace std;

    struct BreakUBlas
    {
      static bool invertMatrix(matrix<double>& orig, matrix<double>& inverted) {
        typedef permutation_matrix<std::size_t> pmatrix;
        matrix<double> A(orig);
        pmatrix pm(A.size1());

        // perform LU-factorization
        int res = lu_factorize(A,pm);
        if( res != 0 ) return false;

        inverted.assign(identity_matrix<double>(A.size1()));
        lu_substitute(A, pm, inverted);

        return true;
      };

      static void breakIt() {
        double data[6][6] = {{15, 29700, 472042, 7.8021e+06, 1.32426e+08, 2.29091e+09},
          {29700,1.32426e+08,2.29091e+09,4.01989e+10,7.13142e+11,1.27611e+13},
          {472042,2.29091e+09,4.01989e+10,7.13142e+11,1.27611e+13,2.29941e+14},
          {7.8021e+06,4.01989e+10,7.13142e+11,1.27611e+13,2.29941e+14,4.16694e+15},
          {1.32426e+08,7.13142e+11,1.27611e+13,2.29941e+14,4.16694e+15,7.58705e+16},
          {2.29091e+09,1.27611e+13,2.29941e+14,4.16694e+15,7.58705e+16,1.38694e+18}};

        matrix<double> a(6, 6);
        for (unsigned i = 0; i < a.size1 (); ++i)
          for (unsigned j = 0; j < a.size2 (); ++j)
            a(i, j) = data[i][j];

        matrix<double> b(a);
        invertMatrix(a, b);
      }
    };

    try {
      std::cout << "testExceptions5: Test 1" << std::endl;
      BreakUBlas::breakIt();
      assert(!"Exception Not Thrown");
    } catch (boost::numeric::ublas::internal_logic &) {
    }

    try {
      std::cout << "testExceptions5: Test 2" << std::endl;
      BreakUBlas::breakIt();
      assert(!"Exception Not Thrown");
    } catch (std::logic_error &) {
    }

    try {
      std::cout << "testExceptions5: Test 3" << std::endl;
      BreakUBlas::breakIt();
      assert(!"Exception Not Thrown");
    } catch (std::exception &) {
    }

   }

  void System::testExceptions3()
  {
    class MyException : public std::runtime_error
    {
      public:
        MyException() : std::runtime_error("exception")
        {}

        virtual ~MyException() throw()
        {}
    };

    try {
      std::cout << "testExceptions3: Test 1" << std::endl;
      throw MyException();
    } catch (const MyException &) {
    }

    try {
      std::cout << "testExceptions3: Test 2" << std::endl;
      throw MyException();
    } catch (const std::runtime_error &) {
    }

    try {
      std::cout << "testExceptions3: Test 3" << std::endl;
      throw MyException();
    } catch (const std::exception &) {
    }

    try {
      std::cout << "testExceptions3: Test 4" << std::endl;
      throw MyException();
    } catch (...) {
    }
  }

  void System::testExceptions4()
  {
    class MyException : public std::runtime_error
    {
      public:
        MyException() : std::runtime_error("exception")
        {}

        virtual ~MyException() throw()
        {}
    };

    class MyException2 : public MyException
    {
      public:
        MyException2()
        {}

        virtual ~MyException2() throw()
        {}
    };

    try {
      std::cout << "testExceptions4: Test 1" << std::endl;
      throw MyException2();
    } catch (const MyException2 &) {
    }

    try {
      std::cout << "testExceptions4: Test 2" << std::endl;
      throw MyException2();
    } catch (const MyException &) {
    }

    try {
      std::cout << "testExceptions4: Test 3" << std::endl;
      throw MyException2();
    } catch (const std::runtime_error &) {
    }

    try {
      std::cout << "testExceptions4: Test 4" << std::endl;
      throw MyException2();
    } catch (const std::exception &) {
    }

    try {
      std::cout << "testExceptions4: Test 5" << std::endl;
      throw MyException2();
    } catch (...) {
    }
  }

} // openstudio

max_stars_repo_name: mehrdad-shokri/OpenStudio

max_issues_repo_name: mehrdad-shokri/OpenStudio

max_forks_repo_name: mehrdad-shokri/OpenStudio


text:
/**
 * @file budgeted_maximum_coverage.hpp
 * @brief
 * @author Piotr Smulewicz
 * @version 1.0
 * @date 2014-03-18
 */
#ifndef PAAL_BUDGETED_MAXIMUM_COVERAGE_HPP
#define PAAL_BUDGETED_MAXIMUM_COVERAGE_HPP

#include "paal/data_structures/fraction.hpp"
#include "paal/utils/accumulate_functors.hpp"
#include "paal/utils/algorithms/subset_backtrack.hpp"
#include "paal/utils/functors.hpp"
#include "paal/utils/type_functions.hpp"

#include <boost/heap/d_ary_heap.hpp>
#include <boost/range/adaptor/indexed.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/algorithm_ext/iota.hpp>
#include <boost/range/algorithm/fill.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/algorithm/sort.hpp>
#include <boost/range/combine.hpp>

#include <algorithm>
#include <vector>

namespace paal {
namespace greedy {
namespace detail {

template <typename ElementWeight, typename SetCost> struct set_data_type {
    set_data_type()
        : m_weight_of_uncovered_elements{}, m_cost{}, m_is_processed{ true } {}
    ElementWeight m_weight_of_uncovered_elements; // sum of weight of uncovered
                                                  // elements in backtrack and
                                                  // greedy
    SetCost m_cost;
    bool m_is_processed;
    // set is processed if is selected or is not selected and at least one of
    // the following situations occurs
    // -we have not enough budget to select set
    // -sum of weight of uncovered elements belong to set equal 0
};

template <typename SetReference, typename GetElementsOfSet,
          typename GetWeightOfElement>
using element_weight_t = pure_result_of_t<GetWeightOfElement(
    range_to_elem_t<pure_result_of_t<GetElementsOfSet(SetReference)>>)>;

const int UNCOVERED = -1;
template <class Budget, class SetCost, class SetIdToData, class ElementWeight,
          class SetIdToElements, class ElementIndex, class GetWeightOfElement,
          typename DecreseWeight>
class selector {
    const Budget m_budget;
    SetCost &m_cost_of_solution;
    std::vector<int> m_selected_sets;
    SetIdToData &m_sets_data;
    const ElementWeight &m_weight_of_bests_solution;
    ElementWeight &m_weight_of_covered_elements;
    SetIdToElements m_set_id_to_elements;
    std::vector<int> &m_covered_by;
    std::vector<std::vector<int>> &m_sets_covering_element;
    ElementIndex &m_get_el_index;
    GetWeightOfElement &m_element_to_weight;
    DecreseWeight m_decrese_weight;

    using SetData = range_to_elem_t<SetIdToData>;

  public:
    selector(const Budget budget, SetCost &cost_of_solution,
             SetIdToData &sets_data,
             const ElementWeight &weight_of_bests_solution,
             ElementWeight &weight_of_covered_elements,
             SetIdToElements set_id_to_elements, std::vector<int> &covered_by,
             std::vector<std::vector<int>> &sets_covering_element,
             ElementIndex &get_el_index, GetWeightOfElement &element_to_weight,
             DecreseWeight decrese_weight)
        : m_budget(budget), m_cost_of_solution(cost_of_solution),
          m_sets_data(sets_data),
          m_weight_of_bests_solution(weight_of_bests_solution),
          m_weight_of_covered_elements(weight_of_covered_elements),
          m_set_id_to_elements(set_id_to_elements), m_covered_by(covered_by),
          m_sets_covering_element(sets_covering_element),
          m_get_el_index(get_el_index), m_element_to_weight(element_to_weight),
          m_decrese_weight(decrese_weight) {}

    // we return true if (we select set) or (set is already in solution)
    bool select_set_backtrack(int selected_set_id, bool in_reset = false) {
        if(!can_select(m_sets_data[selected_set_id])) return false;

        select_set(selected_set_id, true);
        if(!in_reset) m_selected_sets.push_back(selected_set_id);
        return true;
    }

    // we return true if we violated budget
    bool select_set_greedy(int selected_set_id) {
        auto &select_set_data = m_sets_data[selected_set_id];

        if(!can_select(select_set_data)) return false;
        m_selected_sets.push_back(selected_set_id);

        if(greedy_prune(select_set_data))  return true;
        select_set(selected_set_id, false);
        return false;
    }

    void deselect_set(int selected_set_id, bool backtrack = true) {
        // we deselect set

        m_cost_of_solution -= m_sets_data[selected_set_id].m_cost;
        for (auto element : m_set_id_to_elements(selected_set_id)) {
            if (covered_by(element) == selected_set_id) {
                m_covered_by[m_get_el_index(element)] = UNCOVERED;
                auto weight_of_element = m_element_to_weight(element);
                cover_element(element, -weight_of_element, backtrack, false);
            }
        }
        m_selected_sets.pop_back();
    }

    void set_unprocessed(
            boost::iterator_range<std::vector<int>::const_iterator> const & set_ids) {
        for (auto set_id : set_ids) {
            m_sets_data[set_id].m_is_processed = false;
        }
    };

    void reset() {
        set_unprocessed(m_selected_sets);
        if (m_selected_sets.size() > 0) {
            boost::for_each(m_selected_sets, [&](int selected_set_id) {
                select_set_backtrack(selected_set_id, true);
            });
        }
    }

    std::size_t size() {
        return m_selected_sets.size();
    }

    void resize(std::size_t size) {
        return m_selected_sets.resize(size);
    }

    template <typename OutputIterator>
    void copy_to(OutputIterator out){
        boost::copy(m_selected_sets, out);
    }
private:

    void select_set(int selected_set_id, bool backtrack) {
        auto &select_set_data = m_sets_data[selected_set_id];

        m_cost_of_solution += select_set_data.m_cost;
        for (auto element : m_set_id_to_elements(selected_set_id)) {
            if (covered_by(element) == UNCOVERED) { /* we do not cover the
                                                        elements being covered*/

                m_covered_by[m_get_el_index(element)] = selected_set_id;
                auto weight_of_element = m_element_to_weight(element);
                cover_element(element, weight_of_element, backtrack);
            }
        }
    }

    /// optimization:
    /// in greedy phase we get sets in decreasing density order, so we can cut
    /// when spend rest of budget with current density product solution, worse
    /// then best found solution.
    bool greedy_prune(const SetData & set_data) {
        return (m_budget - m_cost_of_solution) * set_data.m_weight_of_uncovered_elements <=
                static_cast<Budget>(set_data.m_cost * (m_weight_of_bests_solution - m_weight_of_covered_elements));
    }

    ///this function is ALWAYS called from select_set, thats why we set set_data.m_is_processed!
    bool can_select(SetData & set_data) {
        if (set_data.m_is_processed) return false;
        set_data.m_is_processed = true;
        return static_cast<Budget>(m_cost_of_solution + set_data.m_cost) <= m_budget &&
            set_data.m_weight_of_uncovered_elements!= ElementWeight{};
    }

    template <typename Element>
    void cover_element(Element && el, ElementWeight weight_diff, bool backtrack, bool select = true) {
        m_weight_of_covered_elements += weight_diff;
        for (auto set_id :
                m_sets_covering_element[m_get_el_index(el)]) {
            if (m_sets_data[set_id].m_weight_of_uncovered_elements >
                    weight_diff || backtrack) {
                m_sets_data[set_id].m_weight_of_uncovered_elements -= weight_diff;
                if (!backtrack && !m_sets_data[set_id].m_is_processed) {
                    m_decrese_weight(set_id);
                }
            } else {
                if (select) {
                    m_sets_data[set_id].m_is_processed = true;
                }
            }
        }
    }

    template <typename Element>
    auto covered_by(Element && el) const
        -> decltype(m_covered_by[m_get_el_index(el)]) {

        return m_covered_by[m_get_el_index(el)];
    }
};

template <class Budget, class SetCost, class SetIdToData, class ElementWeight,
         class SetIdToElements, class ElementIndex, class GetWeightOfElement,
         typename DecreseWeight>
auto make_selector(const Budget budget, SetCost &cost_of_solution,
                   SetIdToData &sets_data,
                   const ElementWeight &weight_of_bests_solution,
                   ElementWeight &weight_of_covered_elements,
                   SetIdToElements set_id_to_elements,
                   std::vector<int> &covered_by,
                   std::vector<std::vector<int>> &sets_covering_element,
                   ElementIndex &get_el_index,
                   GetWeightOfElement &element_to_weight,
                   DecreseWeight decrese_weight) {
    return selector<Budget, SetCost, SetIdToData, ElementWeight,
                    SetIdToElements, ElementIndex, GetWeightOfElement,
                    DecreseWeight>(
        budget, cost_of_solution, sets_data,
        weight_of_bests_solution, weight_of_covered_elements,
        set_id_to_elements, covered_by, sets_covering_element, get_el_index,
        element_to_weight, decrese_weight);
}
} //!detail

/**
 * @brief this is solve Set Cover problem
 * and return set cover cost
 * example:
 *  \snippet set_cover_example.cpp Set Cover Example
 *
 * complete example is set_cover_example.cpp
 * @param sets
 * @param set_to_cost
 * @param set_to_elements
 * @param result set iterators of chosen sets
 * @param get_el_index
 * @param budget
 * @param element_to_weight
 * @param initial_set_size
 * @tparam SetRange
 * @tparam GetCostOfSet
 * @tparam GetElementsOfSet
 * @tparam OutputIterator
 * @tparam ElementIndex
 * @tparam Budget
 * @tparam GetWeightOfElement
 */
template <typename SetRange, class GetCostOfSet, class GetElementsOfSet,
          class OutputIterator, class ElementIndex, class Budget,
          class GetWeightOfElement = utils::return_one_functor>
auto budgeted_maximum_coverage(
    SetRange && sets, GetCostOfSet set_to_cost,
    GetElementsOfSet set_to_elements, OutputIterator result,
    ElementIndex get_el_index, Budget budget,
    GetWeightOfElement element_to_weight = GetWeightOfElement(),
    const unsigned int initial_set_size = 3) {

    using set_reference = typename boost::range_reference<SetRange>::type;
    using element_weight = typename detail::element_weight_t<
        set_reference, GetElementsOfSet, GetWeightOfElement>;
    using set_cost = pure_result_of_t<GetCostOfSet(set_reference)>;
    using set_id_to_data = std::vector<detail::set_data_type<element_weight, set_cost>>;

    auto nu_sets = boost::distance(sets);
    set_id_to_data initial_sets_data(nu_sets), sets_data(nu_sets);
    set_cost cost_of_solution{}, cost_of_best_solution{};
    int number_of_elements = 0;

    // we find max index of elements in all sets
    for (auto set_and_data : boost::combine(sets, initial_sets_data)) {
        auto const & set = boost::get<0>(set_and_data);
        auto &cost = boost::get<1>(set_and_data).m_cost;
        cost = set_to_cost(set);
        assert(cost != set_cost{});
        auto const & elements = set_to_elements(set);
        if (!boost::empty(elements)) {
            number_of_elements = std::max(number_of_elements,
                    *max_element_functor(elements, get_el_index) + 1);
        }
    }
    element_weight weight_of_covered_elements{}, weight_of_bests_solution{};
    std::vector<int> best_solution(1);
    std::vector<int> covered_by(
        number_of_elements, detail::UNCOVERED); // index of the first set that covers
                                        // element or -1 if element is uncovered
    std::vector<int> sets_id(nu_sets);
    boost::iota(sets_id, 0);
    std::vector<std::vector<int>> sets_covering_element(number_of_elements);
    auto decreasing_density_order =
        utils::make_functor_to_comparator([&](int x) {
            return data_structures::make_fraction(
                sets_data[x].m_weight_of_uncovered_elements, sets_data[x].m_cost);
        });
    using queue = boost::heap::d_ary_heap<
        int, boost::heap::arity<3>, boost::heap::mutable_<true>,
        boost::heap::compare<decltype(decreasing_density_order)>>;

    queue uncovered_set_queue{ decreasing_density_order };
    std::vector<typename queue::handle_type> set_id_to_handle(nu_sets);

    // we fill sets_covering_element and setToWeightOfElements
    for (auto set : sets | boost::adaptors::indexed()) {
        auto set_id = set.index();
        auto &set_data = initial_sets_data[set_id];

        for (auto &&element : set_to_elements(set.value())) {
            sets_covering_element[get_el_index(element)].push_back(set_id);
            set_data.m_weight_of_uncovered_elements += element_to_weight(element);
        }
        if (initial_set_size ==
            0) { /* we check all one element set. if initial_set_size!= 0 then
                    we will do it anyway */
            set_cost cost_of_set = set_data.m_cost;
            if (set_data.m_weight_of_uncovered_elements >= weight_of_bests_solution &&
                static_cast<Budget>(cost_of_set) <= budget) {
                weight_of_bests_solution = set_data.m_weight_of_uncovered_elements;
                best_solution[0] = set_id;
                cost_of_best_solution = cost_of_set;
            }
        }
    };

    auto sort_sets = [&](std::vector<int>& sets_range) {
        boost::sort(sets_range, utils::make_functor_to_comparator([&](int x) {
                                    return sets_data[x].m_weight_of_uncovered_elements;
                                }));
        return sets_range.end();
    };
    auto selector = detail::make_selector
                (budget, cost_of_solution,sets_data,
                 weight_of_bests_solution,weight_of_covered_elements,
                 [&](int selected_set_id){return set_to_elements(sets[selected_set_id]);},
                 covered_by,sets_covering_element,get_el_index,
                 element_to_weight,
                 [&](int set_id){uncovered_set_queue.decrease(set_id_to_handle[set_id]);});

    boost::copy(initial_sets_data, sets_data.begin());
    sort_sets(sets_id);
    auto solver = make_subset_backtrack(sets_id);

    auto reset = [&]() {
        boost::copy(initial_sets_data, sets_data.begin());
        cost_of_solution = set_cost{};
        selector.set_unprocessed(solver.get_moves());
        boost::fill(covered_by, detail::UNCOVERED);
        weight_of_covered_elements = element_weight{};
        selector.reset();
    };

    auto on_pop = [&](int deselected_set_id) {
        selector.deselect_set(deselected_set_id);
        selector.set_unprocessed(solver.get_moves());
    };

    auto save_best_solution = [&]() {
        // we check that new solution is better than any previous
        // if is we remember them
        // tricky: either better weight, or equal weight and lower cost
        if (std::make_pair(weight_of_covered_elements, cost_of_best_solution) >
            std::make_pair(weight_of_bests_solution, cost_of_solution)) {
            weight_of_bests_solution = weight_of_covered_elements;
            cost_of_best_solution = cost_of_solution;
            best_solution.resize(selector.size());
            selector.copy_to(best_solution.begin());
        }
    };
    auto greedy_phase = [&]() {
        uncovered_set_queue.clear();
        auto moves = solver.get_moves();
        if(boost::empty(moves)) return;

        for (auto set_id : moves) {
            set_id_to_handle[set_id] = uncovered_set_queue.push(set_id);
        }
        /* we select set with best elements to cost ratio, and add it to the
         * result until all elements are covered*/
        int uncovered_set_id;
        do {
            uncovered_set_id = uncovered_set_queue.top();
            uncovered_set_queue.pop();
        } while (!selector.select_set_greedy(uncovered_set_id) &&
                !uncovered_set_queue.empty());
    };

    auto can_push = [&](int candidate) {
        if (!selector.select_set_backtrack(candidate)) {
            return false;
        }
        if (selector.size() == initial_set_size) {
            greedy_phase();
            save_best_solution();
            selector.resize(initial_set_size-1);
            reset();
            return false;
        } else {
            save_best_solution();
            return true;
        }
    };

    reset();
    if (initial_set_size != 0) { /* if initial_set_size == 0 then we do greedy
    algorithm once starts from empty initial Set.
    Otherwise we starts greedy algorithm from all initial set of size equal
    initial_set_size those for which we have enough budget*/
        solver.solve(can_push, on_pop, sort_sets);
    } else {
        greedy_phase();
        save_best_solution();
    }

    for (auto set_id : best_solution) {
        *result = *(sets.begin() + set_id);
        ++result;
    }
    return weight_of_bests_solution;
};
} //!greedy
} //!paal

#endif /* PAAL_BUDGETED_MAXIMUM_COVERAGE_HPP */

max_stars_repo_name: Kommeren/AA

max_issues_repo_name: Kommeren/AA

max_forks_repo_name: Kommeren/AA


text:
#include <base/cgal_typedefs.h>
#include <IO/fileIO.h>
#include <util/helper.h>
#include <util/geometricOperations.h>

#include <processing/field.h>

#include <CGAL/point_generators_3.h>
#include <CGAL/Random.h>
#include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <boost/foreach.hpp>
#include <CGAL/Polygon_mesh_processing/distance.h>
#include <CGAL/polygon_mesh_processing.h>
#include <CGAL/optimal_bounding_box.h>
#include <CGAL/Side_of_triangle_mesh.h>

#include <util/helper.h>

#include <random>

using namespace std;

int makeFieldOnDelaunayVertices(dataHolder& data, string mode){

    auto start = std::chrono::high_resolution_clock::now();

    cout << "\nMaking field..." << endl;
    cout << "\t-using mode: " << mode << endl;

    if(data.gt_poly.size_of_vertices() == 0){
        cout << "\nERROR: you need to load a ground truth polygon (with -g) for scanning it" << endl;
        return 1;
    }
    if(!data.gt_poly.is_closed()){
        cout << "\nERROR: ground truth is not closed" << endl;
        return 1;
    }

    // Initialize the point-in-polyhedron tester
    // Construct AABB tree with a KdTree
    SurfaceMesh smesh;
    CGAL::copy_face_graph(data.gt_poly, smesh);
    Tree tree(faces(smesh).first, faces(smesh).second, smesh);
    tree.accelerate_distance_queries();
    // Initialize the point-in-polyhedron tester
    Point p;
    double val;
    Delaunay::Finite_vertices_iterator aci;

    const Point_inside inside_tester(tree);

    for(aci = data.Dt.finite_vertices_begin(); aci != data.Dt.finite_vertices_end(); aci++){

        p = aci->point();

        if(inside_tester(p) == CGAL::ON_BOUNDED_SIDE){
            val=-1.0;
        }
        else if(inside_tester(p) == CGAL::ON_UNBOUNDED_SIDE){
            val=1.0;
        }
        else{
            val=0.0;
        }

        if(mode == "occ"){
            aci->info().field_value = val;
        }
        else if(mode == "sdf"){
            aci->info().field_value = sqrt(tree.squared_distance(p))*val;
        }
        else{
            cout << "\nERROR: not a valid field mode!" << endl;
            return 1;
        }
    }

    auto stop = chrono::high_resolution_clock::now();
    auto duration = chrono::duration_cast<std::chrono::seconds>(stop - start);
    cout << "\t-in "<<duration.count() << "s" << endl;

    return 0;
}

max_stars_repo_name: raphaelsulzer/mesh-tools

max_issues_repo_name: raphaelsulzer/mesh-tools

max_forks_repo_name: raphaelsulzer/mesh-tools


text:
#ifndef EIGEN_TYPEDEFS_HPP
#define EIGEN_TYPEDEFS_HPP

#include <Eigen/Geometry>
#include <Eigen/StdVector>
#include <map>

namespace EigenHelpers {
////////////////////////////////////////////////////////////////////////////
// Typedefs for aligned STL containers using Eigen types
////////////////////////////////////////////////////////////////////////////

typedef std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f>> VectorVector2f;
typedef std::vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> VectorVector2d;
typedef std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f>> VectorVector3f;
typedef std::vector<Eigen::Vector3d, Eigen::aligned_allocator<Eigen::Vector3d>> VectorVector3d;
typedef std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f>> VectorVector4f;
typedef std::vector<Eigen::Vector4d, Eigen::aligned_allocator<Eigen::Vector4d>> VectorVector4d;
typedef std::vector<Eigen::Quaternionf, Eigen::aligned_allocator<Eigen::Quaternionf>> VectorQuaternionf;
typedef std::vector<Eigen::Quaterniond, Eigen::aligned_allocator<Eigen::Quaterniond>> VectorQuaterniond;
typedef std::vector<Eigen::Isometry3f, Eigen::aligned_allocator<Eigen::Isometry3f>> VectorIsometry3f;
typedef std::vector<Eigen::Isometry3d, Eigen::aligned_allocator<Eigen::Isometry3d>> VectorIsometry3d;
typedef std::vector<Eigen::Affine3f, Eigen::aligned_allocator<Eigen::Affine3f>> VectorAffine3f;
typedef std::vector<Eigen::Affine3d, Eigen::aligned_allocator<Eigen::Affine3d>> VectorAffine3d;
typedef std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f>> VectorMatrix4f;
typedef std::vector<Eigen::Matrix4d, Eigen::aligned_allocator<Eigen::Matrix4d>> VectorMatrix4d;
typedef std::vector<Eigen::Translation3f, Eigen::aligned_allocator<Eigen::Translation3f>> VectorTranslation3f;
typedef std::vector<Eigen::Translation3d, Eigen::aligned_allocator<Eigen::Translation3d>> VectorTranslation3d;
typedef std::map<std::string, Eigen::Vector2f, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Vector2f>>>
    MapStringVector2f;
typedef std::map<std::string, Eigen::Vector2d, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Vector2d>>>
    MapStringVector2d;
typedef std::map<std::string, Eigen::Vector3f, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Vector3f>>>
    MapStringVector3f;
typedef std::map<std::string, Eigen::Vector3d, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Vector3d>>>
    MapStringVector3d;
typedef std::map<std::string, Eigen::Vector4f, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Vector4f>>>
    MapStringVector4f;
typedef std::map<std::string, Eigen::Vector4d, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Vector4d>>>
    MapStringVector4d;
typedef std::map<std::string, Eigen::Quaternionf, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Quaternionf>>>
    MapStringQuaternionf;
typedef std::map<std::string, Eigen::Quaterniond, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Quaterniond>>>
    MapStringQuaterniond;
typedef std::map<std::string, Eigen::Isometry3f, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Isometry3f>>>
    MapStringIsometry3f;
typedef std::map<std::string, Eigen::Isometry3d, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Isometry3d>>>
    MapStringIsometry3d;
typedef std::map<std::string, Eigen::Affine3f, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Affine3f>>>
    MapStringAffine3f;
typedef std::map<std::string, Eigen::Affine3d, std::less<std::string>,
                 Eigen::aligned_allocator<std::pair<const std::string, Eigen::Affine3d>>>
    MapStringAffine3d;
}  // namespace EigenHelpers

#endif


text:
//          Copyright Gavin Band 2008 - 2012.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#ifndef GENFILE_COHORT_INDIVIDUAL_SOURCE_CHAIN_HPP
#define GENFILE_COHORT_INDIVIDUAL_SOURCE_CHAIN_HPP

#include <memory>
#include <string>
#include <boost/ptr_container/ptr_vector.hpp>
#include "genfile/CohortIndividualSource.hpp"

namespace genfile {
	class CohortIndividualSourceChain: public CohortIndividualSource
	{
	public:
		typedef std::auto_ptr< CohortIndividualSourceChain > UniquePtr ;
	public:
		CohortIndividualSourceChain() ;
		~CohortIndividualSourceChain() ;

		void add_source( CohortIndividualSource::UniquePtr source, std::string const& source_name ) ;

		std::size_t get_number_of_individuals() const ;
		ColumnSpec get_column_spec() const ;

		Entry get_entry( std::size_t sample_i, std::string const& column_name ) const ;

		std::string get_source_spec() const ;
	private:
		boost::ptr_vector< CohortIndividualSource > m_sources ;
        std::vector< std::string > m_source_names ;
		ColumnSpec m_column_spec ;
	} ;
}

#endif

max_stars_repo_name: gavinband/bingwa

max_issues_repo_name: gavinband/bingwa

max_forks_repo_name: gavinband/bingwa


text:
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#define ELPP_THREAD_SAFE
#define ELPP_STL_LOGGING

#include <iostream>
#include <random>
#include <vector>

#include "cutil.hpp"
#include "qsufsort.hpp"
#include "util.hpp"

#include <boost/algorithm/string/classification.hpp> // Include boost::for is_any_of
#include <boost/algorithm/string/split.hpp> // Include for boost::split
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

namespace po = boost::program_options;
namespace fs = boost::filesystem;

#include "collection.hpp"
#include "rlz_utils.hpp"
#include "utils.hpp"

#include "indexes.hpp"

#include "logging.hpp"
INITIALIZE_EASYLOGGINGPP

po::variables_map parse_cmdargs(int argc, char const* argv[])
{
    po::variables_map vm;
    po::options_description desc("Allowed options");
    // clang-format off
    desc.add_options()
        ("help,h", "produce help message")
        ("input,i",po::value<std::string>()->required(), "input file")
        ("collection,c",po::value<std::string>()->required(), "tmp collection directory")
        ("dict,d",po::value<uint32_t>()->required(), "dict size")
        ("text,t", "text instead of uint32_t output")
        ("output,o",po::value<std::string>()->required(), "output prefix")
        ("maxint,m",po::value<uint32_t>(), "maximum number of integers to write");
    // clang-format on
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        if (vm.count("help")) {
            std::cout << desc << "\n";
            exit(EXIT_SUCCESS);
        }
        po::notify(vm);
    } catch (const po::required_option& e) {
        std::cout << desc;
        std::cerr << "Missing required option: " << e.what() << std::endl;
        exit(EXIT_FAILURE);
    } catch (po::error& e) {
        std::cout << desc;
        std::cerr << "Error parsing cmdargs: " << e.what() << std::endl;
        exit(EXIT_FAILURE);
    }

    return vm;
}

void print_progress(double percent)
{
    uint32_t bar_width = 70;
    std::cout << "[";
    uint32_t pos = percent * bar_width;
    for (uint32_t i = 0; i < bar_width; i++) {
        if (i < pos)
            std::cout << "=";
        else if (i == pos)
            std::cout << ">";
        else
            std::cout << " ";
    }
    std::cout << "] " << uint32_t(percent * 100) << " %\r";
    std::cout.flush();
}

void create_collection(std::string input_file, std::string col_dir)
{

    utils::create_directory(col_dir);
    std::string output_file = col_dir + "/" + KEY_PREFIX + KEY_TEXT;
    if (utils::file_exists(output_file)) {
        LOG(INFO) << "Collection already exists.";
        return;
    }
    {
        // auto out = sdsl::write_out_buffer<8>::create(output_file);
        sdsl::int_vector_buffer<8> out(
            output_file, std::ios::out, 128 * 1024 * 1024);
        if (!utils::file_exists(input_file)) {
            LOG(FATAL) << "Input file " << input_file << " does not exist.";
        }
        LOG(INFO) << "Processing " << input_file;
        sdsl::int_vector_buffer<8> input(
            input_file, std::ios::in, 128 * 1024 * 1024, 8, true);
        auto itr = input.begin();
        auto end = input.end();
        auto replaced_zeros = 0;
        auto replaced_ones = 0;
        size_t processed = 0;
        size_t total = std::distance(itr, end);
        size_t one_percent = total * 0.01;
        while (itr != end) {
            auto sym = *itr;
            if (sym == 0) {
                sym = 0xFE;
                replaced_zeros++;
            }
            if (sym == 1) {
                replaced_ones++;
                sym = 0xFF;
            }
            out.push_back(sym);
            ++itr;
            ++processed;
            if (processed % one_percent == 0) {
                print_progress(double(processed) / double(total));
            }
        }
        std::cout << "\n";
        LOG(INFO) << "Replaced zeros = " << replaced_zeros;
        LOG(INFO) << "Replaced ones = " << replaced_ones;
        LOG(INFO) << "Copied " << out.size() << " bytes.";
    }
}

int main(int argc, char const* argv[])
{
    setup_logger(argc, argv);

    auto cmdargs = parse_cmdargs(argc, argv);
    auto input_file = cmdargs["input"].as<std::string>();
    auto col_dir = cmdargs["collection"].as<std::string>();
    auto output_prefix = cmdargs["output"].as<std::string>();
    auto dict_size_mb = cmdargs["dict"].as<uint32_t>();
    auto dict_size_bytes = dict_size_mb * 1024 * 1024;
    auto write_text = cmdargs.count("text") != 0;
    auto file_name = output_prefix + "-RLZ-D" + std::to_string(dict_size_mb);
    uint32_t max_int = std::numeric_limits<uint32_t>::max();
    if (cmdargs.count("maxint") != 0) {
        max_int = cmdargs["maxint"].as<uint32_t>();
    }

    /* parse the collection */
    create_collection(input_file, col_dir);
    std::cout << "Parsing collection directory " << col_dir << std::endl;
    collection col(col_dir);

    /* create rlz index */
    std::vector<uint32_t> lens;
    std::vector<uint32_t> offsets;
    const uint32_t factorization_blocksize = 64 * 1024;
    {
        auto rlz_store = rlz_store_static<
            dict_uniform_sample_budget<default_dict_sample_block_size>,
            dict_prune_none, dict_index_csa<>, factorization_blocksize, false,
            factor_select_first,
            factor_coder_blocked<3, coder::zlib<9>, coder::zlib<9>,
                coder::zlib<9>>,
            block_map_uncompressed>::builder {}
                             .set_threads(16)
                             .set_dict_size(dict_size_bytes)
                             .build_or_load(col);

        auto fitr = rlz_store.factors_begin();
        auto fend = rlz_store.factors_end();
        while (fitr != fend) {
            auto cur_factor = *fitr;
            if (!cur_factor.is_literal) {
                lens.push_back(cur_factor.len);
                offsets.push_back(cur_factor.offset);
                if (lens.size() >= max_int)
                    break;
            }
            ++fitr;
        }
    }

    {
        timer t("(5) write RLZ file");
        if (write_text) {

            write_file_text(lens, file_name + "-FLENS.txt");
            write_file_text(offsets, file_name + "-FOFFSETS.txt");
        } else {
            write_file_u32(lens, file_name + "-FLENS.u32");
            write_file_u32(offsets, file_name + "-FOFFSETS.u32");
        }
    }
}

max_stars_repo_name: mpetri/ans-large-alphabet

max_issues_repo_name: mpetri/ans-large-alphabet

max_forks_repo_name: mpetri/ans-large-alphabet


text:
/*
 * Neighbourhood.cpp
 *
 *  Created on: May 18, 2012
 *      Author: david
 */

#include "Neighbourhood.hpp"
#include "Metric.hpp"
#include <Slimage/Convert.hpp>
#include <boost/graph/copy.hpp>
#include <iostream>

namespace dasp
{

DaspGraph CreateDaspNeighbourhoodGraph(const Superpixels& superpixels)
{
	NeighbourhoodGraph gnb = CreateNeighborhoodGraph(superpixels, NeighborGraphSettings::NoCut());
	DaspGraph result;
	boost::copy_graph(gnb, result,
		boost::vertex_copy(
			[&superpixels,&gnb,&result](UndirectedWeightedGraph::vertex_descriptor src, DaspGraph::vertex_descriptor dst) {
				result[dst] = superpixels.cluster[src].center;
			}
		)
		.edge_copy(
			[&gnb,&result](UndirectedWeightedGraph::edge_descriptor src, DaspGraph::edge_descriptor dst) {
				result[dst] = 1.0f;
			}
		)
	);
	return result;
}

DaspGraph CreateDaspGraph(const Superpixels& superpixels, const UndirectedWeightedGraph& weighted_graph)
{
	DaspGraph result;
	boost::copy_graph(weighted_graph, result,
		boost::vertex_copy(
			[&superpixels,&weighted_graph,&result](UndirectedWeightedGraph::vertex_descriptor src, DaspGraph::vertex_descriptor dst) {
				result[dst] = superpixels.cluster[src].center;
			}
		)
		.edge_copy(
			[&weighted_graph,&result](UndirectedWeightedGraph::edge_descriptor src, DaspGraph::edge_descriptor dst) {
				result[dst] = weighted_graph[src];
			}
		)
	);
	return result;
}

DaspGraph ConvertToSimilarityGraph(const DaspGraph& source, const float sigma) {
	DaspGraph result;
	boost::copy_graph(source, result,
			boost::edge_copy([&source,&result,sigma](typename DaspGraph::edge_descriptor src, DaspGraph::edge_descriptor dst) {
				const float d = source[src];
				const float s = std::exp(-d/sigma);
				result[dst] = s;
	}));
	return result;
}

std::vector<unsigned int> ComputeAllBorderPixels(const Superpixels& superpixels)
{
	slimage::Image1i labels = superpixels.ComputeLabels();
	std::set<unsigned int> u;
	int face_neighbours[] = { -1, +1, -labels.width(), +labels.width() };
	for(unsigned int y=1; y<labels.height()-1; y++) {
		for(unsigned int x=1; x<labels.width()-1; x++) {
			int q = labels.index(x,y);
			unsigned int lc = labels[q];
			for(unsigned int i=0; i<4; i++) {
				if(labels[q + face_neighbours[i]] != lc) {
					u.insert(q);
				}
			}
		}
	}
	return std::vector<unsigned int>(u.begin(), u.end());
}

//std::vector<unsigned int> ComputeBorderPixels(const std::vector<unsigned int>& pixel_ids, unsigned int desired_neighbour_cid, const slimage::Image1i& labels)
//{
//	const int w = static_cast<int>(labels.width());
//	const int h = static_cast<int>(labels.height());
//	const int d[4] = { -1, +1, -w, +w };
//	std::vector<unsigned int> border;
//	for(unsigned int pid : pixel_ids) {
//		int x = pid % w;
//		int y = pid / w;
//		if(1 <= x && x+1 <= w && 1 <= y && y+1 <= h) {
//			for(int i=0; i<4; i++) {
//				int label = labels[pid + d[i]];
//				if(label == static_cast<int>(desired_neighbour_cid)) {
//					border.push_back(pid);
//				}
//			}
//		}
//	}
//	return border;
//}

struct BorderPixel
{
	unsigned int pixel_id;
	unsigned int label;
};

std::vector<BorderPixel> ComputeBorderLabels(unsigned int cid, const Superpixels& spc, const slimage::Image1i& labels)
{
	const int w = static_cast<int>(labels.width());
	const int h = static_cast<int>(labels.height());
	const int d[4] = { -1, +1, -w, +w };
	std::vector<BorderPixel> border;
	for(unsigned int pid : spc.cluster[cid].pixel_ids) {
		int x = pid % w;
		int y = pid / w;
		if(1 <= x && x+1 < w && 1 <= y && y+1 < h) {
			for(int i=0; i<4; i++) {
				int label = labels[pid + d[i]];
				if(label != cid && label != -1) {
					border.push_back(BorderPixel{pid, label});
				}
			}
		}
	}
	return border;
}

std::vector<std::vector<BorderPixel>> ComputeBorderLabels(const Superpixels& spc)
{
	slimage::Image1i labels = spc.ComputeLabels();
	std::vector<std::vector<BorderPixel>> border_pixels(spc.cluster.size());
	for(unsigned int cid=0; cid<spc.cluster.size(); cid++) {
		border_pixels[cid] = ComputeBorderLabels(cid, spc, labels);
	}
	return border_pixels;
}

std::vector<unsigned int> FindCommonBorder(const std::vector<std::vector<BorderPixel>>& border, unsigned int cid, unsigned cjd) {
	const std::vector<BorderPixel>& bi = border[cid];
	const std::vector<BorderPixel>& bj = border[cjd];
	std::vector<unsigned int> common;
	common.reserve(bi.size() + bj.size());
	for(const BorderPixel& q : bi) {
		if(q.label == cjd) {
			common.push_back(q.pixel_id);
		}
	}
	for(const BorderPixel& q : bi) {
		if(q.label == cjd) {
			common.push_back(q.pixel_id);
		}
	}
	return common;
}

NeighbourhoodGraph CreateNeighborhoodGraph(const Superpixels& superpixels, NeighborGraphSettings settings)
{
	// create one node for each superpixel
	NeighbourhoodGraph neighbourhood_graph(superpixels.clusterCount());
	// compute superpixel borders
	std::vector<std::vector<BorderPixel> > border = ComputeBorderLabels(superpixels);
	// connect superpixels
	const float spatial_distance_threshold = settings.spatial_distance_mult_threshold * superpixels.opt.base_radius;
	const float pixel_distance_mult_threshold = settings.pixel_distance_mult_threshold;
	for(unsigned int i=0; i<superpixels.cluster.size(); i++) {
		for(unsigned int j=i+1; j<superpixels.cluster.size(); j++) {
			const Point& c_i = superpixels.cluster[i].center;
			const Point& c_j = superpixels.cluster[j].center;
			// early test if the two superpixels are even near to each other
			if(settings.cut_by_spatial) {
				// spatial distance
				float d = (c_i.position - c_j.position).norm();
				// only test if distance is smaller than threshold
				if(d > spatial_distance_threshold) {
					continue;
				}
			}
			else {
				// pixel distance on camera image plane
				float d = std::sqrt(static_cast<float>(metric::PixelDistanceSquared(c_i,c_j)));
				// only test if pixel distance is smaller then C * pixel_radius
				float r = std::max(c_i.cluster_radius_px, c_j.cluster_radius_px);
				if(d > pixel_distance_mult_threshold * r) {
					continue;
				}
			}
			// compute intersection of border pixels
			std::vector<unsigned int> common_border = FindCommonBorder(border, i, j);
			// test if superpixels have a common border
			unsigned int common_border_size = common_border.size();
			if(common_border_size < settings.min_abs_border_overlap) {
				continue;
			}
			float p = static_cast<float>(common_border_size) / static_cast<float>(std::min(border[i].size(), border[j].size()));
			if(p < settings.min_border_overlap) {
				continue;
			}
			// add edge
			NeighbourhoodGraph::edge_descriptor eid;
			bool ok;
			boost::tie(eid,ok) = boost::add_edge(i, j, neighbourhood_graph); // FIXME correctly convert superpixel_id to vertex descriptor
			assert(ok);
			neighbourhood_graph[eid].num_border_pixels = common_border_size;
			neighbourhood_graph[eid].border_pixel_ids = common_border;
		}
	}
	return neighbourhood_graph;
}

}

max_stars_repo_name: jbellis/superpixel-benchmark

max_issues_repo_name: jbellis/superpixel-benchmark

max_forks_repo_name: jbellis/superpixel-benchmark


text:
//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc.

//Distributed under the Boost Software License, Version 1.0. (See accompanying
//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//This example shows how boost::error_info_group can be used to bundle
//the name of the function that fails together with the reported errno.

#include <boost/exception/info_tuple.hpp>
#include <boost/shared_ptr.hpp>
#include <stdio.h>
#include <string>
#include <errno.h>

typedef boost::error_info<struct tag_file_name,std::string> file_name_info;
typedef boost::error_info<struct tag_function,char const *> function_info;
typedef boost::error_info<struct tag_errno,int> errno_info;
typedef boost::tuple<function_info,errno_info> clib_failure;

class file_open_error: public boost::exception { };

boost::shared_ptr<FILE>
file_open( char const * name, char const * mode )
    {
    if( FILE * f=fopen(name,mode) )
        return boost::shared_ptr<FILE>(f,fclose);
    else
        throw file_open_error() <<
            file_name_info(name) <<
            clib_failure("fopen",errno);
    }


text:
#include "wrappers.h"

#include <GraphMol/GraphMol.h>
#include <GraphMol/MolOps.h>
#include <boost/optional.hpp>

#include <GraphMol/ChemTransforms/ChemTransforms.h>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/SmilesParse/SmilesWrite.h>

#include <pybind11/stl.h>

namespace py = pybind11;

using Atom = RDKit::Atom;
using Bond = RDKit::Bond;
using ROMol = RDKit::ROMol;
using RWMol = RDKit::RWMol;

namespace pybind11 {
namespace detail {
template <typename T>
struct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};
} // namespace detail
} // namespace pybind11

namespace {
std::shared_ptr<RWMol> MolFromSmiles(py::object ismiles, bool sanitize, py::dict replDict) {
    std::map<std::string, std::string> replacements;

    for (auto const &it : replDict) {
        replacements[py::str(it.first)] = py::str(it.second);
    }

    RDKit::RWMol *newM;
    std::string smiles = py::str(ismiles);

    try {
        newM = RDKit::SmilesToMol(smiles, 0, sanitize, &replacements);
    } catch (...) {
        newM = nullptr;
    }

    newM->updatePropertyCache();

    return std::shared_ptr<RWMol>(newM);
}

std::string MolFragmentToSmiles(const ROMol &mol, py::list atomsToUse,
                                boost::optional<std::vector<int>> bondsToUse,
                                boost::optional<std::vector<std::string>> atomSymbols,
                                boost::optional<std::vector<std::string>> bondSymbols,
                                bool doIsomericSmiles, bool doKekule, int rootedAtAtom,
                                bool canonical, bool allBondsExplicit, bool allHsExplicit) {
    std::vector<int> atoms = py::cast<std::vector<int>>(atomsToUse);

    return RDKit::MolFragmentToSmiles(mol, atoms, bondsToUse.get_ptr(), atomSymbols.get_ptr(),
                                      bondSymbols.get_ptr(), doIsomericSmiles, doKekule,
                                      rootedAtAtom, canonical, allBondsExplicit, allHsExplicit);
}

std::vector<std::vector<int>> getSymmSssr(ROMol &mol) {
    std::vector<std::vector<int>> result;
    RDKit::MolOps::symmetrizeSSSR(mol, result);
    return result;
}

RDKit::MolOps::SanitizeFlags sanitizeMol(RWMol &mol, RDKit::MolOps::SanitizeFlags sanitizeOps) {
    unsigned int failedOperations;
    RDKit::MolOps::sanitizeMol(mol, failedOperations, sanitizeOps);
    return static_cast<RDKit::MolOps::SanitizeFlags>(failedOperations);
}
} // namespace

void genric::register_molops(py::module &m) {
    py::enum_<RDKit::MolOps::SanitizeFlags>(m, "SanitizeFlags", py::arithmetic())
        .value("SANITIZE_NONE", RDKit::MolOps::SANITIZE_NONE)
        .value("SANITIZE_CLEANUP", RDKit::MolOps::SANITIZE_CLEANUP)
        .value("SANITIZE_PROPERTIES", RDKit::MolOps::SANITIZE_PROPERTIES)
        .value("SANITIZE_SYMMRINGS", RDKit::MolOps::SANITIZE_SYMMRINGS)
        .value("SANITIZE_KEKULIZE", RDKit::MolOps::SANITIZE_KEKULIZE)
        .value("SANITIZE_FINDRADICALS", RDKit::MolOps::SANITIZE_FINDRADICALS)
        .value("SANITIZE_SETAROMATICITY", RDKit::MolOps::SANITIZE_SETAROMATICITY)
        .value("SANITIZE_SETCONJUGATION", RDKit::MolOps::SANITIZE_SETCONJUGATION)
        .value("SANITIZE_SETHYBRIDIZATION", RDKit::MolOps::SANITIZE_SETHYBRIDIZATION)
        .value("SANITIZE_CLEANUPCHIRALITY", RDKit::MolOps::SANITIZE_CLEANUPCHIRALITY)
        .value("SANITIZE_ADJUSTHS", RDKit::MolOps::SANITIZE_ADJUSTHS)
        .value("SANITIZE_ALL", RDKit::MolOps::SANITIZE_ALL)
        .export_values();

    m.def("MolFromSmiles", &MolFromSmiles, py::arg("SMILES"), py::arg("sanitize") = true,
          py::arg("replacements") = py::dict());

    m.def("MolToSmiles", &RDKit::MolToSmiles, py::arg("mol"), py::arg("isomericSmiles") = true,
          py::arg("kekuleSmiles") = false, py::arg("rootedAtAtom") = -1,
          py::arg("canonical") = true, py::arg("allBondsExplicit") = false,
          py::arg("allHsExplicit") = false, py::arg("doRandom") = false);

    m.def("MolFragmentToSmiles", &MolFragmentToSmiles, py::arg("mol"), py::arg("atomsToUse"),
          py::arg("bondsToUse") = py::none(), py::arg("atomSymbols") = py::none(),
          py::arg("bondSymbols") = py::none(), py::arg("isomericSmiles") = false,
          py::arg("kekuleSmiles") = false, py::arg("rootedAtAtom") = -1,
          py::arg("canonical") = true, py::arg("allBondsExplicit") = false,
          py::arg("allHsExplicit") = false);

    m.def("Kekulize", RDKit::MolOps::Kekulize, py::arg("mol"),
          py::arg("clearAromaticFlags") = false, py::arg("maxBackTracks") = 100);

    py::class_<RDGeom::Point3D>(m, "Point3D")
        .def(py::init<>())
        .def(py::init<double, double, double>())
        .def_readwrite("x", &RDGeom::Point3D::x)
        .def_readwrite("y", &RDGeom::Point3D::y)
        .def_readwrite("z", &RDGeom::Point3D::z);

    m.def("CombineMols", RDKit::combineMols, py::arg("mol1"), py::arg("mol2"),
          py::arg("offset") = RDGeom::Point3D(0, 0, 0));

    m.def("GetSymmSSSR", &getSymmSssr);
    m.def("SanitizeMol", &sanitizeMol, py::arg("mol"),
          py::arg("sanitizeOps") = RDKit::MolOps::SANITIZE_ALL);
}


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

#include <properties.h>

#include <logging.h>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/algorithm/string/trim.hpp>

typedef std::pair<std::string,std::string> StdPair;
BOOST_FUSION_ADAPT_STRUCT(
    StdPair,
    (std::string, first)
    (std::string, second)
)

namespace piel { namespace lib {

struct JavaPropertiesConstants {
    static const char comment;
    static const char assign;
    static const char endl;
};

const char JavaPropertiesConstants::comment = '#';
const char JavaPropertiesConstants::assign = '=';
const char JavaPropertiesConstants::endl = '\n';

namespace java_properties {

    namespace qi = boost::spirit::qi;

    std::string trim_str(const std::string& input) {
        std::string result = input;
        boost::algorithm::trim(result);
        return result;
    }
    BOOST_PHOENIX_ADAPT_FUNCTION(std::string, trim_str_, trim_str, 1)

    template<typename Iterator>
    struct grammar: qi::grammar<Iterator, StdPair()> {
        grammar(): grammar::base_type(_data)
        {
            using qi::char_;
            using qi::space;
            using qi::skip;
            using qi::_1;
            using qi::_val;
            using qi::as_string;
            using boost::phoenix::ref;

            _syms       = (char_(JavaPropertiesConstants::assign)|char_(JavaPropertiesConstants::comment));
            _comment    = skip[JavaPropertiesConstants::comment > -( +( char_ ) ) ];
            _first      = as_string[ +( char_ - _syms ) > skip[ JavaPropertiesConstants::assign ] ]         [ _val = trim_str_(_1) ];
            _second     = as_string[ +( char_ - JavaPropertiesConstants::comment ) ]                        [ _val = trim_str_(_1) ];
            _data       = -( _first > -_second ) | -_comment;
        }

    private:
        qi::rule<Iterator>                                      _syms;
        qi::rule<Iterator>                                      _comment;
        qi::rule<Iterator, std::string()>                       _first;
        qi::rule<Iterator, std::string()>                       _second;
        qi::rule<Iterator, StdPair()>                           _data;
    };

} // namespace java_properties

Properties::Properties()
    : data_()
{
}

Properties::Properties(const Properties& src)
    : data_(src.data_)
{

}

Properties::~Properties()
{
}

Properties Properties::load(std::istream &is)
{
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

    Properties result;

    std::string buffer;
    java_properties::grammar<std::string::iterator> java_properties_grammar;

    while (is) {
        StdPair pair;
        std::getline(is, buffer);
        LOGT << "buffer: " << buffer << ELOG;
        qi::phrase_parse( buffer.begin(), buffer.end(), java_properties_grammar, ascii::space, pair );
        if (!pair.first.empty())
        {
            result.data_[pair.first] = pair.second;
        }
        LOGT << "'"<< pair.first << "' = '" << pair.second << "'" << ELOG;
    }

    return result;
}

void Properties::store(std::ostream &os) const
{
    for(MapType::const_iterator i = data_.begin(), end = data_.end(); i != end; ++i)
    {
        if (!i->first.empty() && !i->second.empty())
        {
            os << i->first << JavaPropertiesConstants::assign << i->second << JavaPropertiesConstants::endl;
        }
    }
}

void Properties::set(const Property::name_type& name, const Property::value_type& value)
{
    data_[name] = value;
}

Properties::Property::value_type Properties::get(const Property::name_type& name, const Property::value_type& default_value) const
{
    if (data_.find(name) == data_.end())
    {
        return default_value;
    }
    else
    {
        return data_.at(name);
    }
}

bool Properties::contains(const Property::name_type& name) const
{
    return data_.find(name) != data_.end();
}

const Properties::MapType& Properties::data() const
{
    return data_;
}

Properties::MapType& Properties::data()
{
    return data_;
}

Properties::MapType::mapped_type& Properties::operator[](const Properties::MapType::key_type& key)
{
    return data_[key];
}

void Properties::clear()
{
    data_.clear();
}

} } //namespace piel::lib

max_stars_repo_name: diakovliev/pie

max_issues_repo_name: diakovliev/pie

max_forks_repo_name: diakovliev/pie