text:
/*
 * supervoxel_clustering.cpp
 *
 *  Created on: 10/05/2015
 *      Author: Francesco Verdoja <francesco.verdoja@aalto.fi>
 *    Based on: example_supervoxels.cpp from PointCloudLibrary:
 *              https://github.com/PointCloudLibrary/pcl/commits/master/
 *                      examples/segmentation/example_supervoxels.cpp
 *
 *
 * BSD 3-Clause License
 *
 * Copyright (c) 2015, Francesco Verdoja
 * 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 copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/common/time.h>
#include <pcl/console/parse.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/png_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/supervoxel_clustering.h>

#include <vtkImageReader2Factory.h>
#include <vtkImageReader2.h>
#include <vtkImageData.h>
#include <vtkImageFlip.h>
#include <vtkPolyLine.h>

//#include <boost/filesystem.hpp>

#include "supervoxel_clustering/clustering.h"
#include "supervoxel_clustering/testing.h"

using namespace boost;
using namespace pcl;

typedef PointXYZRGBA PointT;
typedef PointCloud<PointT> PointCloudT;
typedef PointNormal PointNT;
typedef PointCloud<PointNT> PointNCloudT;
typedef PointXYZL PointLT;
typedef PointCloud<PointLT> PointLCloudT;
typedef PointXYZRGBL PointLCT;
typedef PointCloud<PointLCT> PointLCCloudT;

bool show_voxel_centroids = false;
bool show_segmentation = true;
bool show_supervoxels = false;
bool show_supervoxel_normals = false;
bool show_graph = true;
bool show_help = false;
float start_thresh = 0.8;
float end_thresh = 1;
float step_thresh = 0.005;

void keyboard_callback(const visualization::KeyboardEvent& event, void*) {
    int key = event.getKeyCode();

    if (event.keyUp())
        switch (key) {
            case (int) '1':
                show_voxel_centroids = !show_voxel_centroids;
                break;
            case (int) '2':
                show_segmentation = !show_segmentation;
                break;
            case (int) '3':
                show_graph = !show_graph;
                break;
            case (int) '4':
                show_supervoxel_normals = !show_supervoxel_normals;
                break;
            case (int) '0':
                show_supervoxels = !show_supervoxels;
                break;
            case (int) 'h':
            case (int) 'H':
                show_help = !show_help;
                break;
            default:
                break;
        }
}

inline bool isNan(float f) {
    return f != f;
}

void manageAllPerformances(
        std::vector<std::map<float, performanceSet> > all_performances,
        std::string filename);
void printBestPerformances(std::vector<performanceSet> best_performances);

void addSupervoxelConnectionsToViewer(PointT &supervoxel_center,
        PointCloudT &adjacent_supervoxel_centers, std::string supervoxel_name,
        shared_ptr<visualization::PCLVisualizer> & viewer);

void visualize(std::map<uint32_t, Supervoxel<PointT>::Ptr> supervoxel_clusters,
        PointCloudT::Ptr colored_cloud, PointCloudT::Ptr segm_cloud,
        PointCloudT::Ptr truth_cloud, PointNCloudT::Ptr normal_cloud,
        std::multimap<uint32_t, uint32_t> adjacency);

void printText(shared_ptr<visualization::PCLVisualizer> viewer);
void removeText(shared_ptr<visualization::PCLVisualizer> viewer);

int main(int argc, char ** argv) {
    if (argc < 3) {
        console::print_info(
                "Syntax is: "
                "%s {-d <direcory-of-pcd-files> OR -p <pcd-file>} [arguments] \n"
                "\n\t"
                "SUPERVOXEL optional arguments: \n\t"
                " -v <voxel-resolution>          (default: 0.008) \n\t"
                " -s <seed-resolution>           (default: 0.08) \n\t"
                " -c <color-weight>              (default: 0.2) \n\t"
                " -z <spatial-weight>            (default: 0.4) \n\t"
                " -n <normal-weight>             (default: 1.0) \n\t"
                "\n\t"
                "SEGMENTATION optional arguments: \n\t"
                " -t <threshold>                 (default: auto)\n\t"
                " --RGB                          (uses the RGB color space for "
                "measuring the color distance; if not given, L*A*B* color "
                "space is used) \n\t"
                " --CVX                          (uses the convexity criterion "
                "to weigh the geometric distance; if not given, convexity is "
                "not considered) \n\t"
                " --ML [manual-lambda] *         (uses Manual Lambda as "
                "merging criterion; if no parameter is given, lambda=0.5 is "
                "used) \n\t"
                " --AL                 *         (uses Adaptive lambda as "
                "merging criterion) \n\t"
                " --EQ [bins-number]   *         (uses Equalization as merging "
                "criterion; if no parameter is given, 200 bins are used) \n\t"
                "  * please note that only one of these arguments can be passed "
                "at the same time \n\t"
                "\n\t"
                "OTHER optional arguments: \n\t"
                " -r <label-to-be-removed>       (if ground-truth is provided, "
                "removes all points with the given label from the "
                "ground-truth)\n\t"
                " -f <test-results-filename>     (uses the given name as "
                "filename for all test results files; if not given, 'test' is "
                "going to be used)\n\t"
                " --NT                           (disables use of single "
                "camera transform) \n\t"
                " --V                            (verbose) \n",
                argv[0]);
        return (1);
    }

    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////
    ////// Input handling
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////

    bool verbose = console::find_switch(argc, argv, "--V");
    if (verbose) {
        console::setVerbosityLevel(console::L_DEBUG);
    }

    bool disable_transform = console::find_switch(argc, argv, "--NT");

    std::string test_filename = "test";
    if (console::find_switch(argc, argv, "-f"))
        console::parse(argc, argv, "-f", test_filename);

    // Input parameters
    PointCloudT::Ptr cloud = make_shared<PointCloudT>();
    PointLCloudT::Ptr truth_cloud = make_shared<PointLCloudT>();
    PointLCCloudT::Ptr input_cloud = make_shared<PointLCCloudT>();

    std::string path;
    std::vector<std::string> file_list;

    bool directory_specified = console::find_switch(argc, argv, "-d");
    bool pcd_file_specified = console::find_switch(argc, argv, "-p");

    if (directory_specified) {
        console::parse(argc, argv, "-d", path);
        console::print_info("Counting files in directory...\n");
        if (!filesystem::exists(path) || !filesystem::is_directory(path)) {
            console::print_error(
                    "Specified directory doesn't exists or can't be opened\n");
            return (1);
        }

        filesystem::recursive_directory_iterator it(path);
        filesystem::recursive_directory_iterator end_it;
        for (; it != end_it; ++it) {
            if (filesystem::is_regular_file(*it)
                    && it->path().extension() == ".pcd") {
                file_list.push_back(it->path().string());
                console::print_debug("File found: %s\n", it->path().c_str());
            }
        }
        console::print_info("Found %d files\n", file_list.size());
    } else if (pcd_file_specified) {
        console::parse(argc, argv, "-p", path);
        file_list.push_back(path);
    } else {
        console::print_error("No input file or directory specified\n");
        return (1);
    }

    bool thresh_specified = console::find_switch(argc, argv, "-t");
    float thresh = 0;

    if (thresh_specified) {
        console::parse_argument(argc, argv, "-t", thresh);
        console::print_debug("Using threshold: %f\n", thresh);
    } else {
        console::print_debug("Using automatic threshold\n");
    }

    // Supervoxel segmentation parameters
    float voxel_resolution = 0.008f;
    bool voxel_res_specified = console::find_switch(argc, argv, "-v");
    if (voxel_res_specified)
        console::parse(argc, argv, "-v", voxel_resolution);

    float seed_resolution = 0.08f;
    bool seed_res_specified = console::find_switch(argc, argv, "-s");
    if (seed_res_specified)
        console::parse(argc, argv, "-s", seed_resolution);

    float color_importance = 0.2f;
    if (console::find_switch(argc, argv, "-c"))
        console::parse(argc, argv, "-c", color_importance);

    float spatial_importance = 0.4f;
    if (console::find_switch(argc, argv, "-z"))
        console::parse(argc, argv, "-z", spatial_importance);

    float normal_importance = 1.0f;
    if (console::find_switch(argc, argv, "-n"))
        console::parse(argc, argv, "-n", normal_importance);

    // Segmentation parameters
    bool rgb_color_space_specified = console::find_switch(argc, argv, "--RGB");
    bool convexity_specified = console::find_switch(argc, argv, "--CVX");
    bool manual_lambda_specified = console::find_switch(argc, argv, "--ML");
    bool adapt_lambda_specified = console::find_switch(argc, argv, "--AL");
    bool equalization_specified = console::find_switch(argc, argv, "--EQ");
    if (!(manual_lambda_specified || adapt_lambda_specified
            || equalization_specified)) {
        adapt_lambda_specified = true;
        console::print_debug("No merging criterion specified, Adaptive Lambda "
                "is going to be used\n");
    } else if (!(manual_lambda_specified ^ adapt_lambda_specified
            ^ equalization_specified)) {
        console::print_error("Only one parameter between --ML --AL and --EQ "
                "can be specified at a time\n");
        return (1);
    }

    float lambda = 0;
    if (manual_lambda_specified)
        console::parse_argument(argc, argv, "--ML", lambda);

    int bin_num = 0;
    if (equalization_specified)
        console::parse_argument(argc, argv, "--EQ", bin_num);

    bool remove_label = console::find_switch(argc, argv, "-r");
    uint32_t label_to_be_removed = 0;
    if (remove_label)
        console::parse_argument(argc, argv, "-r", label_to_be_removed);

    std::vector<performanceSet> best_performances;
    std::vector<std::map<float, performanceSet> > all_performances;
    std::vector<std::string>::iterator file_it = file_list.begin();
    for (; file_it != file_list.end(); ++file_it) {

        ////////////////////////////////////////////////////////////
        ////// File reading
        ////////////////////////////////////////////////////////////

        bool has_label = true; //TODO should be false

        console::print_info("Loading pointcloud from PCD file '%s'...\n",
                file_it->c_str());
        pcl::io::loadPCDFile(*file_it, *input_cloud);
        PointLCCloudT::Ptr cloud_temp = make_shared<PointLCCloudT>();
        PointLCCloudT::iterator cloud_itr = input_cloud->begin();
        for (; cloud_itr != input_cloud->end(); ++cloud_itr) {
            if (cloud_itr->z < 0) {
                console::print_debug(
                        "Found point with z<0, setting to absolute value\n");
                cloud_itr->z = std::abs(cloud_itr->z);
            }
            /*
             * TODO
             * this doesn't work if label = 0 exists and is the one to be
             * removed
             */
            if (!has_label && cloud_itr->label != 0) {
                console::print_debug("Found label data, evaluation is going "
                        "to be performed\n");
                has_label = true;
            }
            if (!has_label || !remove_label
                    || (cloud_itr->label != label_to_be_removed
                    && !isNan(cloud_itr->z))) {
                cloud_temp->push_back(*cloud_itr);
            }
        }

        copyPointCloud(*cloud_temp, *cloud);
        copyPointCloud(*cloud_temp, *truth_cloud);

        console::print_info("Pointcloud loaded\n");

        ////////////////////////////////////////////////////////////
        ////// Supervoxel generation
        ////////////////////////////////////////////////////////////

        SupervoxelClustering<PointT> super(voxel_resolution, seed_resolution);
        super.setUseSingleCameraTransform(!disable_transform);
        super.setInputCloud(cloud);
        super.setColorImportance(color_importance);
        super.setSpatialImportance(spatial_importance);
        super.setNormalImportance(normal_importance);
        std::map<uint32_t, Supervoxel<PointT>::Ptr> supervoxel_clusters;

        console::print_info("Extracting supervoxels...\n");
        super.extract(supervoxel_clusters);
        console::print_info("Found %d supervoxels\n",
                supervoxel_clusters.size());
        PointCloudT::Ptr voxel_centroid_cloud = super.getVoxelCentroidCloud();
        PointNCloudT::Ptr sv_normal_cloud = super.makeSupervoxelNormalCloud(
                supervoxel_clusters);
        PointLCloudT::Ptr full_labeled_cloud = super.getLabeledCloud();

        console::print_info("Getting supervoxel adjacency...\n");
        std::multimap<uint32_t, uint32_t> label_adjacency;
        super.getSupervoxelAdjacency(label_adjacency);

        std::map<uint32_t, Supervoxel<PointT>::Ptr> refined_supervoxel_clusters;
        console::print_info("Refining supervoxels...\n");
        super.refineSupervoxels(3, refined_supervoxel_clusters);

        PointNCloudT::Ptr refined_sv_normal_cloud =
                super.makeSupervoxelNormalCloud(refined_supervoxel_clusters);
        PointLCloudT::Ptr refined_full_labeled_cloud = super.getLabeledCloud();

        console::print_info(
                "Constructing Boost Graph Library Adjacency List...\n");
        typedef adjacency_list<setS, setS, undirectedS, uint32_t, float>
                VoxelAdjacencyList;
        typedef VoxelAdjacencyList::vertex_descriptor VoxelID;
        typedef VoxelAdjacencyList::edge_descriptor EdgeID;
        VoxelAdjacencyList supervoxel_adjacency_list;
        super.getSupervoxelAdjacencyList(supervoxel_adjacency_list);

        // Voxelizing ground truth cloud
        PointCloudT::Ptr colored_truth_cloud = Clustering::label2color(
                truth_cloud);
        SupervoxelClustering<PointT> super_label(voxel_resolution,
                seed_resolution);
        super_label.setUseSingleCameraTransform(!disable_transform);
        super_label.setInputCloud(colored_truth_cloud);
        super_label.setColorImportance(color_importance);
        super_label.setSpatialImportance(spatial_importance);
        super_label.setNormalImportance(normal_importance);
        std::map<uint32_t, Supervoxel<PointT>::Ptr> supervoxel_label_clusters;
        super_label.extract(supervoxel_label_clusters);
        colored_truth_cloud = super_label.getVoxelCentroidCloud();
        truth_cloud = Clustering::color2label(colored_truth_cloud);
        colored_truth_cloud = Clustering::label2color(truth_cloud);

        ////////////////////////////////////////////////////////////
        ////// Segmentation
        ////////////////////////////////////////////////////////////

        console::print_info("Segmentation initialization...\n");

        Clustering segmentation;
        if (rgb_color_space_specified)
            segmentation.set_delta_c(RGB_EUCL);

        if (convexity_specified)
            segmentation.set_delta_g(CONVEX_NORMALS_DIFF);

        if (manual_lambda_specified) {
            segmentation.set_merging(MANUAL_LAMBDA);
            if (lambda != 0)
                segmentation.set_lambda(lambda);
        } else if (equalization_specified) {
            segmentation.set_merging(EQUALIZATION);
            if (bin_num != 0)
                segmentation.set_bins_num(bin_num);
        }
        segmentation.set_initialstate(supervoxel_clusters, label_adjacency);
        if (manual_lambda_specified || adapt_lambda_specified)
            console::print_debug("Lambda: %f\n", segmentation.get_lambda());

        if (!thresh_specified) {
            std::map<float, performanceSet> all = segmentation.all_thresh(
                    truth_cloud, start_thresh, end_thresh, step_thresh);
            all_performances.push_back(all);
            std::pair<float, performanceSet> best = segmentation.best_thresh(
                    all);
            console::print_info(
                    "Using best threshold: %f (F-score %f, voi %f)\n",
                    best.first, best.second.fscore, best.second.voi);
            thresh = best.first;
        }

        console::print_info(
                "Initialization complete\nStarting clustering...\n");

        segmentation.cluster(thresh);
        console::print_info("Clustering complete\n");
        std::pair<ClusteringT, AdjacencyMapT> s =
                segmentation.get_currentstate();

        PointCloudT::Ptr colored_voxel_cloud = segmentation.get_colored_cloud();
        label_adjacency = s.second;

        ////////////////////////////////////////////////////////////
        ////// Testing
        ////////////////////////////////////////////////////////////

        console::print_info("Initializing testing suite...\n");
        Testing test(segmentation.get_labeled_cloud(), truth_cloud);
        best_performances.push_back(test.eval_performance());

        ////////////////////////////////////////////////////////////
        ////// Visualization
        ////////////////////////////////////////////////////////////

        if (file_list.size() == 1) {
            console::print_info("Loading visualization...\n");
            visualize(supervoxel_clusters, voxel_centroid_cloud,
                    colored_voxel_cloud, colored_truth_cloud,
                    refined_sv_normal_cloud, label_adjacency);
        }
    }

    manageAllPerformances(all_performances, test_filename);

    printBestPerformances(best_performances);

    return (0);
}

void manageAllPerformances(
        std::vector<std::map<float, performanceSet> > all_performances,
        std::string filename) {
    ofstream file_voi((filename + "_voi.csv").c_str());
    ofstream file_prec((filename + "_precision.csv").c_str());
    ofstream file_recall((filename + "_recall.csv").c_str());
    ofstream file_fscore((filename + "_fscore.csv").c_str());
    ofstream file_wov((filename + "_wov.csv").c_str());
    ofstream file_fpr((filename + "_fpr.csv").c_str());
    ofstream file_fnr((filename + "_fnr.csv").c_str());

    std::vector<std::map<float, performanceSet> >::iterator p_it =
            all_performances.begin();
    for (; p_it != all_performances.end(); ++p_it) {
        std::map<float, performanceSet>::iterator m_it = p_it->begin();
        for (; m_it != p_it->end(); ++m_it) {
            file_voi << m_it->second.voi << ";";
            file_prec << m_it->second.precision << ";";
            file_recall << m_it->second.recall << ";";
            file_fscore << m_it->second.fscore << ";";
            file_wov << m_it->second.wov << ";";
            file_fpr << m_it->second.fpr << ";";
            file_fnr << m_it->second.fnr << ";";
        }
        file_voi << "\n";
        file_prec << "\n";
        file_recall << "\n";
        file_fscore << "\n";
        file_wov << "\n";
        file_fpr << "\n";
        file_fnr << "\n";

    }
    file_voi.close();
    file_prec.close();
    file_recall.close();
    file_fscore.close();
    file_wov.close();
    file_fpr.close();
    file_fnr.close();
}

void printBestPerformances(std::vector<performanceSet> best_performances) {
    if (best_performances.size() == 1) {
        performanceSet p = best_performances.back();
        console::print_info(
                "Scores:\nVOI\t%f\nPrec.\t%f\nRecall\t%f\nF-score\t%f\n"
                "WOv\t%f\nFPR\t%f\nFNR\t%f\n",
                p.voi, p.precision, p.recall, p.fscore, p.wov, p.fpr, p.fnr);
    } else {
        std::vector<performanceSet>::iterator p_it = best_performances.begin();
        float mean_v = 0;
        float mean_p = 0;
        float mean_r = 0;
        float mean_f = 0;
        float mean_w = 0;
        float mean_pr = 0;
        float mean_nr = 0;
        int count = 0;
        for (; p_it != best_performances.end(); ++p_it) {
            count++;
            mean_v = mean_v + (1 / count) * (p_it->voi - mean_v);
            mean_p = mean_p + (1 / count) * (p_it->precision - mean_p);
            mean_r = mean_r + (1 / count) * (p_it->recall - mean_r);
            mean_f = mean_f + (1 / count) * (p_it->fscore - mean_f);
            mean_w = mean_w + (1 / count) * (p_it->wov - mean_w);
            mean_pr = mean_pr + (1 / count) * (p_it->fpr - mean_pr);
            mean_nr = mean_nr + (1 / count) * (p_it->fnr - mean_nr);
            console::print_debug(
                    "Scores:\nVOI\t%f\nPrec.\t%f\nRecall\t%f\nF-score\t%f\n"
                    "WOv\t%f\nFPR\t%f\nFNR\t%f\n",
                    p_it->voi, p_it->precision, p_it->recall, p_it->fscore,
                    p_it->wov, p_it->fpr, p_it->fnr);
        }
        console::print_info(
                "Average scores:\nVOI\t%f\nPrec.\t%f\nRecall\t%f\nF-score\t%f\n"
                "WOv\t%f\nFPR\t%f\nFNR\t%f\n",
                mean_v, mean_p, mean_r, mean_f, mean_w, mean_pr, mean_nr);
    }
}

void addSupervoxelConnectionsToViewer(PointT &supervoxel_center,
        PointCloudT &adjacent_supervoxel_centers, std::string supervoxel_name,
        shared_ptr<visualization::PCLVisualizer> & viewer) {
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New();

    // Iterate through all adjacent points, and add a center point to adjacent
    // point pair
    PointCloudT::iterator adjacent_itr = adjacent_supervoxel_centers.begin();
    for (; adjacent_itr != adjacent_supervoxel_centers.end(); ++adjacent_itr) {
        points->InsertNextPoint(supervoxel_center.data);
        points->InsertNextPoint(adjacent_itr->data);
    }
    // Create a polydata to store everything in
    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    // Add the points to the dataset
    polyData->SetPoints(points);
    polyLine->GetPointIds()->SetNumberOfIds(points->GetNumberOfPoints());
    for (unsigned int i = 0; i < points->GetNumberOfPoints(); i++)
        polyLine->GetPointIds()->SetId(i, i);
    cells->InsertNextCell(polyLine);
    // Add the lines to the dataset
    polyData->SetLines(cells);
    viewer->addModelFromPolyData(polyData, supervoxel_name);
}

void visualize(std::map<uint32_t, Supervoxel<PointT>::Ptr> supervoxel_clusters,
        PointCloudT::Ptr colored_cloud, PointCloudT::Ptr segm_cloud,
        PointCloudT::Ptr truth_cloud, PointNCloudT::Ptr normal_cloud,
        std::multimap<uint32_t, uint32_t> adjacency) {
    shared_ptr<visualization::PCLVisualizer> viewer(
            new visualization::PCLVisualizer("3D Viewer"));
    viewer->setBackgroundColor(0, 0, 0);
    viewer->registerKeyboardCallback(keyboard_callback, 0);

    bool graph_added = false;
    std::vector<std::string> poly_names;
    console::print_info("Loading viewer...\n");
    while (!viewer->wasStopped()) {
        if (show_voxel_centroids) {
            if (!viewer->updatePointCloud(colored_cloud, "voxel centroids"))
                viewer->addPointCloud(colored_cloud, "voxel centroids");
            viewer->setPointCloudRenderingProperties(
                    visualization::PCL_VISUALIZER_POINT_SIZE, 2.0,
                    "voxel centroids");
            if (show_segmentation)
                viewer->setPointCloudRenderingProperties(
                    visualization::PCL_VISUALIZER_OPACITY, 0.5,
                    "voxel centroids");
            else
                viewer->setPointCloudRenderingProperties(
                    visualization::PCL_VISUALIZER_OPACITY, 1.0,
                    "voxel centroids");
        } else {
            viewer->removePointCloud("voxel centroids");
        }

        if (show_segmentation) {
            if (!viewer->updatePointCloud(
                    (show_supervoxels) ? truth_cloud : segm_cloud,
                    "colored voxels"))
                viewer->addPointCloud(
                    (show_supervoxels) ? truth_cloud : segm_cloud,
                    "colored voxels");
            viewer->setPointCloudRenderingProperties(
                    visualization::PCL_VISUALIZER_POINT_SIZE, 2.0,
                    "colored voxels");
            viewer->setPointCloudRenderingProperties(
                    visualization::PCL_VISUALIZER_OPACITY, 0.9,
                    "colored voxels");
        } else {
            viewer->removePointCloud("colored voxels");
        }

        if (show_supervoxel_normals) {
            viewer->addPointCloudNormals<PointNormal>(normal_cloud, 1, 0.05f,
                    "supervoxel_normals");
        } else if (!show_supervoxel_normals) {
            viewer->removePointCloud("supervoxel_normals");
        }

        if (show_graph && !graph_added) {
            poly_names.clear();
            std::multimap<uint32_t, uint32_t>::iterator label_itr =
                    adjacency.begin();
            for (; label_itr != adjacency.end();) {
                // First get the label
                uint32_t supervoxel_label = label_itr->first;
                // Now get the supervoxel corresponding to the label
                Supervoxel<PointT>::Ptr supervoxel = supervoxel_clusters.at(
                        supervoxel_label);
                // Now we need to iterate through the adjacent supervoxels and
                // make a point cloud of them
                PointCloudT adjacent_supervoxel_centers;
                std::multimap<uint32_t, uint32_t>::iterator adjacent_itr =
                        adjacency.equal_range(supervoxel_label).first;
                for (;
                        adjacent_itr
                        != adjacency.equal_range(supervoxel_label).second;
                        ++adjacent_itr) {
                    Supervoxel<PointT>::Ptr neighbor_supervoxel =
                            supervoxel_clusters.at(adjacent_itr->second);
                    adjacent_supervoxel_centers.push_back(
                            neighbor_supervoxel->centroid_);
                }
                // Now we make a name for this polygon
                std::stringstream ss;
                ss << "supervoxel_" << supervoxel_label;
                poly_names.push_back(ss.str());
                addSupervoxelConnectionsToViewer(supervoxel->centroid_,
                        adjacent_supervoxel_centers, ss.str(), viewer);
                // Move iterator forward to next label
                label_itr = adjacency.upper_bound(supervoxel_label);
            }

            graph_added = true;
        } else if (!show_graph && graph_added) {
            for (std::vector<std::string>::iterator name_itr =
                    poly_names.begin(); name_itr != poly_names.end();
                    ++name_itr) {
                viewer->removeShape(*name_itr);
            }
            graph_added = false;
        }

        if (show_help) {
            viewer->removeShape("help_text");
            printText(viewer);
        } else {
            removeText(viewer);
            if (!viewer->updateText("Press h to show help", 5, 10, 12, 1.0, 1.0,
                    1.0, "help_text"))
                viewer->addText("Press h to show help", 5, 10, 12, 1.0, 1.0,
                    1.0, "help_text");
        }

        viewer->spinOnce(100);
        this_thread::sleep(posix_time::microseconds(100000));

    }
}

void printText(shared_ptr<visualization::PCLVisualizer> viewer) {
    std::string on_str = "ON";
    std::string off_str = "OFF";
    std::string temp =
            "Press (1-n) to show different elements, (h) to hide this";
    if (!viewer->updateText(temp, 5, 72, 12, 1.0, 1.0, 1.0, "hud_text"))
        viewer->addText(temp, 5, 72, 12, 1.0, 1.0, 1.0, "hud_text");

    temp = "(1) Voxels currently "
            + ((show_voxel_centroids) ? on_str : off_str);
    if (!viewer->updateText(temp, 5, 60, 10, 1.0, 1.0, 1.0, "voxel_text"))
        viewer->addText(temp, 5, 60, 10, 1.0, 1.0, 1.0, "voxel_text");

    temp = "(2) Segmentation currently "
            + ((show_segmentation) ? on_str : off_str);
    if (!viewer->updateText(temp, 5, 50, 10, 1.0, 1.0, 1.0, "supervoxel_text"))
        viewer->addText(temp, 5, 50, 10, 1.0, 1.0, 1.0, "supervoxel_text");

    temp = "(3) Graph currently " + ((show_graph) ? on_str : off_str);
    if (!viewer->updateText(temp, 5, 40, 10, 1.0, 1.0, 1.0, "graph_text"))
        viewer->addText(temp, 5, 40, 10, 1.0, 1.0, 1.0, "graph_text");

    temp = "(4) Supervoxel Normals currently "
            + ((show_supervoxel_normals) ? on_str : off_str);
    if (!viewer->updateText(temp, 5, 30, 10, 1.0, 1.0, 1.0,
            "supervoxel_normals_text"))
        viewer->addText(temp, 5, 30, 10, 1.0, 1.0, 1.0,
            "supervoxel_normals_text");

    temp = "(0) Toggle between supervoxels and segmentation: currently showing "
            + std::string((show_supervoxels) ? "SUPERVOXELS" : "SEGMENTATION");
    if (!viewer->updateText(temp, 5, 7, 10, 1.0, 1.0, 1.0, "refined_text"))
        viewer->addText(temp, 5, 7, 10, 1.0, 1.0, 1.0, "refined_text");

}

void removeText(shared_ptr<visualization::PCLVisualizer> viewer) {
    viewer->removeShape("hud_text");
    viewer->removeShape("voxel_text");
    viewer->removeShape("supervoxel_text");
    viewer->removeShape("graph_text");
    viewer->removeShape("voxel_normals_text");
    viewer->removeShape("supervoxel_normals_text");
    viewer->removeShape("refined_text");
}


text:
// EBNF
// symbol_tone ::= 'ON' | 'OFF'
// symbol_repeat ::= 'R'
// tone ::= <symbol_tone> '(' [0-9]+ ')' | <symbol_repeat>
// tone_list ::= <tone> (',' <tone>)*

#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

namespace client {

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
struct Parser : qi::grammar<Iterator, ascii::space_type> {
	Parser() : Parser::base_type(start) {
		using qi::int_;

		symbol_tone = qi::lit("ON") | qi::lit("OFF");
		symbol_repeat = 'R';
		tone = symbol_tone >> '(' >> int_ >> ')' | symbol_repeat;
		tone_list = tone >> *( ',' >> tone);
		start = tone_list;
	}

	qi::rule<Iterator, ascii::space_type> start;
	qi::rule<Iterator, ascii::space_type> symbol_tone;
	qi::rule<Iterator, ascii::space_type> symbol_repeat;
	qi::rule<Iterator, ascii::space_type> tone;
	qi::rule<Iterator, ascii::space_type> tone_list;
};

}

int main() {

	typedef client::Parser<std::string::const_iterator> Parser;
	Parser grammar;
	std::string str = "ON(10),OFF(20),R";

        std::string::const_iterator itr = str.begin();
        std::string::const_iterator end = str.end();
	bool r = phrase_parse(itr, end, grammar, boost::spirit::ascii::space);

	if (r && itr == end) {
		std::cout << "parse ok" << std::endl;
	} else {
		std::cout << "parse failed" << std::endl;
	}

	return 0;
}

ext: cpp

max_stars_repo_name: alexhausen/PoC

max_issues_repo_name: alexhausen/PoC

max_forks_repo_name: alexhausen/PoC


text:
/*
 * Copyright 2014 Antony Polukhin
 * Copyright 2015 Andrey Semashev
 *
 * Distributed under the Boost Software License, Version 1.0.
 * See http://www.boost.org/LICENSE_1_0.txt
 */

#ifndef BOOST_WINAPI_CRYPT_HPP_INCLUDED_
#define BOOST_WINAPI_CRYPT_HPP_INCLUDED_

#include <boost/winapi/basic_types.hpp>
#include <boost/winapi/detail/cast_ptr.hpp>
#if defined( BOOST_USE_WINDOWS_H )
// This header is not always included as part of windows.h
#include <wincrypt.h>
#endif

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

#if !defined( BOOST_USE_WINDOWS_H )
namespace boost { namespace winapi {
typedef ULONG_PTR_ HCRYPTPROV_;
}}

// Some versions of MinGW contain buggy declarations of CryptEnumProvidersA and CryptEnumProvidersW.
// We cannot detect those broken versions, and we can't include the system header because it's incomplete.
// So below we duplicate the broken declarations here and work around the problem with cast_ptr. These declarations
// will have to be removed when MinGW is fixed.
//
// @@@ Looks like mingw 5.0-dev has this fixed and possibly in a 3.2x late release as well
//     See: https://sourceforge.net/p/mingw/bugs/2263/

extern "C" {
#if BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM
#if !defined( BOOST_NO_ANSI_APIS )
#if !defined( BOOST_WINAPI_IS_MINGW ) || !defined( UNICODE )
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptEnumProvidersA(
    boost::winapi::DWORD_ dwIndex,
    boost::winapi::DWORD_ *pdwReserved,
    boost::winapi::DWORD_ dwFlags,
    boost::winapi::DWORD_ *pdwProvType,
    boost::winapi::LPSTR_ szProvName,
    boost::winapi::DWORD_ *pcbProvName);
#else
// Broken declaration in MinGW
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptEnumProvidersA(
    boost::winapi::DWORD_ dwIndex,
    boost::winapi::DWORD_ *pdwReserved,
    boost::winapi::DWORD_ dwFlags,
    boost::winapi::DWORD_ *pdwProvType,
    boost::winapi::LPWSTR_ szProvName,
    boost::winapi::DWORD_ *pcbProvName);
#endif

BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptAcquireContextA(
    boost::winapi::HCRYPTPROV_ *phProv,
    boost::winapi::LPCSTR_ pszContainer,
    boost::winapi::LPCSTR_ pszProvider,
    boost::winapi::DWORD_ dwProvType,
    boost::winapi::DWORD_ dwFlags);
#endif // !defined( BOOST_NO_ANSI_APIS )

#if !defined( BOOST_WINAPI_IS_MINGW ) || defined( UNICODE )
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptEnumProvidersW(
    boost::winapi::DWORD_ dwIndex,
    boost::winapi::DWORD_ *pdwReserved,
    boost::winapi::DWORD_ dwFlags,
    boost::winapi::DWORD_ *pdwProvType,
    boost::winapi::LPWSTR_ szProvName,
    boost::winapi::DWORD_ *pcbProvName);
#else
// Broken declaration in MinGW
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptEnumProvidersW(
    boost::winapi::DWORD_ dwIndex,
    boost::winapi::DWORD_ *pdwReserved,
    boost::winapi::DWORD_ dwFlags,
    boost::winapi::DWORD_ *pdwProvType,
    boost::winapi::LPSTR_ szProvName,
    boost::winapi::DWORD_ *pcbProvName);
#endif

BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptAcquireContextW(
    boost::winapi::HCRYPTPROV_ *phProv,
    boost::winapi::LPCWSTR_ szContainer,
    boost::winapi::LPCWSTR_ szProvider,
    boost::winapi::DWORD_ dwProvType,
    boost::winapi::DWORD_ dwFlags);

BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptGenRandom(
    boost::winapi::HCRYPTPROV_ hProv,
    boost::winapi::DWORD_ dwLen,
    boost::winapi::BYTE_ *pbBuffer);
#endif // BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM

#if BOOST_WINAPI_PARTITION_APP_SYSTEM
#if defined(_MSC_VER) && (_MSC_VER+0) >= 1500 && (_MSC_VER+0) < 1900 && BOOST_USE_NTDDI_VERSION < BOOST_WINAPI_NTDDI_WINXP
// Standalone MS Windows SDK 6.0A and later until 10.0 provide a different declaration of CryptReleaseContext for Windows 2000 and older.
// This is not the case for (a) MinGW and MinGW-w64, (b) MSVC 7.1 and 8, which are shipped with their own Windows SDK,
// and (c) MSVC 14.0 and later, which are used with Windows SDK 10.
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptReleaseContext(
    boost::winapi::HCRYPTPROV_ hProv,
    boost::winapi::ULONG_PTR_ dwFlags);
#else
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ WINAPI
CryptReleaseContext(
    boost::winapi::HCRYPTPROV_ hProv,
    boost::winapi::DWORD_ dwFlags);
#endif
#endif // BOOST_WINAPI_PARTITION_APP_SYSTEM
}
#endif // !defined( BOOST_USE_WINDOWS_H )

namespace boost {
namespace winapi {

#if defined( BOOST_USE_WINDOWS_H )

typedef ::HCRYPTPROV HCRYPTPROV_;

#if BOOST_WINAPI_PARTITION_APP_SYSTEM
const DWORD_ PROV_RSA_FULL_         = PROV_RSA_FULL;

const DWORD_ CRYPT_VERIFYCONTEXT_   = CRYPT_VERIFYCONTEXT;
const DWORD_ CRYPT_NEWKEYSET_       = CRYPT_NEWKEYSET;
const DWORD_ CRYPT_DELETEKEYSET_    = CRYPT_DELETEKEYSET;
const DWORD_ CRYPT_MACHINE_KEYSET_  = CRYPT_MACHINE_KEYSET;
const DWORD_ CRYPT_SILENT_          = CRYPT_SILENT;
#endif

#else

#if BOOST_WINAPI_PARTITION_APP_SYSTEM
const DWORD_ PROV_RSA_FULL_         = 1;

const DWORD_ CRYPT_VERIFYCONTEXT_   = 0xF0000000;
const DWORD_ CRYPT_NEWKEYSET_       = 8;
const DWORD_ CRYPT_DELETEKEYSET_    = 16;
const DWORD_ CRYPT_MACHINE_KEYSET_  = 32;
const DWORD_ CRYPT_SILENT_          = 64;
#endif

#endif

#if BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM

#if !defined( BOOST_NO_ANSI_APIS )
using ::CryptAcquireContextA;
#endif
using ::CryptAcquireContextW;
using ::CryptGenRandom;

#if !defined( BOOST_NO_ANSI_APIS )
BOOST_FORCEINLINE BOOL_ CryptEnumProvidersA(
    DWORD_ dwIndex,
    DWORD_ *pdwReserved,
    DWORD_ dwFlags,
    DWORD_ *pdwProvType,
    LPSTR_ szProvName,
    DWORD_ *pcbProvName)
{
    return ::CryptEnumProvidersA(dwIndex, pdwReserved, dwFlags, pdwProvType, winapi::detail::cast_ptr(szProvName), pcbProvName);
}

BOOST_FORCEINLINE BOOL_ crypt_enum_providers(
    DWORD_ dwIndex,
    DWORD_ *pdwReserved,
    DWORD_ dwFlags,
    DWORD_ *pdwProvType,
    LPSTR_ szProvName,
    DWORD_ *pcbProvName)
{
    return ::CryptEnumProvidersA(dwIndex, pdwReserved, dwFlags, pdwProvType, winapi::detail::cast_ptr(szProvName), pcbProvName);
}

BOOST_FORCEINLINE BOOL_ crypt_acquire_context(
    HCRYPTPROV_ *phProv,
    LPCSTR_ pszContainer,
    LPCSTR_ pszProvider,
    DWORD_ dwProvType,
    DWORD_ dwFlags)
{
    return ::CryptAcquireContextA(phProv, pszContainer, pszProvider, dwProvType, dwFlags);
}
#endif

BOOST_FORCEINLINE BOOL_ CryptEnumProvidersW(
    DWORD_ dwIndex,
    DWORD_ *pdwReserved,
    DWORD_ dwFlags,
    DWORD_ *pdwProvType,
    LPWSTR_ szProvName,
    DWORD_ *pcbProvName)
{
    return ::CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, winapi::detail::cast_ptr(szProvName), pcbProvName);
}

BOOST_FORCEINLINE BOOL_ crypt_enum_providers(
    DWORD_ dwIndex,
    DWORD_ *pdwReserved,
    DWORD_ dwFlags,
    DWORD_ *pdwProvType,
    LPWSTR_ szProvName,
    DWORD_ *pcbProvName)
{
    return ::CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, winapi::detail::cast_ptr(szProvName), pcbProvName);
}

BOOST_FORCEINLINE BOOL_ crypt_acquire_context(
    HCRYPTPROV_ *phProv,
    LPCWSTR_ szContainer,
    LPCWSTR_ szProvider,
    DWORD_ dwProvType,
    DWORD_ dwFlags)
{
    return ::CryptAcquireContextW(phProv, szContainer, szProvider, dwProvType, dwFlags);
}

#endif // BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM

#if BOOST_WINAPI_PARTITION_APP_SYSTEM
BOOST_FORCEINLINE BOOL_ CryptReleaseContext(HCRYPTPROV_ hProv, DWORD_ dwFlags)
{
    return ::CryptReleaseContext(hProv, dwFlags);
}
#endif

}
}

#endif // BOOST_WINAPI_CRYPT_HPP_INCLUDED_

ext: hpp

max_stars_repo_name: dilawar/eyesthatblink

max_issues_repo_name: dilawar/eyesthatblink

max_forks_repo_name: dilawar/eyesthatblink


text:
//
// $Id$
//
//
// Original author: Darren Kessner <darren@proteowizard.org>
//
// Copyright 2008 Spielberg Family Center for Applied Proteomics
//   Cedars-Sinai Medical Center, Los Angeles, California  90048
//
// Licensed 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.
//

#ifndef _CHROMATOGRAMLIST_THERMO_
#define _CHROMATOGRAMLIST_THERMO_

#include "pwiz/utility/misc/Export.hpp"
#include "pwiz/data/msdata/ChromatogramListBase.hpp"
#include "pwiz/utility/misc/Container.hpp"
#include "pwiz/utility/misc/String.hpp"
#include "pwiz/utility/misc/Stream.hpp"
#include "pwiz/data/msdata/Reader.hpp"

#ifdef PWIZ_READER_THERMO
#include "pwiz_aux/msrc/utility/vendor_api/thermo/RawFile.h"
#include "pwiz/utility/misc/IntegerSet.hpp"
#include "pwiz/utility/misc/Once.hpp"
#include <boost/icl/interval_set.hpp>
#include <boost/icl/continuous_interval.hpp>
using namespace pwiz::vendor_api::Thermo;
#endif // PWIZ_READER_THERMO

using boost::shared_ptr;

namespace pwiz {
namespace msdata {
namespace detail {

class PWIZ_API_DECL ChromatogramList_Thermo : public ChromatogramListBase
{
public:

    virtual size_t size() const;
    virtual const ChromatogramIdentity& chromatogramIdentity(size_t index) const;
    virtual size_t find(const string& id) const;
    virtual ChromatogramPtr chromatogram(size_t index, bool getBinaryData) const;
    virtual ChromatogramPtr chromatogram(size_t index, DetailLevel detailLevel) const;

#ifdef PWIZ_READER_THERMO
    ChromatogramList_Thermo(const MSData& msd, RawFilePtr rawfile, const Reader::Config& config);

    ChromatogramPtr xic(double startTime, double endTime, const boost::icl::interval_set<double>& massRanges, int msLevel);

    private:

    const MSData& msd_;
    shared_ptr<RawFile> rawfile_;
    const Reader::Config config_;

    mutable util::once_flag_proxy indexInitialized_;

    struct IndexEntry : public ChromatogramIdentity
    {
        CVID chromatogramType;
        ControllerType controllerType;
        long controllerNumber;
        string filter;
        double q1, q3;
        double q3Offset;
        CVID polarityType;
    };

    mutable vector<IndexEntry> index_;
    mutable map<string, size_t> idMap_;

    void createIndex() const;
    IndexEntry& addChromatogram(const string& id, ControllerType controllerType, int controllerNumber, CVID chromatogramType, const string& filter) const;
#endif // PWIZ_READER_THERMO
};

} // detail
} // msdata
} // pwiz

#endif // _CHROMATOGRAMLIST_THERMO_

max_stars_repo_name: vagisha/pwiz

max_issues_repo_name: vagisha/pwiz

max_forks_repo_name: vagisha/pwiz


text:
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// 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 BEAST_EXAMPLE_HTTP_ASYNC_SERVER_H_INCLUDED
#define BEAST_EXAMPLE_HTTP_ASYNC_SERVER_H_INCLUDED

#include "file_body.hpp"
#include "mime_type.hpp"

#include <beast/http.hpp>
#include <beast/core/handler_helpers.hpp>
#include <beast/core/handler_ptr.hpp>
#include <beast/core/placeholders.hpp>
#include <beast/core/streambuf.hpp>
#include <boost/asio.hpp>
#include <cstddef>
#include <cstdio>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>

namespace beast {
namespace http {

class http_async_server
{
    using endpoint_type = boost::asio::ip::tcp::endpoint;
    using address_type = boost::asio::ip::address;
    using socket_type = boost::asio::ip::tcp::socket;

    using req_type = request<string_body>;
    using resp_type = response<file_body>;

    std::mutex m_;
    bool log_ = true;
    boost::asio::io_service ios_;
    boost::asio::ip::tcp::acceptor acceptor_;
    socket_type sock_;
    std::string root_;
    std::vector<std::thread> thread_;

public:
    http_async_server(endpoint_type const& ep,
            std::size_t threads, std::string const& root)
        : acceptor_(ios_)
        , sock_(ios_)
        , root_(root)
    {
        acceptor_.open(ep.protocol());
        acceptor_.bind(ep);
        acceptor_.listen(
            boost::asio::socket_base::max_connections);
        acceptor_.async_accept(sock_,
            std::bind(&http_async_server::on_accept, this,
                beast::asio::placeholders::error));
        thread_.reserve(threads);
        for(std::size_t i = 0; i < threads; ++i)
            thread_.emplace_back(
                [&] { ios_.run(); });
    }

    ~http_async_server()
    {
        error_code ec;
        ios_.dispatch(
            [&]{ acceptor_.close(ec); });
        for(auto& t : thread_)
            t.join();
    }

    template<class... Args>
    void
    log(Args const&... args)
    {
        if(log_)
        {
            std::lock_guard<std::mutex> lock(m_);
            log_args(args...);
        }
    }

private:
    template<class Stream, class Handler,
        bool isRequest, class Body, class Fields>
    class write_op
    {
        struct data
        {
            bool cont;
            Stream& s;
            message<isRequest, Body, Fields> m;

            data(Handler& handler, Stream& s_,
                    message<isRequest, Body, Fields>&& m_)
                : cont(beast_asio_helpers::
                    is_continuation(handler))
                , s(s_)
                , m(std::move(m_))
            {
            }
        };

        handler_ptr<data, Handler> d_;

    public:
        write_op(write_op&&) = default;
        write_op(write_op const&) = default;

        template<class DeducedHandler, class... Args>
        write_op(DeducedHandler&& h, Stream& s, Args&&... args)
            : d_(std::forward<DeducedHandler>(h),
                s, std::forward<Args>(args)...)
        {
            (*this)(error_code{}, false);
        }

        void
        operator()(error_code ec, bool again = true)
        {
            auto& d = *d_;
            d.cont = d.cont || again;
            if(! again)
            {
                beast::http::async_write(d.s, d.m, std::move(*this));
                return;
            }
            d_.invoke(ec);
        }

        friend
        void* asio_handler_allocate(
            std::size_t size, write_op* op)
        {
            return beast_asio_helpers::
                allocate(size, op->d_.handler());
        }

        friend
        void asio_handler_deallocate(
            void* p, std::size_t size, write_op* op)
        {
            return beast_asio_helpers::
                deallocate(p, size, op->d_.handler());
        }

        friend
        bool asio_handler_is_continuation(write_op* op)
        {
            return op->d_->cont;
        }

        template<class Function>
        friend
        void asio_handler_invoke(Function&& f, write_op* op)
        {
            return beast_asio_helpers::
                invoke(f, op->d_.handler());
        }
    };

    template<class Stream,
        bool isRequest, class Body, class Fields,
            class DeducedHandler>
    static
    void
    async_write(Stream& stream, message<
        isRequest, Body, Fields>&& msg,
            DeducedHandler&& handler)
    {
        write_op<Stream, typename std::decay<DeducedHandler>::type,
            isRequest, Body, Fields>{std::forward<DeducedHandler>(
                handler), stream, std::move(msg)};
    }

    class peer : public std::enable_shared_from_this<peer>
    {
        int id_;
        streambuf sb_;
        socket_type sock_;
        http_async_server& server_;
        boost::asio::io_service::strand strand_;
        req_type req_;

    public:
        peer(peer&&) = default;
        peer(peer const&) = default;
        peer& operator=(peer&&) = delete;
        peer& operator=(peer const&) = delete;

        peer(socket_type&& sock, http_async_server& server)
            : sock_(std::move(sock))
            , server_(server)
            , strand_(sock_.get_io_service())
        {
            static int n = 0;
            id_ = ++n;
        }

        void
        fail(error_code ec, std::string what)
        {
            if(ec != boost::asio::error::operation_aborted)
                server_.log("#", id_, " ", what, ": ", ec.message(), "\n");
        }

        void run()
        {
            do_read();
        }

        void do_read()
        {
            async_read(sock_, sb_, req_, strand_.wrap(
                std::bind(&peer::on_read, shared_from_this(),
                    asio::placeholders::error)));
        }

        void on_read(error_code const& ec)
        {
            if(ec)
                return fail(ec, "read");
            auto path = req_.url;
            if(path == "/")
                path = "/index.html";
            path = server_.root_ + path;
            if(! boost::filesystem::exists(path))
            {
                response<string_body> res;
                res.status = 404;
                res.reason = "Not Found";
                res.version = req_.version;
                res.fields.insert("Server", "http_async_server");
                res.fields.insert("Content-Type", "text/html");
                res.body = "The file '" + path + "' was not found";
                prepare(res);
                async_write(sock_, std::move(res),
                    std::bind(&peer::on_write, shared_from_this(),
                        asio::placeholders::error));
                return;
            }
            try
            {
                resp_type res;
                res.status = 200;
                res.reason = "OK";
                res.version = req_.version;
                res.fields.insert("Server", "http_async_server");
                res.fields.insert("Content-Type", mime_type(path));
                res.body = path;
                prepare(res);
                async_write(sock_, std::move(res),
                    std::bind(&peer::on_write, shared_from_this(),
                        asio::placeholders::error));
            }
            catch(std::exception const& e)
            {
                response<string_body> res;
                res.status = 500;
                res.reason = "Internal Error";
                res.version = req_.version;
                res.fields.insert("Server", "http_async_server");
                res.fields.insert("Content-Type", "text/html");
                res.body =
                    std::string{"An internal error occurred"} + e.what();
                prepare(res);
                async_write(sock_, std::move(res),
                    std::bind(&peer::on_write, shared_from_this(),
                        asio::placeholders::error));
            }
        }

        void on_write(error_code ec)
        {
            if(ec)
                fail(ec, "write");
            do_read();
        }
    };

    void
    log_args()
    {
    }

    template<class Arg, class... Args>
    void
    log_args(Arg const& arg, Args const&... args)
    {
        std::cerr << arg;
        log_args(args...);
    }

    void
    fail(error_code ec, std::string what)
    {
        log(what, ": ", ec.message(), "\n");
    }

    void
    on_accept(error_code ec)
    {
        if(! acceptor_.is_open())
            return;
        if(ec)
            return fail(ec, "accept");
        socket_type sock(std::move(sock_));
        acceptor_.async_accept(sock_,
            std::bind(&http_async_server::on_accept, this,
                asio::placeholders::error));
        std::make_shared<peer>(std::move(sock), *this)->run();
    }
};

} // http
} // beast

#endif

max_stars_repo_name: MassICTBV/casinocoind

max_issues_repo_name: MassICTBV/casinocoind

max_forks_repo_name: MassICTBV/casinocoind


text: #include <boost/mpl/map/aux_/item.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_LINEARELLIPTIC_DISCRETEPROBLEM_HH
#define DUNE_HDD_LINEARELLIPTIC_DISCRETEPROBLEM_HH

#include <memory>
#include <limits>

#include <boost/numeric/conversion/cast.hpp>

#include <dune/stuff/common/disable_warnings.hh>
# include <dune/common/mpihelper.hh>
# include <dune/common/timer.hh>

# if HAVE_DUNE_FEM
#   include <dune/fem/misc/mpimanager.hh>
# endif
#include <dune/stuff/common/reenable_warnings.hh>

#if HAVE_DUNE_GRID_MULTISCALE
# include <dune/grid/multiscale/provider.hh>
#endif

#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/string.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/common/configuration.hh>
#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/grid/layers.hh>
#include <dune/stuff/common/memory.hh>

#include "problems.hh"

namespace Dune {
namespace HDD {
namespace LinearElliptic {

template< class GridImp >
class DiscreteProblem
{
public:
  typedef GridImp GridType;
  typedef Stuff::Grid::ProviderInterface< GridType >  GridProviderType;
private:
  typedef Stuff::GridProviders< GridType > GridProviders;
  typedef typename GridType::LeafIntersection IntersectionType;
  typedef Stuff::Grid::BoundaryInfoProvider< IntersectionType > BoundaryInfoProvider;
  typedef typename GridType::template Codim< 0 >::Entity EntityType;
  typedef typename GridType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridType::dimension;
public:
  typedef double RangeFieldType;
  static const unsigned int dimRange = 1;
  typedef LinearElliptic::ProblemInterface< EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > ProblemType;
  typedef LinearElliptic::ProblemsProvider< EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > ProblemsProvider;

  static void write_config(const std::string filename, const std::string id)
  {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    write_keys_to_file("gridprovider", GridProviders::available(), file);
    write_keys_to_file("boundaryinfo", BoundaryInfoProvider::available(), file);
    write_keys_to_file("problem", ProblemsProvider::available(), file);
    file << "[logging]" << std::endl;
    file << "info  = true" << std::endl;
    file << "debug = true" << std::endl;
    file << "file  = false" << std::endl;
    file << "visualize = true" << std::endl;
    file << "[parameter]" << std::endl;
    file << "0.diffusion_factor = [0.1 0.1 1.0 1.0]" << std::endl;
    file << "1.diffusion_factor = [1.0 1.0 0.1 0.1]" << std::endl;
    write_config_to_file< GridProviders >(file);
    write_config_to_file< BoundaryInfoProvider >(file);
    write_config_to_file< ProblemsProvider >(file);
    file.close();
  } // ... write_config(...)

  DiscreteProblem(const std::string id, const std::vector< std::string >& arguments)
  {
    // mpi
    assert(arguments.size() < std::numeric_limits< int >::max());
    int argc = boost::numeric_cast< int >(arguments.size());
    char** argv = Stuff::Common::String::vectorToMainArgs(arguments);
#if HAVE_DUNE_FEM
    Fem::MPIManager::initialize(argc, argv);
#else
    MPIHelper::instance(argc, argv);
#endif

    // configuration
    config_ = Stuff::Common::Configuration(argc, argv, id + ".cfg");
    if (!config_.has_sub(id))
      DUNE_THROW(Stuff::Exceptions::configuration_error,
                 "Missing sub '" << id << "' in the following Configuration:\n\n" << config_);
    filename_ = config_.get(id + ".filename", id);

    // logger
    const Stuff::Common::Configuration logger_config = config_.sub("logging");
    int log_flags = Stuff::Common::LOG_CONSOLE;
    debug_logging_ = logger_config.get< bool >("debug", false);
    if (logger_config.get< bool >("info"))
      log_flags = log_flags | Stuff::Common::LOG_INFO;
    if (debug_logging_)
      log_flags = log_flags | Stuff::Common::LOG_DEBUG;
    if (logger_config.get< bool >("file", false))
      log_flags = log_flags | Stuff::Common::LOG_FILE;
    Stuff::Common::Logger().create(log_flags, id, "", "");
    auto& info  = Stuff::Common::Logger().info();

    Timer timer;
    const std::string griprovider_type = config_.get< std::string >(id + ".gridprovider");
    info << "creating grid with '" << griprovider_type << "'... " << std::flush;
    grid_provider_ = GridProviders::create(griprovider_type, config_);
    const auto grid_view = grid_provider_->leaf_view();
    info << " done (took " << timer.elapsed()
         << "s, has " << grid_view.indexSet().size(0) << " element";
    if (grid_view.indexSet().size(0) > 1)
      info << "s";
    info << ")" << std::endl;

    const std::string boundary_info_type = config_.get< std::string >(id + ".boundaryinfo");
    if (config_.has_sub(boundary_info_type))
      boundary_info_ = config_.sub(boundary_info_type);
    else
      boundary_info_ = Stuff::Common::Configuration("type", boundary_info_type);

    info << "setting up ";
    timer.reset();
    const std::string problem_type = config_.get< std::string >(id + ".problem");
    if (!debug_logging_)
      info << "'" << problem_type << "'... " << std::flush;
    problem_ = ProblemsProvider::create(problem_type, config_);
    if (debug_logging_)
      info << *problem_ << std::endl;
    else
      info << "done (took " << timer.elapsed() << "s)" << std::endl;

    if (logger_config.get("visualize", true)) {
      info << "visualizing grid and problem... " << std::flush;
      timer.reset();
      grid_provider_->visualize(boundary_info_, filename_ + ".grid");
      problem_->visualize(grid_view, filename_ + ".problem");
      info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } // if (visualize)
  } // DiscreteProblem

  std::string filename() const
  {
    return filename_;
  }

  const Stuff::Common::Configuration& config() const
  {
    return config_;
  }

  bool debug_logging() const
  {
    return debug_logging_;
  }

  GridProviderType& grid_provider()
  {
    return *grid_provider_;
  }

  const GridProviderType& grid_provider() const
  {
    return *grid_provider_;
  }

  const Stuff::Common::Configuration& boundary_info() const
  {
    return boundary_info_;
  }

  const ProblemType& problem() const
  {
    return *problem_;
  }

private:
  static void write_keys_to_file(const std::string name, const std::vector< std::string > keys, std::ofstream& file)
  {
    std::string whitespace = Stuff::Common::whitespaceify(name + " = ");
    file << name << " = " << keys[0] << std::endl;
    for (size_t ii = 1; ii < keys.size(); ++ii)
      file << whitespace << keys[ii] << std::endl;
  } // ... write_keys_to_file(...)

  template< class ConfigProvider >
  static void write_config_to_file(std::ofstream& file)
  {
    for (const auto& type : ConfigProvider::available()) {
      auto config = ConfigProvider::default_config(type, type);
      if (!config.empty())
      file << config;
    }
  } // ... write_config_to_file(...)

  std::string filename_;
  Stuff::Common::Configuration config_;
  bool debug_logging_;
  std::unique_ptr< GridProviderType > grid_provider_;
  Stuff::Common::Configuration boundary_info_;
  std::unique_ptr< const ProblemType > problem_;
}; // class DiscreteProblem

#if HAVE_DUNE_GRID_MULTISCALE

template< class GridImp >
class DiscreteBlockProblem
{
public:
  typedef GridImp GridType;
  typedef grid::Multiscale::ProviderInterface< GridType > GridProviderType;
  typedef grid::Multiscale::MsGridProviders< GridType > GridProviders;
  typedef typename GridType::LeafIntersection IntersectionType;
  typedef Stuff::Grid::BoundaryInfoProvider< IntersectionType > BoundaryInfoProvider;
  typedef typename GridType::template Codim< 0 >::Entity EntityType;
  typedef typename GridType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridType::dimension;
  typedef double RangeFieldType;
  static const unsigned int dimRange = 1;
  typedef LinearElliptic::ProblemInterface
      < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > ProblemType;
  typedef LinearElliptic::ProblemsProvider
      < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > ProblemsProvider;

  static void write_config(const std::string filename,
                           const std::string id,
                           const Stuff::Common::Configuration& problem_cfg = Stuff::Common::Configuration(),
                           const Stuff::Common::Configuration& grid_cfg = Stuff::Common::Configuration(),
                           const Stuff::Common::Configuration& additional_cfg = Stuff::Common::Configuration())
  {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    if (grid_cfg.has_key("type"))
      file << "gridprovider = " << grid_cfg.get< std::string >("type") << std::endl;
    else
      write_keys_to_file("gridprovider", GridProviders::available(), file);
    if (problem_cfg.has_key("type"))
      file << "problem = " << problem_cfg.get< std::string >("type") << std::endl;
    else
      write_keys_to_file("problem", ProblemsProvider::available(), file);
    file << "[logging]" << std::endl;
    file << "info  = true" << std::endl;
    file << "debug = false" << std::endl;
    file << "file  = false" << std::endl;
    file << "visualize = true" << std::endl;
    if (grid_cfg.has_key("type"))
      file << Stuff::Common::Configuration(grid_cfg, grid_cfg.get< std::string >("type"));
    else
      write_config_to_file< GridProviders >(file);
    if (problem_cfg.has_key("type"))
      file << Stuff::Common::Configuration(problem_cfg, problem_cfg.get< std::string >("type"));
    else
      write_config_to_file< ProblemsProvider >(file);
    file << additional_cfg;
    file.close();
  } // ... write_config(...)

  DiscreteBlockProblem(const std::string id, const std::vector< std::string >& arguments)
  {
    // mpi
    int argc = boost::numeric_cast< int >(arguments.size());
    char** argv = Stuff::Common::String::vectorToMainArgs(arguments);
#if HAVE_DUNE_FEM
    Fem::MPIManager::initialize(argc, argv);
#else
    MPIHelper::instance(argc, argv);
#endif

    // configuration
    config_ = Stuff::Common::Configuration(argc, argv, id + ".cfg");
    if (!config_.has_sub(id))
      DUNE_THROW(Stuff::Exceptions::configuration_error,
                 "Missing sub '" << id << "' in the following Configuration:\n\n" << config_);
    filename_ = config_.get(id + ".filename", id);

    // logger
    const Stuff::Common::Configuration logger_config = config_.sub("logging");
    int log_flags = Stuff::Common::LOG_CONSOLE;
    debug_logging_ = logger_config.get< bool >("debug", false);
    if (logger_config.get< bool >("info"))
      log_flags = log_flags | Stuff::Common::LOG_INFO;
    if (debug_logging_)
      log_flags = log_flags | Stuff::Common::LOG_DEBUG;
    if (logger_config.get< bool >("file", false))
      log_flags = log_flags | Stuff::Common::LOG_FILE;
    Stuff::Common::Logger().create(log_flags, id, "", "");
    auto& info  = Stuff::Common::Logger().info();

    Timer timer;
    const std::string griprovider_type = config_.get< std::string >(id + ".gridprovider");
    info << "creating grid with '" << griprovider_type << "'..." << std::flush;
    grid_provider_ = GridProviders::create(griprovider_type, config_);
    const auto grid_view = grid_provider_->leaf_view();
    info << " done (took " << timer.elapsed()
         << "s, has " << grid_view.indexSet().size(0) << " element";
    if (grid_view.indexSet().size(0) > 1)
      info << "s";
    info << ")" << std::endl;

    boundary_info_ = Stuff::Grid::BoundaryInfoConfigs::AllDirichlet::default_config();

//    info << "setting up ";
//    timer.reset();
    const std::string problem_type = config_.get< std::string >(id + ".problem");
//    if (!debug_logging_)
//      info << "'" << problem_type << "'... " << std::flush;
    problem_ = ProblemsProvider::create(problem_type, config_);
//    if (debug_logging_)
//      info << *problem_ << std::endl;
//    else
//      info << "done (took " << timer.elapsed() << "s)" << std::endl;

    if (logger_config.get("visualize", true)) {
      info << "visualizing grid and problem... " << std::flush;
      timer.reset();
      grid_provider_->visualize(filename_ + ".ms_grid", false);
      grid_provider_->visualize(boundary_info_, filename_ + ".grid");
      problem_->visualize(grid_view, filename_ + ".problem");
      info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } // if (visualize)
  } // DiscreteBlockProblem

  std::string filename() const
  {
    return filename_;
  }

  const Stuff::Common::Configuration& config() const
  {
    return config_;
  }

  bool debug_logging() const
  {
    return debug_logging_;
  }

  GridProviderType& grid_provider()
  {
    return *grid_provider_;
  }

  const GridProviderType& grid_provider() const
  {
    return *grid_provider_;
  }

  const Stuff::Common::Configuration& boundary_info() const
  {
    return boundary_info_;
  }

  const ProblemType& problem() const
  {
    return *problem_;
  }

private:
  static void write_keys_to_file(const std::string name, const std::vector< std::string > keys, std::ofstream& file)
  {
    std::string whitespace = Stuff::Common::whitespaceify(name + " = ");
    file << name << " = " << keys[0] << std::endl;
    for (size_t ii = 1; ii < keys.size(); ++ii)
      file << whitespace << keys[ii] << std::endl;
  } // ... write_keys_to_file(...)

  template< class ConfigProvider >
  static void write_config_to_file(std::ofstream& file)
  {
    for (const auto& type : ConfigProvider::available()) {
      auto config = ConfigProvider::default_config(type, type);
      if (!config.empty())
      file << config;
    }
  } // ... write_config_to_file(...)

  std::string filename_;
  Stuff::Common::Configuration config_;
  bool debug_logging_;
  std::unique_ptr< GridProviderType > grid_provider_;
  Stuff::Common::Configuration boundary_info_;
  std::unique_ptr< const ProblemType > problem_;
}; // class DiscreteBlockProblem

#endif // HAVE_DUNE_GRID_MULTISCALE

} // namespace LinearElliptic
} // namespace HDD
} // namespace Dune

#endif // DUNE_HDD_LINEARELLIPTIC_DISCRETEPROBLEM_HH

ext: hh

max_stars_repo_name: tobiasleibner/dune-hdd

max_issues_repo_name: tobiasleibner/dune-hdd

max_forks_repo_name: tobiasleibner/dune-hdd


text:
//******************************************************************************
// RCF - Remote Call Framework
//
// Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
// http://www.deltavsoft.com
//
// RCF is distributed under dual licenses - closed source or GPL.
// Consult your particular license for conditions of use.
//
// If you have not purchased a commercial license, you are using RCF
// under GPL terms.
//
// Version: 2.0
// Contact: support <at> deltavsoft.com
//
//******************************************************************************

#ifndef INCLUDE_RCF_OBJECTFACTORYSERVICE_HPP
#define INCLUDE_RCF_OBJECTFACTORYSERVICE_HPP

#include <RCF/Config.hpp>

#if RCF_FEATURE_LEGACY==0
#error This header is only supported in builds with RCF_FEATURE_LEGACY=1.
#endif

#include <map>
#include <string>
#include <vector>

#include <boost/cstdint.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>

#include <RCF/Export.hpp>
#include <RCF/GetInterfaceName.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/Service.hpp>
#include <RCF/StubFactory.hpp>
#include <RCF/ThreadLibrary.hpp>
#include <RCF/Token.hpp>
#include <RCF/TypeTraits.hpp>

namespace RCF {

    class RcfServer;
    class StubEntry;
    class StubFactory;
    class I_RcfClient;
    class Token;
    class TokenMapped;

    typedef boost::shared_ptr<StubEntry> StubEntryPtr;
    typedef boost::shared_ptr<StubFactory> StubFactoryPtr;
    typedef boost::shared_ptr<TokenMapped> TokenMappedPtr;

    class RCF_EXPORT StubFactoryRegistry
    {
    public:

        StubFactoryRegistry();

        // Binds an object factory to a name.

        template<typename I1, typename ImplementationT>
        bool bind(const std::string &name_ = "")
        {
            return bind( (I1 *) NULL, (ImplementationT **) NULL, name_);
        }

        template<typename I1, typename ImplementationT>
        bool bind(I1 *, ImplementationT **, const std::string &name_ = "")
        {
            const std::string &name = (name_ == "") ?
                getInterfaceName((I1 *) NULL) :
                name_;

            StubFactoryPtr stubFactoryPtr(
                new RCF::StubFactory_1<ImplementationT, I1>());

            std::string desc;
            return insertStubFactory(name, desc, stubFactoryPtr);
        }

    protected:

        bool            insertStubFactory(
                            const std::string &objectName,
                            const std::string &desc,
                            StubFactoryPtr stubFactoryPtr);

        bool            removeStubFactory(
                            const std::string &objectName);

        StubFactoryPtr  getStubFactory(
                            const std::string &objectName);

    private:

        typedef std::map<
            std::string,
            StubFactoryPtr>             StubFactoryMap;

        ReadWriteMutex                  mStubFactoryMapMutex;
        StubFactoryMap                  mStubFactoryMap;

    };

    class RCF_EXPORT ObjectFactoryService :
        public I_Service,
        public StubFactoryRegistry,
        boost::noncopyable
    {
    public:

        ObjectFactoryService();

        // Remotely accessible functions.
        boost::int32_t CreateObject(const std::string &objectName, Token &token);
        boost::int32_t DeleteObject(const Token &token);

        boost::int32_t addObject(TokenMappedPtr tokenMappedPtr, Token &token);

        boost::int32_t CreateSessionObject(const std::string &objectName);
        boost::int32_t DeleteSessionObject();

        StubEntryPtr    getStubEntryPtr(const Token &token);
        TokenMappedPtr  getTokenMappedPtr(const Token & token);

    private:
        void            onServiceAdded(RcfServer &server);
        void            onServiceRemoved(RcfServer &server);
        void            onServerStart(RcfServer &);
        void            onServerStop(RcfServer &);
        void            stopCleanup();
        void            cycleCleanup(int timeoutMs);
        void            cleanupStubMap(unsigned int timeoutS);

        typedef std::map<
            Token,
            std::pair<
                MutexPtr,
                TokenMappedPtr> >         StubMap;

        // TokenFactory is internally synchronized
        typedef boost::shared_ptr<TokenFactory> TokenFactoryPtr;
        TokenFactoryPtr                 mTokenFactory;

        unsigned int                    mClientStubTimeoutS;
        Mutex                           mCleanupThresholdMutex;
        Condition                       mCleanupThresholdCondition;
        unsigned int                    mCleanupIntervalS;
        float                           mCleanupThreshold;

        ReadWriteMutex                  mStubMapMutex;
        StubMap                         mStubMap;

        bool                            mLazyStarted;
    };

    typedef boost::shared_ptr<ObjectFactoryService>
        ObjectFactoryServicePtr;

} // namespace RCF

#endif // ! INCLUDE_RCF_OBJECTFACTORYSERVICE_HPP

max_stars_repo_name: ASMlover/study

max_issues_repo_name: ASMlover/study

max_forks_repo_name: ASMlover/study


text:
#include <scorum/tags/tags_plugin.hpp>
#include <scorum/tags/tags_api.hpp>
#include <scorum/tags/tags_objects.hpp>

#include <scorum/protocol/config.hpp>
#include <scorum/common_api/config_api.hpp>

#include <scorum/chain/database/database.hpp>
#include <scorum/chain/hardfork.hpp>
#include <scorum/chain/operation_notification.hpp>
#include <scorum/chain/schema/account_objects.hpp>
#include <scorum/chain/schema/comment_objects.hpp>
#include <scorum/chain/services/account.hpp>
#include <scorum/chain/services/comment.hpp>
#include <scorum/utils/string_algorithm.hpp>

#include <fc/smart_ref_impl.hpp>
#include <fc/thread/thread.hpp>
#include <fc/io/json.hpp>
#include <fc/string.hpp>

#include <boost/range/iterator_range.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/join.hpp>
#include <boost/algorithm/string.hpp>

namespace scorum {
namespace tags {

namespace detail {

using namespace scorum::protocol;

class tags_plugin_impl
{
public:
    tags_plugin_impl(tags_plugin& _plugin)
        : _self(_plugin)
    {
    }
    virtual ~tags_plugin_impl();

    scorum::chain::database& database()
    {
        return _self.database();
    }

    void pre_operation(const operation_notification& note);
    void post_operation(const operation_notification& note);

    tags_plugin& _self;
};

tags_plugin_impl::~tags_plugin_impl()
{
    return;
}

class category_stats_service : public scorum::chain::dbs_base
{
    friend class chain::dbservice_dbs_factory;

public:
    explicit category_stats_service(database& db)
        : _base_type(db)
    {
    }

    void exclude_from_category_stats(const comment_metadata& meta)
    {
        if (meta.categories.empty() || meta.domains.empty())
            return;
        if (meta.categories.begin()->empty() || meta.domains.begin()->empty())
            return;

        auto normalized_meta = meta.to_lower_copy().truncate_copy();

        const auto& idx = db_impl().get_index<category_stats_index, by_category_tag>();
        // TODO: add support for multiple domains and categories
        auto it_pair
            = idx.equal_range(std::make_tuple(*normalized_meta.domains.begin(), *normalized_meta.categories.begin()));

        std::vector<std::reference_wrapper<const category_stats_object>> stats;
        std::copy(it_pair.first, it_pair.second, std::back_inserter(stats));

        for (const category_stats_object& s : stats)
        {
            auto found_it = std::find(normalized_meta.tags.begin(), normalized_meta.tags.end(), s.tag);
            if (found_it == normalized_meta.tags.end())
                continue;

            if (s.tags_count == 1)
                db_impl().remove(s);
            else if (s.tags_count > 1)
                db_impl().modify(s, [&](category_stats_object& s) { --s.tags_count; });
        }
    }

    void include_into_category_stats(const comment_metadata& meta)
    {
        if (meta.categories.empty() || meta.domains.empty())
            return;
        if (meta.categories.begin()->empty() || meta.domains.begin()->empty())
            return;

        auto normalized_meta = meta.to_lower_copy().truncate_copy();
        const auto& domain = *normalized_meta.domains.begin();
        const auto& category = *normalized_meta.categories.begin();

        auto rng = normalized_meta.tags | boost::adaptors::filtered([&](const std::string& t) {
                       return !t.empty() && t != category && t != domain;
                   });
        for (const std::string& tag : rng)
        {
            const auto& idx = db_impl().get_index<category_stats_index, by_category_tag>();

            auto found_it = idx.find(std::make_tuple(domain, category, tag_name_type(tag)));
            if (found_it == idx.end())
            {
                db_impl().create<category_stats_object>([&](category_stats_object& s) {
                    fc::from_string(s.domain, domain);
                    fc::from_string(s.category, category);
                    s.tag = tag;
                    s.tags_count = 1;
                });
            }
            else
            {
                db_impl().modify(*found_it, [&](category_stats_object& s) { ++s.tags_count; });
            }
        }
    }
};

struct category_stats_pre_operation_visitor
{
    database& _db;
    category_stats_service& _category_stats_service;

    category_stats_pre_operation_visitor(database& db)
        : _db(db)
        , _category_stats_service(_db.obtain_service<category_stats_service>())
    {
    }

    void operator()(const comment_operation& op) const
    {
        const comment_object* c
            = _db.obtain_service<dbs_comment>().find_by<by_permlink>(std::make_tuple(op.author, op.permlink));

        if (c != nullptr)
            _category_stats_service.exclude_from_category_stats(comment_metadata::parse(c->json_metadata));
    }

    void operator()(const delete_comment_operation& op) const
    {
        const comment_object& c = _db.obtain_service<dbs_comment>().get(op.author, op.permlink);

        _category_stats_service.exclude_from_category_stats(comment_metadata::parse(c.json_metadata));
    }

    template <typename Op> void operator()(Op&&) const
    {
    } /// ignore all other ops
};

struct category_stats_post_operation_visitor
{
    database& _db;
    category_stats_service& _category_stats_service;

    category_stats_post_operation_visitor(database& db)
        : _db(db)
        , _category_stats_service(_db.obtain_service<category_stats_service>())
    {
    }

    void operator()(const comment_operation& op) const
    {
        const comment_object& c = _db.obtain_service<dbs_comment>().get(op.author, op.permlink);

        _category_stats_service.include_into_category_stats(comment_metadata::parse(c.json_metadata));
    }

    template <typename Op> void operator()(Op&&) const
    {
    } /// ignore all other ops
};

struct post_operation_visitor
{
    database& _db;

    post_operation_visitor(database& db)
        : _db(db)
    {
    }

    void remove_stats(const tag_object& tag, const tag_stats_object& stats) const
    {
        _db.modify(stats, [&](tag_stats_object& s) {
            s.posts--;
            s.total_trending -= static_cast<uint32_t>(tag.trending);
            s.net_votes -= tag.net_votes;
        });
    }

    void add_stats(const tag_object& tag, const tag_stats_object& stats) const
    {
        _db.modify(stats, [&](tag_stats_object& s) {
            s.posts++;
            s.total_trending += static_cast<uint32_t>(tag.trending);
            s.net_votes += tag.net_votes;
        });
    }

    void remove_tag(const tag_object& tag) const
    {
        /// TODO: update tag stats object
        _db.remove(tag);

        const auto& idx = _db.get_index<author_tag_stats_index, by_author_tag_posts>();

        auto it_pair = idx.equal_range(boost::make_tuple(tag.author, tag.tag));
        for (const auto& stat : boost::make_iterator_range(it_pair))
        {
            _db.modify(stat, [&](author_tag_stats_object& stats) { stats.total_posts--; });
        }
    }

    const tag_stats_object& get_stats(const std::string& tag) const
    {
        const auto& stats_idx = _db.get_index<tag_stats_index>().indices().get<by_tag>();
        auto itr = stats_idx.find(tag);
        if (itr != stats_idx.end())
            return *itr;

        return _db.create<tag_stats_object>([&](tag_stats_object& stats) { stats.tag = tag; });
    }

    std::set<std::string> collect_tags(const comment_metadata& meta) const
    {
        using namespace boost::range;
        // clang-format off
        auto lhs = join(meta.domains, meta.categories);
        auto rhs = join(meta.locales, meta.tags);
        auto rng = join(lhs, rhs)
                | boost::adaptors::filtered([](const std::string& t) { return !t.empty(); })
                | boost::adaptors::transformed(utils::to_lower_copy)
                | boost::adaptors::transformed([](const std::string& s){ return utils::substring(s, 0, TAG_LENGTH_MAX); });
        // clang-format on

        std::set<std::string> tags_in_lower;

        for (const auto& t : rng)
            if (tags_in_lower.size() == get_api_config(TAGS_API_NAME).tags_to_analize_count)
                break;
            else
                tags_in_lower.insert(t);

        // if we need to return all then just return items with empty tag
        tags_in_lower.insert("");

        return tags_in_lower;
    }

    void update_tag(const tag_object& current, const comment_object& comment, double hot, double trending) const
    {
        const auto& stats = get_stats(current.tag);
        remove_stats(current, stats);

        _db.modify(current, [&](tag_object& obj) {
            obj.active = comment.active;
            obj.cashout = _db.calculate_discussion_payout_time(comment);
            obj.children = comment.children;
            obj.net_rshares = comment.net_rshares.value;
            obj.net_votes = comment.net_votes;
            obj.hot = hot;
            obj.trending = trending;
            if (obj.cashout == fc::time_point_sec())
                obj.promoted_balance = 0;
        });

        add_stats(current, stats);
    }

    void create_tag(const std::string& tag, const comment_object& comment, double hot, double trending) const
    {
        account_id_type author = _db.account_service().get_account(comment.author).id;

        const auto& tag_obj = _db.create<tag_object>([&](tag_object& obj) {
            obj.tag = tag;
            obj.comment = comment.id;
            obj.created = comment.created;
            obj.active = comment.active;
            obj.cashout = comment.cashout_time;
            obj.net_votes = comment.net_votes;
            obj.children = comment.children;
            obj.net_rshares = comment.net_rshares.value;
            obj.author = author;
            obj.hot = hot;
            obj.trending = trending;
        });
        add_stats(tag_obj, get_stats(tag));

        const auto& idx = _db.get_index<author_tag_stats_index, by_author_tag_posts>();
        auto itr = idx.lower_bound(boost::make_tuple(author, tag));
        if (itr != idx.end() && itr->author == author && itr->tag == tag)
        {
            _db.modify(*itr, [&](author_tag_stats_object& stats) { stats.total_posts++; });
        }
        else
        {
            _db.create<author_tag_stats_object>([&](author_tag_stats_object& stats) {
                stats.author = author;
                stats.tag = tag;
                stats.total_posts = 1;
            });
        }
    }

    /**
     * https://medium.com/hacking-and-gonzo/how-reddit-ranking-algorithms-work-ef111e33d0d9#.lcbj6auuw
     */
    template <int64_t S, int32_t T> double calculate_score(const share_type& score, const time_point_sec& created) const
    {
        /// new algorithm
        auto mod_score = score.value / S;

        /// reddit algorithm
        double order = log10(std::max<int64_t>(std::abs(mod_score), 1));
        int sign = 0;
        if (mod_score > 0)
            sign = 1;
        else if (mod_score < 0)
            sign = -1;

        return sign * order + double(created.sec_since_epoch()) / double(T);
    }

    inline double calculate_hot(const share_type& score, const time_point_sec& created) const
    {
        return calculate_score<10000000, 10000>(score, created);
    }

    inline double calculate_trending(const share_type& score, const time_point_sec& created) const
    {
        return calculate_score<10000000, 480000>(score, created);
    }

    /** finds tags that have been added or removed or updated */
    void update_tags(const comment_object& c, bool parse_tags = false) const
    {
        try
        {
            auto hot = calculate_hot(c.net_rshares, c.created);
            auto trending = calculate_trending(c.net_rshares, c.created);

            const auto& comment_idx = _db.get_index<scorum::tags::tag_index, by_comment>();

            if (parse_tags)
            {
                auto tags = collect_tags(comment_metadata::parse(c.json_metadata));
                auto citr = comment_idx.lower_bound(c.id);

                std::map<std::string, const tag_object*> existing_tags;
                std::vector<const tag_object*> remove_queue;

                while (citr != comment_idx.end() && citr->comment == c.id)
                {
                    const tag_object* tag = &*citr;
                    ++citr;

                    if (tags.find(tag->tag) == tags.end())
                    {
                        remove_queue.push_back(tag);
                    }
                    else
                    {
                        existing_tags[tag->tag] = tag;
                    }
                }

                for (const auto& tag : tags)
                {
                    auto existing = existing_tags.find(tag);

                    if (existing == existing_tags.end())
                    {
                        create_tag(tag, c, hot, trending);
                    }
                    else
                    {
                        update_tag(*existing->second, c, hot, trending);
                    }
                }

                for (const auto& item : remove_queue)
                    remove_tag(*item);
            }
            else
            {
                auto citr = comment_idx.lower_bound(c.id);

                while (citr != comment_idx.end() && citr->comment == c.id)
                {
                    update_tag(*citr, c, hot, trending);
                    ++citr;
                }
            }
        }
        FC_CAPTURE_LOG_AND_RETHROW((c))
    }

    const peer_stats_object& get_or_create_peer_stats(account_id_type voter, account_id_type peer) const
    {
        const auto& peeridx = _db.get_index<peer_stats_index>().indices().get<by_voter_peer>();
        auto itr = peeridx.find(boost::make_tuple(voter, peer));
        if (itr == peeridx.end())
        {
            return _db.create<peer_stats_object>([&](peer_stats_object& obj) {
                obj.voter = voter;
                obj.peer = peer;
            });
        }
        return *itr;
    }

    void operator()(const comment_operation& op) const
    {
        const comment_object& comment = _db.obtain_service<dbs_comment>().get(op.author, op.permlink);

        if (comment.parent_author == SCORUM_ROOT_POST_PARENT_ACCOUNT)
            update_tags(comment, true);
    }

    void operator()(const transfer_operation& op) const
    {
        // SCORUM: changed from null account
        // if( op.to == SCORUM_NULL_ACCOUNT && op.amount.symbol() == SCORUM_SYMBOL )
        if (op.to == "" && op.amount.symbol() == SCORUM_SYMBOL)
        {
            std::vector<std::string> part;
            part.reserve(4);
            auto path = op.memo;
            boost::split(part, path, boost::is_any_of("/"));
            if (part.size() > 1 && part[0].size() && part[0][0] == '@')
            {
                auto acnt = part[0].substr(1);
                auto perm = part[1];

                auto& comment_service = _db.obtain_service<dbs_comment>();
                if (comment_service.is_exists(acnt, perm))
                {
                    const auto& c = comment_service.get(acnt, perm);
                    if (c.parent_author.size() == 0)
                    {
                        const auto& comment_idx = _db.get_index<scorum::tags::tag_index>().indices().get<by_comment>();
                        auto citr = comment_idx.lower_bound(c.id);
                        while (citr != comment_idx.end() && citr->comment == c.id)
                        {
                            _db.modify(*citr, [&](tag_object& t) {
                                if (t.cashout != fc::time_point_sec::maximum())
                                    t.promoted_balance += op.amount.amount;
                            });
                            ++citr;
                        }

                        return;
                    }
                }

                ilog("unable to find body");
            }
        }
    }

    void operator()(const vote_operation& op) const
    {
        const comment_object& comment = _db.obtain_service<dbs_comment>().get(op.author, op.permlink);

        if (comment.parent_author == SCORUM_ROOT_POST_PARENT_ACCOUNT)
            update_tags(comment);
    }

    void operator()(const delete_comment_operation& op) const
    {
        const auto& idx = _db.get_index<scorum::tags::tag_index, by_author_comment>();

        const auto& auth = _db.account_service().get_account(op.author);

        auto tags_rng = idx.equal_range(auth.id)
            | boost::adaptors::filtered([&](const tag_object& t) { return !_db.find(t.comment); });

        auto it = tags_rng.begin();
        while (it != tags_rng.end())
        {
            const auto& tag_object = *it;
            ++it;
            remove_tag(tag_object);
        }
    }

    void operator()(const comment_reward_operation& op) const
    {
        const comment_object& comment = _db.obtain_service<dbs_comment>().get(op.author, op.permlink);
        if (comment.parent_author != SCORUM_ROOT_POST_PARENT_ACCOUNT)
            return;

        update_tags(comment);

        auto tags = collect_tags(comment_metadata::parse(comment.json_metadata));

        for (const std::string& tag : tags)
        {
            _db.modify(get_stats(tag), [&](tag_stats_object& ts) {
                if (op.total_payout.symbol() == SCORUM_SYMBOL)
                {
                    ts.total_payout_scr += op.total_payout;
                }
                else if (op.total_payout.symbol() == SP_SYMBOL)
                {
                    ts.total_payout_sp += op.total_payout;
                }
            });
        }
    }

    void operator()(const comment_payout_update_operation& op) const
    {
        const comment_object& comment = _db.obtain_service<dbs_comment>().get(op.author, op.permlink);

        if (comment.parent_author == SCORUM_ROOT_POST_PARENT_ACCOUNT)
            update_tags(comment);
    }

    template <typename Op> void operator()(Op&&) const
    {
    } /// ignore all other ops
};

void tags_plugin_impl::pre_operation(const operation_notification& note)
{
    try
    {
        /// plugins shouldn't ever throw
        note.op.visit(category_stats_pre_operation_visitor(database()));
    }
    catch (const fc::exception& e)
    {
        edump((e.to_detail_string()));
    }
    catch (...)
    {
        elog("unhandled exception");
    }
}

void tags_plugin_impl::post_operation(const operation_notification& note)
{
    try
    {
        /// plugins shouldn't ever throw
        note.op.visit(post_operation_visitor(database()));
        note.op.visit(category_stats_post_operation_visitor(database()));
    }
    catch (const fc::exception& e)
    {
        edump((e.to_detail_string()));
    }
    catch (...)
    {
        elog("unhandled exception");
    }
}

} // namespace detail

tags_plugin::tags_plugin(scorum::app::application* app)
    : plugin(app)
    , my(new detail::tags_plugin_impl(*this))
{
}

tags_plugin::~tags_plugin()
{
}

std::string tags_plugin::plugin_name() const
{
    return TAGS_PLUGIN_NAME;
}

void tags_plugin::plugin_set_program_options(boost::program_options::options_description& cli,
                                             boost::program_options::options_description& cfg)
{
    cli.add(get_api_config(TAGS_API_NAME).get_options_descriptions());
    cfg.add(cli);
}

void tags_plugin::plugin_initialize(const boost::program_options::variables_map& options)
{
    try
    {
        chain::database& db = database();

        db.pre_apply_operation.connect([&](const operation_notification& note) { my->pre_operation(note); });
        db.post_apply_operation.connect([&](const operation_notification& note) { my->post_operation(note); });

        db.add_plugin_index<tags::tag_index>();
        db.add_plugin_index<tag_stats_index>();
        db.add_plugin_index<peer_stats_index>();
        db.add_plugin_index<author_tag_stats_index>();
        db.add_plugin_index<category_stats_index>();

        get_api_config(TAGS_API_NAME).set_options(options);
    }
    FC_LOG_AND_RETHROW()

    print_greeting();
}

void tags_plugin::plugin_startup()
{
    app().register_api_factory<tags_api>("tags_api");
}

} // namespace tags
} // namespace scorum

SCORUM_DEFINE_PLUGIN(tags, scorum::tags::tags_plugin)

max_stars_repo_name: scorum/scorum

max_issues_repo_name: Scorum/Scorum

max_forks_repo_name: Scorum/Scorum


text:
/**
 *  $Id: load_project.cxx 168854 2018-04-21 17:13:54Z olivas $
 *
 *  Copyright (C) 2007
 *  Troy D. Straszheim  <troy@icecube.umd.edu>
 *  and the IceCube Collaboration <http://www.icecube.wisc.edu>
 *
 *  This file is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

#include <dlfcn.h>
#include <string>
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include <cstdlib>

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;

namespace{

  /**
   * The project_name should *not* have the preceding 'lib' unless
   * that's acutally part of the project name.  For example, if the
   * project is actually library_reader, then the shared library
   * that's built (on linux) is liblibrary_reader.so.
   */
  std::string construct_libname(const std::string& project_name){
    const std::string prefix("lib");
#ifdef __APPLE_CC__
    const std::string suffix(".dylib");
#else
    const std::string suffix(".so");
#endif
    return prefix + project_name + suffix;
  }

  /**
   * The filename is passed directly to dlopen, so can accept
   * libfoo.so and will search in LD_LIBRARY_PATH, or path
   * names (both absolute and relative) like /usr/local/lib/libfoo.so.
   * or ../lib/libfoobar.so.
   *
   * This functions throws std::runtime_error on error.
   */
  void load_dynamic_library(const std::string& filename){
    void* v = dlopen(filename.c_str(), RTLD_NOW | RTLD_GLOBAL);
    char* errmsg = dlerror();

    if(v == NULL || errmsg != NULL){
      std::string errormsg("dynamic loading error ");
      errormsg += "(" + filename + ")\n";
      errormsg += (errmsg == NULL) ? "dlopen: unknown error" : errmsg;
      errormsg += '\n';
      throw std::runtime_error(errormsg);
    }
  }

}

/**
 * This takes the project_name...and when I say project name, I mean
 * PROJECT NAME...it's the name of the project, not the library.
 * There's no '.so' suffix nor is there a 'lib' prefix, unless that's
 * actually part of the project's name.  For example, if the project
 * name is 'librarians_rock' then it's entirely appropriate to look
 * for and load the library called liblibrarians_rock.so (on linux).
 */
void
load_icecube_library(const std::string& project_name){
  load_dynamic_library(construct_libname(project_name));
}

/**
 * This should typically just thunk to 'load_icecube_library'
 * but has two functions:
 * 1) Maintain the interface, so no downstream code has to change.
 * 2) Provide functionality for any projects out there that might
 *    be constructing their own paths and using this function to
 *    dynamically load a (possibly) non-IceCube project.
 */
int
load_project(std::string path, bool verbose){
  if (path.find("/") == std::string::npos){
    // The 'path' is not a path, but a project name, which is
    // actually standard-ish, with the exception of sometimes
    // leading 'lib's

    // Also to maintain the old pathology for this function,
    // if there's a leading 'lib' assume it's *not* part
    // of the project name, so lop it off...it'll be added back
    // later.
    std::string project_name(path);
    const std::string lib("lib");
    if(project_name.find(lib) == 0){
      // 'lib' is at the beginning
      project_name = path.substr(lib.size());
    }
    load_icecube_library(project_name);
  }else{

    if(!fs::exists(fs::path(path))){
      std::string errormsg("Cannot find library ");
      errormsg += path;
      throw std::runtime_error(errormsg);
    }
    load_dynamic_library(path);
  }
  return 0;
}

ext: cxx