text:
/**
 * \file
 *
 * This file contains the template for the graphlab graph
 * data-structure.
 *
 */

#ifndef GRAPHLAB_BASICGRAPH_HPP
#define GRAPHLAB_BASICGRAPH_HPP

#include <cassert>
#include <cmath>

#include <string>
#include <list>
#include <vector>
#include <set>
#include <map>

#include <queue>
#include <algorithm>
#include <functional>
#include <fstream>

#include <boost/bind.hpp>

#include <graphlab/logger/logger.hpp>

#include <graphlab/serialization/iarchive.hpp>
#include <graphlab/serialization/oarchive.hpp>

#include <graphlab/extern/metis/metis.hpp>

#include <graphlab/macros_def.hpp>
namespace graphlab {

  /**
   * \brief the partitioning methods.
   *
   * The partition method struct contains the partition_method_enum
   * which desribes the partitioning method supported by the graphlab
   * graph partitioning framework.  Graphlab links to the metis graph
   * partitioning library and also provides its own partitioning
   * algorithms.
   */
  struct partition_method {

    /**
     * \brief the partition methods
     *
     * <ul>
     *
     *   <li> PARTITION_RANDOM: Randomly partition the graph. </li>
     *
     *   <li> PARTITION_METIS: Partition the graph using the metis
     *   algorithm </li>
     *
     *   <li> PARTITION_BFS: Use BFS partition method. </li>
     *
     * </ul>
     */
    enum partition_method_enum {
      PARTITION_RANDOM,
      PARTITION_METIS,
      PARTITION_BFS,
      PARTITION_EDGE_NUM,
    };
  };

  /** The type of a vertex is a simple size_t */
  typedef uint32_t vertex_id_t;

  /** The type of an edge id */
  typedef uint32_t edge_id_t;

  /** Type for vertex colors **/
  typedef uint8_t vertex_color_type;

  template<typename VertexData, typename EdgeData> class graph;

  // CLASS GRAPH ==============================================================>
  /**
   * The graph data structure which behaves like a container of edge
   * and vertex data. Intuitively the graph behaves like an
   * std::vector over VertexData with data associated with select
   * pairs of indices corresponding to edge data.
   */
  template<typename VertexData, typename EdgeData>
  class graph {
  public:

    /** The type of the vertex data stored in the graph */
    typedef VertexData vertex_data_type;

    /** The type of the edge data stored in the graph */
    typedef EdgeData   edge_data_type;

  public:

    // CONSTRUCTORS ============================================================>
    /**
     * Build a basic graph
     */
    graph() : finalized(true) {  }

    /**
     * BUG: Should not reserve but instead directly create vertices.
     * Create a graph with space allocated for num_vertices and
     * num_edges.
     */
    graph(size_t nverts) :
      vertices(nverts),
      in_edges(nverts), out_edges(nverts), vcolors(nverts),
      finalized(true) { }

    graph(const graph<VertexData, EdgeData> &g) { (*this) = g; }

    // METHODS =================================================================>

    /**
     * Clear all internal data
     */
    void clear() {
      vertices.clear();
      edges.clear();
      in_edges.clear();
      out_edges.clear();
      vcolors.clear();
      finalized = true;
    }

    /**
     * Finalize a graph by sorting its edges to maximize the
     * efficiency of graphlab.  This is invoked by the engine at
     * start.
     */
    void finalize() {
      // check to see if the graph is already finalized
      if(finalized) return;
      // Assert that the graph is not finalized
      typedef std::vector< edge_id_t > edge_set;

      edge_id_less_functor less_functor(this);

      // Sort all in edges sets
      foreach(edge_set& eset, in_edges) {
        std::sort(eset.begin(),
                  eset.end(),
                  less_functor);
        //                  boost::bind(&graph::edge_id_less, this, _1, _2) );
        // Test for duplicate edges
        if (eset.size() > 1) {
          for(size_t i = 0; i < eset.size()-1; ++i) {
            // Duplicate edge test
            assert(edge_id_less(eset[i], eset[i+1]));
          }
        }
      }
      // Sort all out edges sets
      foreach(edge_set& eset, out_edges) {
        std::sort(eset.begin(),
                  eset.end(),
                  less_functor);
        //                 boost::bind(&graph::edge_id_less, this, _1, _2) );
        // Test for dupliate edges
        if (eset.size() > 1) {
          for(size_t i = 0; i < eset.size()-1; ++i) {
            // Duplicate edge test
            assert(edge_id_less(eset[i], eset[i+1]));
          }
        }
      }
      finalized = true;
    } // End of finalize

    /** Get the number of vetices */
    size_t num_vertices() const {
      return vertices.size();
    } // end of num vertices

    /** Get the number of edges */
    size_t num_edges() const {
      return edges.size();
    } // end of num edges

    /** Get the number of in edges */
    size_t num_in_neighbors(vertex_id_t v) const {
      assert(v < vertices.size());
      return in_edges[v].size();
    } // end of num vertices

    /** get the number of out edges */
    size_t num_out_neighbors(vertex_id_t v) const  {
      assert(v < vertices.size());
      return out_edges[v].size();
    } // end of num vertices

    /** Find an edge */
    std::pair<bool, edge_id_t>
    find(vertex_id_t source, vertex_id_t target) const {
      assert(source < in_edges.size());
      assert(target < out_edges.size());
      // Check the base case that the souce or target have no edges
      if (in_edges[target].size() == 0 ||
          out_edges[source].size() == 0) {
        return std::make_pair(false,-1);
      } else if(finalized) { // O( log degree ) search ========================>
        // if it is finalized then do the search using a binary search
        // If their are fewer in edges into the target search the in
        // edges
        if(in_edges[target].size() < out_edges[source].size()) {
          // search the source vertices for the edge
          size_t index = binary_search(in_edges[target], source, target);
          if(index < in_edges[target].size())
            return std::make_pair(true, in_edges[target][index]);
          else
            return std::make_pair(false,-1);
        } else { // If their are fewer edges out of the source binary
                 // search there
          // search the source vertices for the edge
          size_t index = binary_search(out_edges[source], source, target);
          if(index < out_edges[source].size())
            return std::make_pair(true, out_edges[source][index]);
          else
            return std::make_pair(false,-1);
        }
      } else { // O( degree ) search ==========================================>
        // if there are few in edges at the target search there
        if(in_edges[target].size() < out_edges[source].size()) {
          // linear search the in_edges at the target
          foreach(edge_id_t eid, in_edges[target]) {
            assert(eid < edges.size());
            if(edges[eid].source() == source
               && edges[eid].target() == target) {
              return std::make_pair(true, eid);
            }
          }
          return std::make_pair(false, -1);
        } else { // fewer out edges at the source
          // linear search the out_edges at the source
          foreach(edge_id_t eid, out_edges[source]) {
            assert(eid < edges.size());
            if(edges[eid].source() == source
               && edges[eid].target() == target) {
              return std::make_pair(true, eid);
            }
          }
          return std::make_pair(false, -1);
        }
      } // End of else
    } // end of find

    /** get the edge id for the edge */
    edge_id_t edge_id(vertex_id_t source, vertex_id_t target) const {
      std::pair<bool, edge_id_t> res = find(source, target);
      // The edge must exist
      assert(res.first);
      assert(res.second < edges.size());
      return res.second;
    } // end of edge_id

    /** get the reverser edge id for the edge */
    edge_id_t rev_edge_id(edge_id_t eid) const {
      assert(eid < edges.size());
      vertex_id_t source = edges[eid].source();
      vertex_id_t target = edges[eid].target();
      return edge_id(target, source);
    } // end of rev_edge_id

    /**
     * Creates a vertex containing the vertex data and returns the id
     * of the new vertex id.
     */
    vertex_id_t add_vertex(const VertexData& vdata = VertexData() ) {
      vertices.push_back(vdata);
      // Resize edge maps
      out_edges.resize(vertices.size());
      in_edges.resize(vertices.size());
      vcolors.resize(vertices.size());
      return vertices.size() - 1;
    } // End of add vertex;

    /**
     * Add additional vertices up to provided num_vertices.  This will
     * fail is resizing down.
     */
    void resize(size_t num_vertices ) {
      assert(num_vertices >= vertices.size());
      vertices.resize(num_vertices);
      // Resize edge maps
      out_edges.resize(vertices.size());
      in_edges.resize(vertices.size());
      vcolors.resize(vertices.size());
    } // End of resize

    /**
     * Creates an edge connecting vertex source to vertex target.  Any
     * existing data will be cleared.
     */
    edge_id_t add_edge(vertex_id_t source, vertex_id_t target,
                       const EdgeData& edata = EdgeData()) {
      if ( source >= vertices.size()
           || target >= vertices.size() ) {
        logger(LOG_FATAL,
               "Attempting add_edge (%d -> %d) when there are only %d vertices",
               source, target, vertices.size());
        assert(source < vertices.size());
        assert(target < vertices.size());
      }
      // Add the edge to the set of edge data (this copies the edata)
      edges.push_back( edge( source, target, edata ) );

      // Add the edge id to in and out edge maps
      edge_id_t edge_id = edges.size() - 1;
      in_edges[target].push_back(edge_id);
      out_edges[source].push_back(edge_id);

      // Determine if the graph is still finalized A graph is
      // finalized if it was finalized and the newly added edge_id is
      // in the correct location in the in and out edge lists (which
      // is true if either the lists only contain a single element or
      // the last two elements are in the correct order).
      finalized = finalized &&
        ((in_edges[target].size() < 2) ||
         edge_id_less(*(in_edges[target].end()-2),
                      *(in_edges[target].end()-1))) &&
        ((out_edges[source].size() < 2) ||
         edge_id_less(*(out_edges[source].end()-2),
                      *(out_edges[source].end()-1)));
      return edge_id;
    } // End of add edge

    /** Get the vertex data */
    VertexData& vertex_data(vertex_id_t v) {
      assert(v < vertices.size());
      return vertices[v];
    } // end of data(v)

    /** Get the vertex data */
    const VertexData& vertex_data(vertex_id_t v) const {
      assert(v < vertices.size());
      return vertices[v];
    } // end of data(v)

    /** Get the edge_data */
    EdgeData& edge_data(vertex_id_t source, vertex_id_t target) {
      assert(source < vertices.size());
      assert(target < vertices.size());
      std::pair<bool, edge_id_t> ans = find(source, target);
      // We must find the edge!
      assert(ans.first);
      // the edge id should be valid!
      assert(ans.second < edges.size());
      return edges[ans.second].data();
    } // end of edge_data(u,v)

    /** Get the edge_data */
    const EdgeData& edge_data(vertex_id_t source, vertex_id_t target) const {
      assert(source < vertices.size());
      assert(target < vertices.size());
      std::pair<bool, edge_id_t> ans = find(source, target);
      // We must find the edge!
      assert(ans.first);
      // the edge id should be valid!
      assert(ans.second < edges.size());
      return edges[ans.second].data();
    } // end of edge_data(u,v)

    /** Get the edge_data */
    EdgeData& edge_data(edge_id_t edge_id) {
      assert(edge_id < edges.size());
      return edges[edge_id].data();
    }

    /** Get the edge_data */
    const EdgeData& edge_data(edge_id_t edge_id) const {
      assert(edge_id < edges.size());
      return edges[edge_id].data();
    }

    /** get the source of the edge */
    vertex_id_t source(edge_id_t edge_id) const {
      //      assert(edge_id < edges.size());
      return edges[edge_id].source();
    }

    /** get the dest of the edge */
    vertex_id_t target(edge_id_t edge_id) const {
      //      assert(edge_id < edges.size());
      return edges[edge_id].target();
    }

    /** Set vertex color **/
    const vertex_color_type& color(vertex_id_t vertex) const {
      assert(vertex < vertices.size());
      return vcolors[vertex];
    }

    vertex_color_type& color(vertex_id_t vertex) {
      assert(vertex < vertices.size());
      return vcolors[vertex];
    }

    /** This function constructs a coloring for the graph and returns
        the number of colors */
    size_t compute_coloring() {
      // Reset the colors
      for(vertex_id_t v = 0; v < num_vertices(); ++v) color(v) = 0;
      // construct a permuation of the vertices to use in the greedy
      // coloring. \todo Should probably sort by degree instead when
      // constructing greedy coloring.
      std::vector<vertex_id_t> permutation(num_vertices());
      for(vertex_id_t v = 0; v < num_vertices(); ++v)
        permutation[v] = v;
      std::random_shuffle(permutation.begin(), permutation.end());
      // Recolor
      size_t max_color = 0;
      std::set<vertex_color_type> neighbor_colors;
      for(size_t i = 0; i < permutation.size(); ++i) {
        neighbor_colors.clear();
        const vertex_id_t& vid = permutation[i];
        const std::vector<edge_id_t>& in_edges = in_edge_ids(vid);
        // Get the neighbor colors
        foreach(edge_id_t eid, in_edges){
          const vertex_id_t& neighbor_vid = source(eid);
          const vertex_color_type& neighbor_color = color(neighbor_vid);
          neighbor_colors.insert(neighbor_color);
        }
        // Find the lowest free color
        vertex_color_type& vertex_color = color(vid);
        foreach(vertex_color_type neighbor_color, neighbor_colors) {
          if(vertex_color != neighbor_color) break;
          else vertex_color++;
          // Ensure no wrap around
          assert(vertex_color != 0);
        }
        max_color = std::max(max_color, size_t(vertex_color) );
      }
      // Return the NUMBER of colors
      return max_color + 1;
    } // end of compute coloring

    /**
     * Check that the colors satisfy a valid coloring of the graph.
     * return true is coloring is valid;
     */
    bool valid_coloring() {
      for(vertex_id_t vid = 0; vid < num_vertices(); ++vid) {
        const vertex_color_type& vertex_color = color(vid);
        const std::vector<edge_id_t>& in_edges = in_edge_ids(vid);
        // Get the neighbor colors
        foreach(edge_id_t eid, in_edges){
          const vertex_id_t& neighbor_vid = source(eid);
          const vertex_color_type& neighbor_color = color(neighbor_vid);
          if(vertex_color == neighbor_color) return false;
        }
      }
      return true;
    }

    /** Get the ids of the in edges */
    const std::vector<edge_id_t>& in_edge_ids(vertex_id_t v) const {
      assert(v < in_edges.size());
      return in_edges[v];
    } // end of in edges

    /** Get the ids of the out edges */
    const std::vector<edge_id_t>& out_edge_ids(vertex_id_t v) const {
      assert(v < out_edges.size());
      return out_edges[v];
    } // end of out edges

    /** Load the graph from an archive */
    void load(iarchive& arc) {
      clear();
      // read the vertices and colors
      arc >> vertices
          >> edges
          >> in_edges
          >> out_edges
          >> vcolors
          >> finalized;
    } // end of load

    /** Save the graph to an archive */
    void save(oarchive& arc) const {
      // Write the number of edges and vertices
      arc << vertices
          << edges
          << in_edges
          << out_edges
          << vcolors
          << finalized;
    } // end of save

    /** Load the graph from a file */
    void load(const std::string& filename) {
      std::ifstream fin(filename.c_str());
      iarchive iarc(fin);
      iarc >> *this;
      fin.close();
    } // end of load

    /**
     * \brief save the graph to the file given by the filename
     *
     */
    void save(const std::string& filename) const {
      std::ofstream fout(filename.c_str());
      oarchive oarc(fout);
      oarc << *this;
      fout.close();
    } // end of save

    /**
     * \brief save the adjacency structure to a text file.
     *
     * Save the adjacency structure as a text file in:
     *    src_Id, dest_Id \n
     *    src_Id, dest_Id \n
     * format.
     */
    void save_adjacency(const std::string& filename) const {
      std::ofstream fout(filename.c_str());
      assert(fout.good());
      for(size_t i = 0; i < edges.size(); ++i) {
        fout << edges[i].source() << ", " << edges[i].target() << "\n";
        assert(fout.good());
      }
      fout.close();
    }

    /**
     * partition the graph with roughtly the same number of edges for each part
     */
    void edge_num_partition(size_t nparts, std::vector<uint32_t>& vertex2part){

      vertex2part.resize(num_vertices());
      size_t e = 2 * num_edges();
      size_t edge_per_part = e / nparts;

      size_t curpart = 0;
      std::vector<size_t> parts;
      parts.resize(nparts, 0);

      for (size_t i = 0; i< num_vertices(); i++){
        int ne = out_edge_ids(i).size() + in_edge_ids(i).size();
        vertex2part[i] = curpart;
        parts[curpart]+= ne;

        if (parts[curpart] >= edge_per_part  && curpart < nparts-1){
          curpart++;
        }
      }
    }

    /**
     * Randomly assign vertices to partitions.  This will assign
     * vertices evenly to each partition.
     */
    void random_partition(size_t nparts, std::vector<uint32_t>& vertex2part) {
      vertex2part.resize(num_vertices());
      for (size_t i = 0;i < num_vertices(); ++i) {
        vertex2part[i] = i % nparts;
      }
      std::random_shuffle(vertex2part.begin(), vertex2part.end());
    }

    /**
     * Use a modified version of the METIS library to partition the
     * graph. The methis library is described in:
     *
     *   "A Fast and Highly Quality Multilevel Scheme for Partitioning
     *   Irregular Graphs”. George Karypis and Vipin Kumar. SIAM
     *   Journal on Scientific Computing, Vol. 20, No. 1, pp. 359—392,
     *   1999.
     *
     * We have modified an alpha version (5.0) to work with the
     * GraphLab framework.  Therefore users having trouble with this
     * function or the included Metis source should direct concerns to
     * the contact information provided at:
     *
     *   http://www.select.cs.cmu.edu/code
     *
     */
    void metis_partition(size_t numparts , std::vector<uint32_t>& ret_part) {
      if (numparts == 1) {
        ret_part.assign(num_vertices(), 0);
        return;
      }
      // Determine parameters needed to construct the partitioning
      metis::idxtype numverts = static_cast<int>(num_vertices());
      assert(numverts > 0);
      // Compute the number of edges
      int numedges = static_cast<int>(num_edges());

      // allocate metis data structures
      metis::idxtype* vweight = new metis::idxtype[numverts];
      assert(vweight != NULL);
      metis::idxtype* xadj = new metis::idxtype[numverts + 1];
      assert(xadj != NULL);
      metis::idxtype* adjacency = new metis::idxtype[2 * numedges];
      assert(adjacency != NULL);
      metis::idxtype* eweight = NULL;
      //       if(weighted) {
      //         eweight = new idxtype[numedges];
      //         assert(eweigth != NULL);
      //       }
      metis::idxtype* res = new metis::idxtype[numverts];
      assert(res != NULL);

      // Pass through vertices filling in the metis data structures
      size_t offset = 0;
      for(vertex_id_t u = 0; u < num_vertices(); ++u) {
        // Update vertex weight
        // Set weight
        vweight[u] = 1;
        // Update the offset
        xadj[u] = offset;
        // Fill the the adjacency data

        std::set<size_t> neighbors;
        foreach(edge_id_t eid, out_edge_ids(u)) {
          neighbors.insert(target(eid));
        }
        foreach(edge_id_t eid, in_edge_ids(u)) {
          neighbors.insert(source(eid));
        }
        foreach(vertex_id_t vid, neighbors) {
          if (vid == u) continue;
          adjacency[offset] = vid;
          assert(adjacency[offset] >= 0);
          offset++;
          assert(offset >= 0);
        }

      } // end of data structure creation

      // Set the last entry in xadj to the end of the adjacency array
      xadj[numverts] = offset;

      // Set additional metis flags
      /**
       * 0 No weights (vwgts and adjwgt are NULL)
       * 1 Weights on the edges only (vwgts = NULL)
       * 2 Weights on the vertices only (adjwgt = NULL)
       * 3 Weights both on vertices and edges.
       */
      metis::idxtype weightflag = 2;
      // 0 for C-style numbering starting at 0 (1 for fortran style)
      metis::idxtype numflag = 0;
      // the number of parts to cut into
      metis::idxtype nparts = numparts;
      // Options array (only care about first element if first element
      // is zero
      metis::idxtype options[5] = {0};
      // output argument number of edges cut
      metis::idxtype edgecut = 0;

      // Call kmetis
      metis::METIS_PartGraphKway(&(numverts),
                                 xadj,
                                 adjacency,
                                 vweight,
                                 eweight,
                                 &(weightflag),
                                 &(numflag),
                                 &(nparts),
                                 options,
                                 &(edgecut),
                                 res);

      //     // Call pmetis
      //     metis::METIS_PartGraphRecursive(&(numverts),
      //                                     xadj,
      //                                     adjacency,
      //                                     vweight,
      //                                     eweight,
      //                                     &(weightflag),
      //                                     &(numflag),
      //                                     &(nparts),
      //                                     options,
      //                                     &(edgecut),
      //                                     res);

      // destroy all unecessary data structures except res
      if(xadj != NULL) delete [] xadj;
      if(adjacency != NULL) delete [] adjacency;
      if(vweight != NULL) delete [] vweight;
      if(eweight != NULL) delete [] eweight;

      // Resize the partition
      ret_part.resize(num_vertices());
      // process the final results
      assert(res != NULL);
      for(vertex_id_t v = 0; v < num_vertices(); ++v) {
        ret_part[v] = res[v];
      }
      // Delete the result array
      if(res != NULL) delete [] res;
    } // end of metis partition

    /**
     * This function computes a weighted graph partition using METIS.
     * \param numparts The number of parts to partition into
     * \param ret_part A vector providing a vertex_id -> partition_id mapping
     * \param vfunction A function of the type size_t (*)(const VertexData &v)
     *                  This function takes in the data on a vertex, and
     *                  returns the weight of the vertex
     * \param efunction A function of the type size_t (*)(const EdgeData &e)
     *                  This function takes in the data on an edge, and
     *                  returns the weight of the edge
     *
     * Use a modified version of the METIS library to partition the
     * graph using user provided edge and vertex weight functions.
     * The methis library is described in:
     *
     *   "A Fast and Highly Quality Multilevel Scheme for Partitioning
     *   Irregular Graphs”. George Karypis and Vipin Kumar. SIAM
     *   Journal on Scientific Computing, Vol. 20, No. 1, pp. 359—392,
     *   1999.
     *
     * We have modified an alpha version (5.0) to work with the
     * GraphLab framework.  Therefore users having trouble with this
     * function or the included Metis source should direct concerns to
     * the contact information provided at:
     *
     *   http://www.select.cs.cmu.edu/code
     *
     */
    template <typename EdgeWeightFunction, typename VertexWeightFunction>
    void metis_weighted_partition(size_t numparts ,
                                  std::vector<uint32_t>& ret_part,
                                  VertexWeightFunction vfunction,
                                  EdgeWeightFunction wfunction) {
      if (numparts == 1) {
        ret_part.assign(num_vertices(), 0);
        return;
      }
      // Determine parameters needed to construct the partitioning
      metis::idxtype numverts = static_cast<int>(num_vertices());
      assert(numverts > 0);
      // Compute the number of edges
      int numedges = static_cast<int>(num_edges());

      // allocate metis data structures
      metis::idxtype* vweight = new metis::idxtype[numverts];
      assert(vweight != NULL);
      metis::idxtype* xadj = new metis::idxtype[numverts + 1];
      assert(xadj != NULL);
      metis::idxtype* adjacency = new metis::idxtype[2 * numedges];
      assert(adjacency != NULL);
      metis::idxtype* eweight = NULL;
      eweight = new metis::idxtype[ 2 * numedges];
      assert(eweight != NULL);

      metis::idxtype* res = new metis::idxtype[numverts];
      assert(res != NULL);

      // Pass through vertices filling in the metis data structures
      size_t offset = 0;
      for(vertex_id_t u = 0; u < num_vertices(); ++u) {
        // Update vertex weight
        // Set weight
        vweight[u] = double(vfunction(vertex_data(u)));
        // Update the offset
        xadj[u] = offset;
        // Fill the the adjacency data

        std::set<size_t> neighbors;
        std::map<size_t, double> nbrtoweight;
        foreach(edge_id_t eid, out_edge_ids(u)) {
          neighbors.insert(target(eid));
          nbrtoweight[target(eid)] = double(wfunction(edge_data(eid)));
        }
        foreach(edge_id_t eid, in_edge_ids(u)) {
          neighbors.insert(source(eid));
          nbrtoweight[source(eid)] = double(wfunction(edge_data(eid)));
        }
        foreach(vertex_id_t vid, neighbors) {
          if (vid == u) continue;
          adjacency[offset] = vid;
          eweight[offset] = nbrtoweight[vid];
          assert(adjacency[offset] >= 0);
          offset++;
          assert(offset >= 0);
        }

      } // end of data structure creation

      // Set the last entry in xadj to the end of the adjacency array
      xadj[numverts] = offset;

      // Set additional metis flags
      /**
       * 0 No weights (vwgts and adjwgt are NULL)
       * 1 Weights on the edges only (vwgts = NULL)
       * 2 Weights on the vertices only (adjwgt = NULL)
       * 3 Weights both on vertices and edges.
       */
      metis::idxtype weightflag = 3;
      // 0 for C-style numbering starting at 0 (1 for fortran style)
      metis::idxtype numflag = 0;
      // the number of parts to cut into
      metis::idxtype nparts = numparts;
      // Options array (only care about first element if first element
      // is zero
      metis::idxtype options[5] = {0};

      options[0] = 1;
      options[1]=3;
      options[2]=1;
      options[3]=2;
      options[4]=0;
      // output argument number of edges cut
      metis::idxtype edgecut = 0;

      // Call kmetis
      metis::METIS_PartGraphKway(&(numverts),
                                 xadj,
                                 adjacency,
                                 vweight,
                                 eweight,
                                 &(weightflag),
                                 &(numflag),
                                 &(nparts),
                                 options,
                                 &(edgecut),
                                 res);

      // Call pmetis
      /*   metis::METIS_PartGraphRecursive(&(numverts),
           xadj,
           adjacency,
           vweight,
           eweight,
           &(weightflag),
           &(numflag),
           &(nparts),
           options,
           &(edgecut),
           res);*/

      // destroy all unecessary data structures except res
      if(xadj != NULL) delete [] xadj;
      if(adjacency != NULL) delete [] adjacency;
      if(vweight != NULL) delete [] vweight;
      if(eweight != NULL) delete [] eweight;

      // Resize the partition
      ret_part.resize(num_vertices());
      // process the final results
      assert(res != NULL);
      for(vertex_id_t v = 0; v < num_vertices(); ++v) {
        ret_part[v] = res[v];
      }
      // Delete the result array
      if(res != NULL) delete [] res;
    } // end of metis partition

    void bfs_partition(size_t nparts, std::vector<uint32_t> &vertex2part) {
      // create a list of all unassigned variables
      std::set<vertex_id_t> unassigned;
      vertex2part.resize(num_vertices());
      // initialize the unassigned vertices
      for(vertex_id_t v = 0; v < num_vertices(); ++v) {
        unassigned.insert(v);
      }
      // Compute the partition size
      size_t maxpartsize = (size_t)(std::ceil(double(unassigned.size()) / nparts));
      size_t partid = 0;
      while(!unassigned.empty()) {
        std::list<vertex_id_t> queue;    // Breadth first queue
        std::set<vertex_id_t>  visited;  // Set of visited vertices
        // While the task is still too small and their remains
        // unassigned vertices
        size_t curpartsize = 0;
        while(curpartsize < maxpartsize
              && !unassigned.empty()) {
          if(queue.empty()) {
            queue.push_front(*unassigned.begin());
            visited.insert(*unassigned.begin());
          }
          assert(!queue.empty());
          // Pop the first element off the queue
          vertex_id_t v = queue.front(); queue.pop_front();
          assert(partid < nparts);
          // Add the element to the task
          vertex2part[v] = partid;
          ++curpartsize;
          // Remove the vertex from the set of unassigned vertices
          unassigned.erase(v);
          // Add all its unassigned and unvisited neighbors to the queue
          foreach(edge_id_t eid, out_edge_ids(v)) {
            vertex_id_t u = target(eid);
            if(unassigned.find(u) != unassigned.end() &&
               visited.find(u) == visited.end()) {
              queue.push_back(u);
              visited.insert(u);
            }
          }
          foreach(edge_id_t eid, in_edge_ids(v)) {
            vertex_id_t u = source(eid);
            if(unassigned.find(u) != unassigned.end() &&
               visited.find(u) == visited.end()) {
              queue.push_back(u);
              visited.insert(u);
            }
          }
        } // End of block build foor loop
        // move to the next part
        partid++;
      }// end of outer while loop
    } // end of bfs partition

    /**
     * Partition the graph using one of the available partitioning
     * methods.
     */
    void partition(partition_method::partition_method_enum partmethod,
                   size_t nparts, std::vector<uint32_t>& vertex2part) {
      switch (partmethod) {
      case partition_method::PARTITION_METIS:
        return metis_partition(nparts, vertex2part);
      case partition_method::PARTITION_BFS:
        return bfs_partition(nparts, vertex2part);
      case partition_method::PARTITION_RANDOM:
        return random_partition(nparts, vertex2part);
      case partition_method::PARTITION_EDGE_NUM:
        return edge_num_partition(nparts, vertex2part);
      default:
        ASSERT_TRUE(false); //shoud never ever happen
      }
    }

    /**
     * builds a topological_sort of the graph. assuming it is top
     * sortable will return false if fails (i.e. cycles)
     */
    bool topological_sort(std::vector<vertex_id_t>& topsort) const {
      topsort.clear();
      topsort.reserve(num_vertices());

      std::vector<size_t> indeg;
      indeg.resize(num_vertices());
      std::queue<vertex_id_t> q;
      for (size_t i = 0;i < num_vertices(); ++i) {
        indeg[i] = in_edge_ids(i).size();
        if (indeg[i] == 0) {
          q.push(i);
        }
      }

      while (!q.empty()) {
        vertex_id_t v = q.front();
        q.pop();
        topsort.push_back(v);
        foreach(edge_id_t eid, out_edge_ids(v)) {
          vertex_id_t destv = target(eid);
          --indeg[destv];
          if (indeg[destv] == 0) {
            q.push(destv);
          }
        }
      }

      if (q.empty() && topsort.size() != num_vertices()) return false;
      return true;
    } // end of topological sort

  private:
    /** Internal edge class  */
    class edge {
      vertex_id_t _source;
      vertex_id_t _target;
      EdgeData _data;
    public:
      edge() : _source(-1), _target(-1) { }
      edge(const edge& other) :
        _source(other.source()), _target(other.target()),
        _data(other.data()) { }
      edge(vertex_id_t source, vertex_id_t target) :
        _source(source), _target(target)  { }
      edge(vertex_id_t source, vertex_id_t target, EdgeData data) :
        _source(source), _target(target), _data(data) {}

      bool operator<(const edge& other) const {
        return (_source < other._source) ||
          (_source == other._source && _target < other._target);
      }

      inline vertex_id_t source() const { return _source; }
      inline vertex_id_t target() const { return _target; }
      inline EdgeData& data() { return _data; }
      inline const EdgeData& data() const { return _data; }

      void load(iarchive& arc) {
        arc >> _source
            >> _target
            >> _data;
      }

      void save(oarchive& arc) const {
        arc << _source
            << _target
            << _data;
      }
    }; // end of edge_data

    struct edge_id_less_functor {
      graph* g_ptr;
      edge_id_less_functor(graph* g_ptr) : g_ptr(g_ptr) { }
      bool operator()(edge_id_t a, edge_id_t b) {
        return g_ptr->edge_id_less(a,b);
      }
    };

    /**
     * Used to order edge ids in the in and out edges vectors based on
     * the lexical ordering of the vertex ids of the corresponding
     * edge
     */
    inline bool edge_id_less(edge_id_t a, edge_id_t b) const {
      assert(a < edges.size());
      assert(b < edges.size());
      return edges[a] < edges[b];
    }

    // PRIVATE DATA MEMBERS ===================================================>
    /** The vertex data is simply a vector of vertex data */
    std::vector<VertexData> vertices;

    /** The edge data is a vector of edges where each edge stores its
        source, destination, and data. */
    std::vector<edge> edges;

    /** A map from src_vertex -> dest_vertex -> edge index */
    std::vector< std::vector<edge_id_t> >  in_edges;

    /** A map from src_vertex -> dest_vertex -> edge index */
    std::vector< std::vector<edge_id_t> >  out_edges;

    /** The vertex colors specified by the user. **/
    std::vector< vertex_color_type > vcolors;

    /** Mark whether the graph is finalized.  Graph finalization is a
        costly procedure but it can also dramatically improve
        performance. */
    bool finalized;

    // PRIVATE HELPERS =========================================================>
    /**
     * This function tries to find the edge in the vector.  If it
     * fails it returns size_t(-1)
     */
    size_t binary_search(const std::vector<edge_id_t>& vec,
                         vertex_id_t source, vertex_id_t target) const {
      // Compare to the middle of the list
      size_t first = 0;
      size_t last = vec.size() - 1;
      while(first <= last) {
        size_t mid = (first+last)/2;
        vertex_id_t mid_source = edges[vec[mid]].source();
        vertex_id_t mid_target = edges[vec[mid]].target();
        // Edge found
        if(mid_source == source && mid_target == target) {
          return mid;
        } else if(std::make_pair(source, target) <
                  std::make_pair(mid_source, mid_target) ) {
          // Search left
          last = mid - 1;
        } else {
          // Search right
          first = mid + 1;
        }
      }
      // We failed to find
      return -1;
    } // end of binary search

  }; // End of graph

  template<typename VertexData, typename EdgeData>
  std::ostream& operator<<(std::ostream& out,
                           const graph<VertexData, EdgeData>& graph) {

    out << "Printing vertex data:\n";
    for(size_t i = 0; i < graph.num_vertices(); ++i) {
      out << "V_" << i << ": D[" << graph.vertex_data(i) << "]\n";
    }
    out << "Printing edge data:\n";
    for(size_t i = 0; i < graph.num_edges(); ++i) {
      out << "(V_" << graph.source(i) << "-> V_" << graph.target(i) << "): "
          << "D[" << graph.edge_data(i) << "]\n";
    }
    return out;
  }

} // end of namespace graphlab
#include <graphlab/macros_undef.hpp>

#endif

ext: hpp

max_stars_repo_name: Lcrypto/graphlab

max_issues_repo_name: Lcrypto/graphlab

max_forks_repo_name: Lcrypto/graphlab


text:
//
//  ZeroMQSocket.hpp
//  MWorksCore
//
//  Created by Christopher Stawarz on 7/26/16.
//  Copyright © 2016 The MWorks Project. All rights reserved.
//

#ifndef ZeroMQSocket_hpp
#define ZeroMQSocket_hpp

#include <string>

#include <boost/noncopyable.hpp>
#define MSGPACK_DISABLE_LEGACY_NIL
#include <msgpack.hpp>
#include <zmq.h>

#include "Event.h"

BEGIN_NAMESPACE_MW

class ZeroMQSocket : boost::noncopyable {

public:
    enum class Result {
        ok,
        error,
        timeout
    };

    class Message : boost::noncopyable {
    public:
        Message();
        ~Message();
        Result recv(ZeroMQSocket &socket, int flags = 0);
        const void * getData() const;
        std::size_t getSize() const;
        bool isComplete() const;
    private:
        zmq_msg_t msg;
    };

    explicit ZeroMQSocket(int type);
    ~ZeroMQSocket();

    bool getLastEndpoint(std::string &endpoint) const;

    bool setOption(int name, const void *value, std::size_t valueSize);
    bool setOption(int name, int value) { return setOption(name, &value, sizeof(value)); }
    bool setOption(int name, const std::string &value) { return setOption(name, value.data(), value.size()); }

    bool bind(const std::string &endpoint);
    bool unbind(const std::string &endpoint);

    bool connect(const std::string &endpoint);
    bool disconnect(const std::string &endpoint);

    Result send(const void *data, std::size_t dataSize, int flags = 0);

    Result send(const boost::shared_ptr<Event> &event);
    Result recv(boost::shared_ptr<Event> &event);

private:
    void * const socket;

    msgpack::sbuffer packingBuffer;
    msgpack::packer<decltype(packingBuffer)> packer;

};

END_NAMESPACE_MW

#endif /* ZeroMQSocket_hpp */

max_stars_repo_name: esayui/mworks

max_issues_repo_name: esayui/mworks

max_forks_repo_name: esayui/mworks


text:
//  boost/chrono/round.hpp  ------------------------------------------------------------//

//  (C) Copyright Howard Hinnant
//  Copyright 2011 Vicente J. Botet Escriba

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

//  See http://www.boost.org/libs/chrono for documentation.

#ifndef BOOST_CHRONO_CEIL_HPP
#define BOOST_CHRONO_CEIL_HPP

#include <boost/chrono/duration.hpp>

namespace boost
{
  namespace chrono
  {

    /**
     * rounds up
     */
    template <class To, class Rep, class Period>
    To ceil(const duration<Rep, Period>& d)
    {
        To t = duration_cast<To>(d);
        if (t < d)
            ++t;
        return t;
    }

  } // namespace chrono
} // namespace boost

#endif

max_stars_repo_name: rudylee/expo

max_issues_repo_name: rudylee/expo

max_forks_repo_name: rudylee/expo


text:
#ifndef _VSC_KEY_BINDINGS_H_
#define _VSC_KEY_BINDINGS_H_

#include "VSCUI.h"
#include "VSCBindings.hpp"

#include <boost/shared_ptr.hpp>

namespace VSC {

    template <typename Action, typename Input>
    class Bound
    {

    public:

        Bound() {}
        virtual ~Bound() {}

        typename Bindings<Action,Input>::SPtr    getBindings() {return mBindings;}
        void                                        setBindings(typename Bindings<Action,Input>::SPtr bindings) {mBindings = bindings;}

    private:

        typename Bindings<Action,Input>::SPtr    mBindings;

    };

}

#endif//_VSC_KEY_BINDINGS_H_


text:
#define BOOST_TEST_MODULE "extlib tests"
//#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include "test_files.h"

struct GlobalFixture
{
	GlobalFixture()
	{
		auto argc = boost::unit_test::framework::master_test_suite().argc;
		auto argv = boost::unit_test::framework::master_test_suite().argv;

		if (argc >= 2)
		{
			std::filesystem::path files_location = argv[1];
			std::error_code ec;
			if (std::filesystem::exists(files_location, ec))
			{
				test_files_location = files_location;
			}
		}
	}
};

BOOST_GLOBAL_FIXTURE(GlobalFixture);

ext: cpp

max_stars_repo_name: dmlys/ExtLibrary

max_issues_repo_name: dmlys/extlib

max_forks_repo_name: dmlys/extlib


text:
#ifndef CLIENT_PRIVATE_HPP
#define CLIENT_PRIVATE_HPP

#include "url.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/utility/string_view.hpp>
#include <cppcodec/base64_default_rfc4648.hpp> // Used for basic authentication.
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

#if defined(ENABLE_HTTPS) || defined(ENABLE_DIGEST)
#ifndef ENABLE_DIGEST
#define ENABLE_DIGEST
#endif
#include "digestauthenticator.hpp"
#endif

namespace simple_http {

enum client_state
{
    Resolve,
    Connect,
    Handshake,
    RequestSend,
    Header,
    Contents,
    Complete
};

enum fail_reason
{
    Unknown,
    FormatError,
    ResolveError,
    ConnectionError,
    HandshakeError,
    Timeout,
    WriteError,
    ReadError
};

using empty_body_request = boost::beast::http::request<boost::beast::http::empty_body>;
using string_body_request = boost::beast::http::request<boost::beast::http::string_body>;
using empty_body_response = boost::beast::http::response<boost::beast::http::empty_body>;
using string_body_response = boost::beast::http::response<boost::beast::http::string_body>;

template<typename RequestBody, typename ResponseBody>
class client_private_http;

template<typename RequestBody, typename ResponseBody>
class client_private_ssl;

template<typename RequestBody, typename ResponseBody>
class basic_client;

template<typename RequestBody, typename ResponseBody>
class client_private
{
    using ResponseParser = boost::beast::http::response_parser<ResponseBody>;
    using HttpPrivate = client_private_http<RequestBody, ResponseBody>;
    using SslPrivate = client_private_ssl<RequestBody, ResponseBody>;
    using BodyValue = typename RequestBody::value_type;

public:
    static std::shared_ptr<client_private<RequestBody, ResponseBody>> privateForRequest(
        const url& uri, std::shared_ptr<basic_client<RequestBody, ResponseBody>> cl)
    {
        if (uri.scheme() == url::SchemeHttp()) {
            return std::make_shared<HttpPrivate>(cl->m_io, cl);
        }
#ifdef ENABLE_HTTPS
        if (uri.scheme() == url::SchemeHttps()) {
            return std::make_shared<SslPrivate>(cl->m_io, cl);
        }
#endif
        cl->failure(FormatError, "Error unsupported scheme.");
        return nullptr;
    }

    void performRequest(const url& uri, boost::beast::http::verb method, BodyValue requestBody,
                        boost::string_view contentType, int maxRedirects, bool basicAuth,
                        int version)
    {
        c->m_maxRedirects = maxRedirects;
        m_url = uri;
        m_request.version(version);
        m_request.method(method);
        m_request.target(m_url.target());
        m_request.set(boost::beast::http::field::host, m_url.host());
        m_request.set(boost::beast::http::field::user_agent, c->userAgent());
        if (!contentType.empty()) {
            m_request.set(boost::beast::http::field::content_type, contentType);
        }
        if (method == boost::beast::http::verb::post) {
            m_request.body() = requestBody;
            m_request.prepare_payload();
        }
        if (basicAuth) {
            generateBasicAuthentication();
        }
        startTimeout();
        startResolve();
    }

    void abort()
    {
        boost::system::error_code ec;
        c->m_state = Complete;
        m_timeout.cancel();
        closeSocket(ec);
        if (c->m_responseHandler) {
            c->m_responseHandler = nullptr;
        }
        if (c->m_failHandler) {
            c->m_failHandler = nullptr;
        }
        // not_connected happens sometimes so don't bother reporting it.
        if (ec && ec != boost::system::errc::not_connected) {
            c->failure(Unknown, "Unexpected Error: " + ec.message());
        }
    }

protected:
    explicit client_private(boost::asio::io_context& io,
                            std::shared_ptr<basic_client<RequestBody, ResponseBody>> cl)
      : c{cl}, m_resolver{io}, m_timeout{io}
    {}

    virtual ~client_private() {}

    void startTimeout()
    {
        m_timeout.expires_from_now(boost::posix_time::milliseconds{c->m_timeoutMs});
        m_timeout.async_wait(
            std::bind(&client_private::checkTimeout, shared_from_this(), std::placeholders::_1));
    }

    void checkTimeout(const boost::system::error_code& ec)
    {
        if (!ec) {
            std::string stateString;
            switch (c->m_state) {
            case Resolve:
                stateString = "resolve";
                break;
            case Connect:
                stateString = "connect";
                break;
            case Handshake:
                stateString = "handshake";
                break;
            case RequestSend:
                stateString = "request";
                break;
            case Header:
                stateString = "header";
                break;
            case Contents:
                stateString = "contents";
                break;
            case Complete:
                return;
            }
            c->failure(Timeout, "Transfer timeout during " + stateString);
            abort();
        } else if (ec != boost::asio::error::operation_aborted) {
            fail(Timeout, "Transfer timer error: " + ec.message());
        }
    }

    void resetTimeout(client_state state)
    {
        c->m_state = state;
        auto self(shared_from_this());
        m_timeout.expires_from_now(boost::posix_time::milliseconds{c->m_timeoutMs});
    }

    void startResolve()
    {
        resetTimeout(Resolve);
        m_resolver.async_resolve(m_url.host().to_string(), m_url.port().to_string(),
                                 std::bind(&client_private::onResolve, shared_from_this(),
                                           std::placeholders::_1, std::placeholders::_2));
    }

    void onResolve(boost::system::error_code ec,
                   boost::asio::ip::tcp::resolver::results_type results)
    {
        if (ec) {
            fail(ResolveError, "Error resolving target: " + ec.message());
            return;
        }
        m_resolveResults = results;
        connectSocket();
    }

    void onConnect(boost::system::error_code ec)
    {
        if (ec) {
            fail(ConnectionError, "Error connecting: " + ec.message());
            return;
        }
        sendRequest();
    }

    void clearResponse()
    {
        m_responseParser.~ResponseParser();
        new (&m_responseParser) ResponseParser{};
    }

    void onWrite(boost::system::error_code ec, std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);
        if (ec) {
            fail(WriteError, "Error writing request: " + ec.message());
            return;
        }
        initiateReadHeader();
    }

    void onReadHeader(boost::system::error_code ec, std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);
        if (ec) {
            // Error during read of header.
            fail(ReadError, "Error in response header: " + ec.message());
            return;
        }
        initiateRead();
    }

    void onRead(boost::system::error_code ec, std::size_t bytes_transferred)
    {
        boost::ignore_unused(bytes_transferred);
        if (ec) {
            fail(ReadError, "Error reading response: " + ec.message());
            return;
        }
        m_timeout.cancel(); // Finished with connection before this point.
        if (handle()) {
            abort(); // This gracefully closes the client connection.
        }
    }

    bool handle()
    {
        const std::set<boost::beast::http::status> redirectCodes{
            boost::beast::http::status::moved_permanently, boost::beast::http::status::found,
            boost::beast::http::status::temporary_redirect};
        if (m_responseParser.get().result() == boost::beast::http::status::unauthorized) {
            if (generateAuthentication(
                    m_responseParser.get()[boost::beast::http::field::www_authenticate])) {
                // Request again with authentication!
                if (m_responseParser.keep_alive()) {
                    sendRequest();
                } else {
                    connectSocket();
                }
                return false;
            }
        } else if (c->m_maxRedirects > 0 && redirectCodes.count(m_responseParser.get().result())) {
            // follow redirect.
            url newLocation{m_responseParser.get()[boost::beast::http::field::location]};
            if (newLocation.host() == m_url.host() && newLocation.port() == m_url.port()) {
                m_url = std::move(newLocation);
                if (m_responseParser.keep_alive()) {
                    sendRequest();
                } else {
                    connectSocket();
                }
            } else {
                // Request is for a new server
                c->performRequest(std::move(newLocation), m_request.method(), m_request.body(),
                                  m_request[boost::beast::http::field::content_type],
                                  c->m_maxRedirects - 1, c->m_basicAuthForce, m_request.version());
            }
            return false;
        }
        try {
            c->m_responseHandler(m_request, m_responseParser.get());
        } catch (std::bad_function_call& /*f*/) {
            // Discard silently.
        }
        return true;
    }

    void fail(fail_reason reason, boost::string_view message)
    {
        try {
            c->m_failHandler(m_request, m_responseParser.get(), reason, message);
        } catch (std::bad_function_call& /*f*/) {
            // Discard silently.
        }
        abort();
    }

    bool generateAuthentication(boost::string_view authenticate)
    {
        if (c->m_username.empty() || c->m_password.empty() ||
            !m_request[boost::beast::http::field::authorization].empty()) {
            return false;
        }
        if (boost::ifind_first(authenticate, "digest")) {
#ifdef ENABLE_DIGEST
            return generateDigestAuth(authenticate, boost::string_view());
#else
            return false;
#endif
        } else {
            generateBasicAuthentication();
            return true;
        }
    }

    void generateBasicAuthentication()
    {
        std::string credentials{c->m_username};
        credentials += ":" + c->m_password;
        m_request.set(boost::beast::http::field::authorization,
                      "Basic " + base64::encode(credentials));
    }

#ifdef ENABLE_DIGEST
    bool generateDigestAuth(boost::string_view authenticate, boost::string_view body)
    {
        digest_authenticator authenticator(authenticate, c->m_username, c->m_password,
                                           m_request.target(), to_string(m_request.method()), body);
        if (authenticator.generateAuthorization()) {
            m_request.set(boost::beast::http::field::authorization, authenticator.authorization());
            return true;
        }
        return false;
    }
#endif

    virtual void connectSocket() = 0;
    virtual void sendRequest() = 0;
    virtual void initiateReadHeader() = 0;
    virtual void initiateRead() = 0;
    virtual void closeSocket(boost::system::error_code& ec) = 0;

    boost::beast::flat_buffer m_buffer;
    ResponseParser m_responseParser;
    boost::beast::http::request<RequestBody> m_request;
    boost::asio::ip::tcp::resolver::results_type m_resolveResults;
    std::shared_ptr<basic_client<RequestBody, ResponseBody>> c;

private:
    virtual std::shared_ptr<client_private> shared_from_this() = 0;

    boost::asio::ip::tcp::resolver m_resolver;
    boost::asio::deadline_timer m_timeout;
    url m_url;
};

} // namespace simple_http

#endif // CLIENT_PRIVATE_HPP

max_stars_repo_name: haleyConnelly/genny

max_issues_repo_name: haleyConnelly/genny

max_forks_repo_name: haleyConnelly/genny


text:
#include <hpx/hpx_init.hpp>
#include <hpx/include/lcos.hpp>
#include <hpx/runtime/threads/topology.hpp>
#include <hpx/include/util.hpp>
#include <hpx/util/unwrapped.hpp>

#include <boost/assign/std/vector.hpp>
#include <boost/cstdint.hpp>
#include <boost/format.hpp>

#include <atomic>

using hpx::lcos::shared_future;
using hpx::lcos::future;

using std::atomic;
using std::vector;
using std::cout;
using std::endl;

int delay_length;
atomic<int> task_counter{0};

void placeholder_task() {
    float a = 0.;
    for(int i = 0; i < delay_length; i++)
        a += i;
    if(a < 0)
        printf("%f \n", a);
}
void wrapper_task() {
    placeholder_task();
    task_counter--;
}

void print_task_time() {
    auto start = hpx::util::high_resolution_clock::now();
    for(int i = 0; i < 1000; i++) {
        placeholder_task();
    }
    auto total_time = hpx::util::high_resolution_clock::now() - start;
    cout << "task time for delay = " << delay_length << " = " << (total_time)/1000 << " nanoseconds" << endl;
}

uint64_t task_spawn_wait(int total_tasks) {
    uint64_t start = hpx::util::high_resolution_clock::now();
    vector<future<void>> tasks;
    tasks.reserve(total_tasks);
    for(int i = 0; i < total_tasks; i++) {
        tasks.push_back(hpx::async(placeholder_task));
    }
    hpx::wait_all(tasks);
    return hpx::util::high_resolution_clock::now() - start;
}

uint64_t task_spawn_count(int total_tasks) {
    uint64_t start = hpx::util::high_resolution_clock::now();
    task_counter = 0;
    for(int i = 0; i < total_tasks; i++) {
        task_counter++;
        hpx::async(wrapper_task);
    }
    while(task_counter > 0) {
        hpx::this_thread::yield();
    }
    return hpx::util::high_resolution_clock::now() - start;
}

uint64_t task_apply_count(int total_tasks) {
    uint64_t start = hpx::util::high_resolution_clock::now();
    task_counter = 0;
    for(int i = 0; i < total_tasks; i++) {
        task_counter++;
        hpx::apply(wrapper_task);
    }
    while(task_counter > 0) {
        hpx::this_thread::yield();
    }
    return hpx::util::high_resolution_clock::now() - start;
}

// Nested tasking:

void nested_wait_spawner(int num_tasks) {
    vector<future<void>> tasks;
    tasks.reserve(num_tasks);
    for(int i = 0; i < num_tasks; i++) {
        tasks.push_back(hpx::async(placeholder_task));
    }
    hpx::wait_all(tasks);
}

uint64_t nested_task_wait(int level1, int level2) {
    uint64_t start = hpx::util::high_resolution_clock::now();
    vector<future<void>> tasks;
    tasks.reserve(level1);
    for(int i = 0; i < level1; i++) {
        tasks.push_back(hpx::async(nested_wait_spawner, level2));
    }
    hpx::wait_all(tasks);
    return hpx::util::high_resolution_clock::now() - start;
}

// These functions are used for the nested_task_apply_count test
void counting_task(atomic<int> &local_counter) {
    placeholder_task();
    local_counter--;
}
void nested_spawner(int num_tasks, atomic<int> &local_counter) {
    for(int i = 0; i < num_tasks; i++) {
        local_counter++;
        hpx::apply(counting_task, boost::ref(local_counter));
    }
    local_counter--;
}
uint64_t nested_task_apply_count(int level1, int level2) {
    uint64_t start = hpx::util::high_resolution_clock::now();
    atomic<int> local_task_counter{0};
    for(int i = 0; i < level1; i++) {
        local_task_counter++;
        hpx::apply(nested_spawner, level2, boost::ref(local_task_counter));
    }
    while(local_task_counter > 0) {
        hpx::this_thread::yield();
    }
    return hpx::util::high_resolution_clock::now() - start;
}
//-----------------------------------------------------------------------------

int hpx_main(boost::program_options::variables_map& vm) {
    delay_length = vm["delay_length"].as<int>();
    int num_threads = hpx::get_os_thread_count();
    int total_tasks = vm["task_count"].as<int>();
    int nesting1 = num_threads;
    int nesting2 = total_tasks;
    total_tasks *= num_threads;

    print_task_time();

    cout << "wait  time ( " << total_tasks << " ) = " << task_spawn_wait(total_tasks) << endl;

    cout << "apply time ( " << total_tasks << " ) = " << task_apply_count(total_tasks) << endl;

    cout << "nested-wait(" << nesting1 << "," << nesting2  << ") = "
        << nested_task_wait(nesting1, nesting2) << endl;
    cout << "nested-wait(" << nesting2 << "," << nesting1  << ") = "
        << nested_task_wait(nesting2, nesting1) << endl;

    cout << "nested     (" << nesting1 << "," << nesting2  << ") = "
         << nested_task_apply_count(nesting1, nesting2) << endl;
    cout << "nested     (" << nesting2 << "," << nesting1  << ") = "
         << nested_task_apply_count(nesting2, nesting1) << endl;

    return hpx::finalize();
}

int main(int argc, char **argv) {
    using namespace boost::assign;
    std::vector<std::string> cfg;
    cfg += "hpx.os_threads=" +
        boost::lexical_cast<std::string>(hpx::threads::hardware_concurrency());

    boost::program_options::options_description
       desc_commandline("Usage: " HPX_APPLICATION_STRING " [options]");

    using boost::program_options::value;
    desc_commandline.add_options()
        ( "reps", value<int>()->default_value(20),
          "number of times to repeat the benchmark")
        ( "task_count", value<int>()->default_value(1024),
          "number of tasks to spawn (default 1024*num_threads")
        ( "delay_length", value<int>()->default_value(10000),
          "size of work to be done in the task") ;

    return hpx::init(desc_commandline, argc, argv, cfg);
}


text:
/*    Copyright (c) 2010-2018, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 *
 *    Notes
 *      If tabs are used as spaces, it doesn't work. The separator should also be tabs then.
 *
 */

#include <vector>
#include <fstream>
#include <sstream>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include "tudat/io/matrixTextFileReader.h"
#include "tudat/io/streamFilters.h"

namespace tudat
{
namespace input_output
{

//! Read the file and return the data matrix.
Eigen::MatrixXd readMatrixFromFile( const std::string& relativePath, const std::string& separators,
                                    const std::string& skipLinesCharacter )
{
    // Open input and output.
    std::fstream file( relativePath.c_str( ), std::ios::in );
    if ( file.fail( ) )
    {
        throw std::runtime_error( "Data file could not be opened: " + relativePath );
    }

    std::stringstream filteredStream( std::ios::in | std::ios::out );
    {
        // Filter the file stream. This needs to be in its own scope, because filtering_stream::
        // flush( ) does not work if the underlying end point is a stringstream, so the flush has
        // to be forced by letting the filtering_stream go out of scope.
        boost::iostreams::filtering_ostream filterProcessor;
        for ( unsigned int i = 0; i < skipLinesCharacter.size( ); i++ )
        {
            // Remove all comments from the stream.
            filterProcessor.push( input_output::stream_filters::RemoveComment(
                                      skipLinesCharacter[ i ], true ) );
        }

        // Add the output to the filter chain.
        filterProcessor.push( filteredStream );

        // Copy the input to the filter.
        boost::iostreams::copy( file, filterProcessor );
    }

    // Seek stream back to start.
    filteredStream.seekg( 0, std::ios::beg );

    // Read the filtered stream into lines.
    std::vector< std::string > lines_;
    while ( !filteredStream.eof( ) )
    {
        std::string line_;
        getline( filteredStream, line_ );
        if ( !line_.empty( ) )
        {
            boost::trim_all( line_ );
            lines_.push_back( line_ );
        }
    }

    // If there are no lines, return an empty matrix.
    if ( lines_.empty( ) )
    {
        return Eigen::MatrixXd( );
    }

    const std::string realSeparators = std::string( separators ) + " ";

    // Determine the number of columns from.
    std::vector< std::string > lineSplit_;
    boost::algorithm::split( lineSplit_, lines_[ 0 ], boost::is_any_of( realSeparators ),
            boost::algorithm::token_compress_on );
    const unsigned int numberOfColumns = lineSplit_.size( );

    // Initialize the matrix with sizes obtained from the number of lines and the entries in the
    // first line.
    Eigen::MatrixXd dataMatrix_( lines_.size( ), numberOfColumns );
    for ( int rowIndex = 0; rowIndex < dataMatrix_.rows( ); rowIndex++ )
    {
        lineSplit_.clear( );

        // Read current line and split into separate entries.
        boost::algorithm::split( lineSplit_, lines_[ rowIndex ],
                                 boost::is_any_of( realSeparators ),
                                 boost::algorithm::token_compress_on );

        // Check if number of column entries in line matches the number of columns in the matrix.
        // If not, throw a runtime error.
        if ( lineSplit_.size( ) != numberOfColumns )
        {
            throw std::runtime_error(
                        "Number of columns in row " + std::to_string( rowIndex ) + " is " +
                        std::to_string( lineSplit_.size( ) ) + " should be " +
                        std::to_string( numberOfColumns ) );
        }

        // Put single line entries into matrix as doubles.
        for ( int columnIndex = 0; columnIndex < dataMatrix_.cols( ); columnIndex++ )
        {
            boost::trim( lineSplit_.at( columnIndex ) );
            dataMatrix_( rowIndex, columnIndex ) =
                    std::stod( lineSplit_.at( columnIndex ) );
        }
    }

    return dataMatrix_;
}

} // namespace input_output
} // namespace tudat


text:
#include <pimg/ImageData.h>
#include <sm_const.h>
#include <SM_Calc.h>
#include <pimg/ImageData.h>
#include <unirender/Blackboard.h>
#include <painting2/DrawRT.h>
#include <node2/RenderSystem.h>
#include <sx/ResFileHelper.h>
#include <ns/NodeFactory.h>
#include <facade/ResPool.h>

#include <boost/filesystem.hpp>

#include <string>

namespace
{

bool Rotate(const std::string& src_path, const std::string& dst_path, float angle)
{
	if (sx::ResFileHelper::Type(src_path.c_str()) != sx::RES_FILE_IMAGE) {
		return false;
	}

	static const bool PRE_MUL_ALPHA(false);
	auto img = facade::ResPool::Instance().Fetch<pimg::ImageData>(src_path, PRE_MUL_ALPHA);
	float hw = img->GetWidth() * 0.5f;
	float hh = img->GetHeight() * 0.5f;

	float rad = angle * SM_DEG_TO_RAD;
	int w = static_cast<int>(std::ceil(sm::rotate_vector(sm::vec2(hw, hh), -rad).x * 2));
	int h = static_cast<int>(std::ceil(sm::rotate_vector(sm::vec2(-hw, hh), -rad).x * 2));

	auto casset = ns::NodeFactory::CreateAssetComp(src_path);
	if (!casset) {
		return false;
	}

	sm::Matrix2D trans;
	trans.SetTransformation(0, 0, rad, 1, 1, 0, 0, 0, 0);

	pt2::DrawRT rt;
	rt.Draw<n0::CompAsset>(*casset, [&](const n0::CompAsset& casset, const sm::Matrix2D& mt) {
		n2::RenderSystem::Draw(casset, trans * mt);
	}, true);
	rt.StoreToFile(dst_path.c_str(), w, h);

	return true;
}

}

namespace trans
{

void RotateImage(const std::string& src_path, const std::string& dst_path, float angle)
{
	if (boost::filesystem::is_directory(src_path))
	{
		boost::filesystem::recursive_directory_iterator itr(src_path), end;
		while (itr != end)
		{
			std::string src_filepath = itr->path().string();
			auto relative_path = boost::filesystem::relative(src_filepath, src_path);
			auto dst_filepath = boost::filesystem::absolute(relative_path, dst_path);
			Rotate(src_filepath, dst_filepath.string(), angle);
			++itr;
		}
	}
	else
	{
		Rotate(src_path, dst_path, angle);
	}
}

}

max_stars_repo_name: xzrunner/toolchain

max_issues_repo_name: xzrunner/toolchain

max_forks_repo_name: xzrunner/toolchain


text:
#pragma once

#include <httplib/detail/common.hpp>

#include <boost/container/small_vector.hpp>
#include <boost/optional.hpp>
#include <boost/utility/string_view.hpp>

#include <cstdlib>
#include <string>

HTTPLIB_OPEN_NAMESPACE

struct token_t {
    std::string value;

    // Compare case-insensitively.
    bool equals(boost::string_view value) const;
};

// *( "," OWS ) token *( OWS "," [ OWS token ] )
struct token_list_t {
    using container_type = boost::container::small_vector<token_t, 2>;

    container_type tokens;

    bool has(boost::string_view token) const;
};

inline bool operator==(const token_t &one, const token_t &another) {
    return one.equals(another.value);
}

inline bool operator!=(const token_t &one, const token_t &another) {
    return !(one == another);
}

inline bool operator==(const token_t &one, boost::string_view another) {
    return one.equals(another);
}

inline bool operator!=(const token_t &one, boost::string_view another) {
    return !(one == another);
}

inline bool operator==(boost::string_view one, const token_t &another) {
    return another.equals(one);
}

inline bool operator!=(boost::string_view one, const token_t &another) {
    return !(one == another);
}

namespace detail {

bool parse_token_list(boost::string_view data, token_list_t &result);

} // namespace detail

// Parse a list from a header value.
boost::optional<token_list_t> parse_token_list(boost::string_view data);

// Parse a list from a sequence of header values.
template<class It>
boost::optional<token_list_t> parse_token_list(It begin, It end) {
    if (begin == end) {
        return boost::none;
    }

    token_list_t result;

    for (; begin != end; ++begin) {
        if (!detail::parse_token_list(*begin, result)) {
            return boost::none;
        }
    }

    return result;
}

HTTPLIB_CLOSE_NAMESPACE


text:
#ifndef uri__parsers__rules__uri__host_hpp
#define uri__parsers__rules__uri__host_hpp

#include <string>

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

#include <uri/parsers/rules/uri/character.hpp>
#include <uri/parsers/rules/uri/ip.hpp>

namespace uri {
namespace parsers {
namespace rules {
namespace uri {

template < typename Iterator >
class host
{
public:
    using rule_type = boost::spirit::qi::rule< Iterator, std::string() >;

public:
    // clang-format off
    host()
    {
        namespace ascii = boost::spirit::ascii;

        // host          =  IP-literal /  IPv4address /  reg-name
        _host            = _IP_literal | _ip.v4()     | _reg_name;
        _host.name("uri.host");

        // IP-literal    = "["                  (  IPv6address /  IPvFuture    )   "]"
        _IP_literal      = ascii::char_('[') >> ( _ip.v6()     | _ip.vFuture() ) >> ascii::char_(']');

        // reg-name      = *(  unreserved /   pct-encoded /   sub-delims )
        _reg_name        = *( _char.unreserved() | _char.percent_encoded() | _char.sub_delims() );
    }
    // clang-format on

    void enable_debug()
    {
        BOOST_SPIRIT_DEBUG_NODE( _host );
        BOOST_SPIRIT_DEBUG_NODE( _IP_literal );
        BOOST_SPIRIT_DEBUG_NODE( _reg_name );
    }

    const rule_type & operator()() const { return _host; }

private:
    rule_type                         _host;
    rule_type                         _IP_literal;
    rule_type                         _reg_name;
    rules::uri::ip< Iterator >        _ip;
    rules::uri::character< Iterator > _char;
};

} // namespace uri
} // namespace rules
} // namespace parsers
} // namespace uri

#endif // #define uri__parsers__rules__uri__host_hpp

max_stars_repo_name: ledocc/uri

max_issues_repo_name: ledocc/uri

max_forks_repo_name: ledocc/uri


text:
//
// Created by Lehdari on 25.6.2018.
//

#ifndef MYCELIUM_MATHTYPES_HPP
#define MYCELIUM_MATHTYPES_HPP

#include <Eigen/Dense>
#include <cstdint>

namespace mm {

    using Vec2f = Eigen::Vector2f;
    using Vec3f = Eigen::Vector3f;
    using Vec4f = Eigen::Vector4f;
    using Mat2f = Eigen::Matrix2f;
    using Mat3f = Eigen::Matrix3f;
    using Mat4f = Eigen::Matrix4f;

    using Vec2d = Eigen::Vector2d;
    using Vec3d = Eigen::Vector3d;
    using Vec4d = Eigen::Vector4d;
    using Mat2d = Eigen::Matrix2d;
    using Mat3d = Eigen::Matrix3d;
    using Mat4d = Eigen::Matrix4d;

}

#endif // MYCELIUM_MATHTYPES_HPP

max_stars_repo_name: Lehdari/Mycelium

max_issues_repo_name: Lehdari/Mycelium

max_forks_repo_name: Lehdari/Mycelium


text:
#include <boost/foreach.hpp>
#include <string>
#include <iostream>

#include <rose.h>
#include <Outliner.hh>

#include "Outline.h"
#include "GenericDepAttrib.h"
#include "Utils.h"
#include "annotatePragmas.h"
#define foreach BOOST_FOREACH

using namespace std;
using namespace Outliner;
using namespace SageBuilder;
using namespace SageInterface;

static const string filletAttrib = "FILLET";

SgStatement * getPreviousStatementForOutline( SgStatement * targetStmt );

/******************************************************************************
 A FILLET attribute and unitary class.

 Definition:
   Fillet = the 'flesh' of the program; the program without the skeleton.

 Attributes used here:
   filletAttrib -- unit attribute: non-skeleton code.
     Invariants of this attribute:
       if set on node, none of its children/ancestors have it set!
*/

class FilletAttribute : public AstAttribute {
  public:
    FilletAttribute() {}
    FilletAttribute *copy() const {
      return new FilletAttribute(*this);
    }
    std::string attribute_class_name() { return "FilletAttribute"; }
    std::string toString() { return "FilletAttribute"; }
};

FilletAttribute fillet = FilletAttribute();

bool isFillet(SgNode *s) {
  return s->getAttribute(filletAttrib) == (AstAttribute*) &fillet;
}

/******************************************************************************
 shouldOmit - determine if attributes consider this statement skeleton or not
 */
bool shouldOmitGivenAPI(APISpec *spec, SgStatement *s) {
    if( s->getAttribute("APIDep") != NULL ){
      GenericDepAttribute *attr = dynamic_cast<GenericDepAttribute*>(s->getAttribute("APIDep"));
      ROSE_ASSERT( attr != NULL );
      return spec->shouldOmit(attr);
    }
    return true;
}

// FIXME: ADHOC: For debugging!
string ppPresRemUnd (PresRemUnd x);

/******************************************************************************
  SPECIFICATION:
    ifNotSkeletonAddFilletAttrib =
      do
      let toremove = ...
      foreach s in toremove:
        if s->get_parent `notElem` toremove && ... then
          s->setAttribute(filletAttrib,fillet)
*/
void ifNotSkeletonAddFilletAttrib (APISpecs *specs, SgProject *proj) {
  std::set< SgStatement* > toremove;

  // FIXME[CR2]: why 'synthesizedAttribute'? why query (vs traversal)?
  NodeQuerySynthesizedAttributeType stmts =
      NodeQuery::querySubTree(proj, V_SgStatement);

  bool debug = false;

  for (size_t i = 0; i < stmts.size(); i++) {
      SgStatement *s = isSgStatement(stmts[i]);
      if (debug) cout << "O: stmt: " << s->unparseToString() << endl;
      if (debug) printf ("%p\n", s);
      if (debug) cout << "O: attr: " << ppPresRemUnd (getPresRemUnd(s)) << endl;

      bool stdOmit = false;
      APISpecs::iterator it;
      for(it = specs->begin(); it != specs->end(); ++it) {
          if(shouldOmitGivenAPI(*it, s)) {
              stdOmit = true;
          }
      }

      // pragmas override 'stdOmit' status:
      bool omit;
      switch (getPresRemUnd(s))
        {
        case pragma_undef   : omit = stdOmit; break;
        case pragma_preserve: omit = false;   break;
        case pragma_remove  : omit = true;    break;
        default             : assert(0);
        }

      if (omit)
        toremove.insert(s);

      if (debug) printf ("O: omit = %i\n", omit);
      if (debug) printf ("O: stdOmit = %i\n", stdOmit);
  }

  std::set< SgStatement* >::iterator si = toremove.begin();
  for(; si != toremove.end(); ++si) {
      SgStatement *s = *si;
      SgStatement *parStmt = isSgStatement(s->get_parent());

      // FIXME: Q. class defn / func defn are statements?
      if(!(    (parStmt && toremove.find(parStmt) != toremove.end())
            || isSgDeclarationStatement(s)
            || isSgReturnStmt(s)
            || isSgClassDefinition(s)
            || isSgFunctionDefinition(s)))
        s->setAttribute(filletAttrib,&fillet);
  }
}

/******************************************************************************
 blockifySpansOfFillets(ss) - take spans of adjacent FILLETS and put them
   into new basic blocks.
   - the FILLET attributes must be removed and the new basic block must
     get the FILLET attributes.
   - PRECONDITION: not 'in' a FILLET.
 */
void blockifySpansOfFillets (SgBasicBlock *block) {

  // if (debug)  std::cout << "blockifySpansOfFillets:" << std::endl;

  SgStatementPtrList &ss = block->get_statements();
  SgStatementPtrList::iterator i = ss.begin();

  while (i != ss.end()) {

    // Find first FILLET:
    i = find_if (i, ss.end(), isFillet);
    if (i == ss.end())
      break;

    // make 'j' point after end of of span:
    //   I.e.,
    //   j == ss.end() or +1 past the 'span',
    SgStatementPtrList::iterator j = i+1;
    while (j != ss.end() && isFillet(*j))
      ++j;

    // Move FILLET span to new basic block, if length > 1:
    if (j > i+1) {

      // Create new Basic Block:
      //  - mark this as a transformation (required)
      Sg_File_Info* srcLoc =
        Sg_File_Info::generateDefaultFileInfoForTransformationNode();
      ROSE_ASSERT(srcLoc != NULL);
      SgBasicBlock *newblock = new SgBasicBlock(srcLoc);
      SgStatementPtrList &newss = newblock->get_statements();
      newblock->set_parent(block);
      newblock->setAttribute(filletAttrib,&fillet);

      // Add the statements to it, updated accordingly:
      newss.assign (i,j);
      for (SgStatementPtrList::iterator k = newss.begin(); k < newss.end(); ++k)
      {
        (*k)->set_parent(newblock);
        (*k)->removeAttribute(filletAttrib);
      }

      // Replace/Remove from 'block'/'ss':
      i = ss.erase(i,j);
      i = ss.insert(i,newblock);
    }
    ++i;
  }
}

/******************************************************************************
 moveFilletSpansToNewBasicBlocks =
   // and mv attribs from children to new BasicBlock
   foreach basicblock b that's not contained in a FILLET:
     do
     ss <- statements b
     if any (\s-> s->getAttribute(filletAttrib) == fillet) ss then
       do
       ss' <- blockifySpansOfFillets ss
     b.statements := ss'
*/

class Move : public AstPrePostProcessing {
  private:
    bool inFillet;   // true if node has ancestor with FILLET attribute.
  public:
    virtual void preOrderVisit (SgNode* n);
    virtual void postOrderVisit(SgNode* n);
};

void Move::preOrderVisit(SgNode* n) {
  if (!inFillet && isFillet(n))
    inFillet = true;
}

void Move::postOrderVisit(SgNode* n) {
  if (isFillet(n)) {
    inFillet = false;
  } else if (!inFillet) {
    SgBasicBlock* block = isSgBasicBlock(n);
    if (block)
      blockifySpansOfFillets( block );
  }
}

void moveFilletSpansToNewBasicBlocks (SgProject *proj) {
  Move traversal;
  traversal.traverseInputFiles (proj);
}

/*******************************************************************************
 outlineStatementsWithFilletAttrib (proj,outline) -
  foreach statement s in proj:
    if s->getAttribute() == FILLET then
      if outline
        Outliner::outline(s)
      else
        remove(s)

  NOTE:  If 'outline' is false, just remove the 'Fillet's.
*/
void outlineStatementsWithFilletAttrib (SgProject *proj, bool outline) {
  // FIXME[CR2]: why 'synthesizedAttribute'? why query (vs traversal)?
  NodeQuerySynthesizedAttributeType stmts =
    NodeQuery::querySubTree(proj, V_SgStatement);

  for(size_t i = 0; i < stmts.size(); i++) {
    SgStatement *s = isSgStatement(stmts[i]);
    if (isFillet(s)) {
      if (outline) {
        if (! Outliner::isOutlineable(s))
          std::cout << "statement isn't outlineable: "
                    << "(" << s->unparseToString() << ")@"
                    << std::endl;
        else
          Outliner::outline(s);
      } else if (isSgStatement(s->get_parent())) {
          // FIXME: above condition needed, but not sure if there's
          //        a more elegant way?
        // JED: TODO this looks like the place where we want to check for preprocessing info
        // and if it's there move it to a nearby (next?) AST node
        SgStatement * const previousStatement = getPreviousStatementForOutline(s);
        ROSE_ASSERT( previousStatement != NULL );
        if( SgBasicBlock * const block = isSgBasicBlock(s) ){
          foreach(SgStatement * stmt, block->get_statements()){
            ROSE_ASSERT( stmt != NULL );
            if( AttachedPreprocessingInfoType* comments = stmt->getAttachedPreprocessingInfo() ){
              std::vector<int> captureList;
              int commentIndex = 0;
              if (debug) std::cout << "stmt is '"              << stmt->unparseToString()              << "'" << std::endl;
              if (debug) std::cout << "previousStatement is '" << previousStatement->unparseToString() << "'" << std::endl;
              for(AttachedPreprocessingInfoType::iterator i = comments->begin(); i != comments->end(); ++i){
                captureList.push_back(commentIndex);
                commentIndex++;
              }
              moveCommentsToNewStatement(stmt,captureList,previousStatement,true);
              //removeStatement(stmt); // JED: should be fine to remove the whole block below instead of the individual statements
                                       // as the previousStatement was chosen relative to the block.
            }
          }
        }
        removeStatement(s);
        if(debug) {
          const std::string action = outline ? "Replacing " : "Removing ";
          std::cout << action
                    << s->class_name() << " "
                    << "(" << s->unparseToString() << ")@"
                    << s->getFilenameString()
                    << std::endl;
        }
      }
    }
  }
}

/*

This function exists to workaround the way ROSE's builtin getPreviousStatement
works.  Specificaly, getPreviousStatement on an SgBasicBlock (or the first
statement of a scope) returns the surrounding scope. Instead, we want to find
the previous program statement in those cases. In the case of an SgBasicBlock
this function will search through the statements of the surrounding scope and
return the statement before the basic block. In the case where that is also a
scope it will recursively go up a level.

Note: This function is not very well tested.

*/
SgStatement * getPreviousStatementForOutline( SgStatement * const targetStmt )
{
  if( SgBasicBlock * const block = isSgBasicBlock(targetStmt) ){
    // Find the statement before the basic block, we can't simply call getPreviousStatement for basic blocks
    // because that actually returns a scope statement. The best we can do is to then scan that scope for
    // the statement before the basic block.
    SgStatement * previousStatement = NULL;
    if( SgScopeStatement * const scope = block->get_scope() ){
      // TODO: look at the rose code for getPreviousStatement for an example of how to write this search
      if (isSgIfStmt(scope)) {
         // TODO: I believe this is wrong. Write a test case...
         previousStatement = isSgStatement(targetStmt->get_parent());
         ROSE_ASSERT (isSgIfStmt(previousStatement) != NULL);
         if( previousStatement == NULL ){
           if (debug) std::cout << "previousStatement is null, and statement is " << targetStmt->unparseToString() << std::endl;
         }
         ROSE_ASSERT( previousStatement != NULL );
      } else {
        // refactor this search to a separate function
        SgStatementPtrList & statementList = scope->getStatementList();
        Rose_STL_Container<SgStatement*>::iterator i = statementList.begin();
        Rose_STL_Container<SgStatement*>::iterator previousStatementIterator =  statementList.end();
        while ( ( i != statementList.end() ) && ( (*i) != targetStmt ) ){
          previousStatementIterator = i++;
        }

        if ( previousStatementIterator != statementList.end() ){
          previousStatement = *previousStatementIterator;
        }
        if( previousStatement == NULL ){
          if (debug) std::cout << "previousStatement is null, and statement is " << targetStmt->unparseToString() << std::endl;
          previousStatement = getPreviousStatementForOutline(scope);
        }
        ROSE_ASSERT( previousStatement != NULL );
      }
    } else {
      ROSE_ASSERT( false ); // What does it mean if the block has no scope?
    }
    // JED: What TODO when previousStatement is null?
    if( previousStatement == NULL ){
      if (debug) std::cout << "previousStatement is null, and statement is " << targetStmt->unparseToString() << std::endl;
    }
    return previousStatement;
  } else {
    return getPreviousStatement(targetStmt);
  }
}

/*******************************************************************************
 skeletonizeCode - the exported function.
*/
void skeletonizeCode (APISpecs *specs, SgProject *proj, bool outline,
                      bool genPDF) {
  ifNotSkeletonAddFilletAttrib(specs, proj);
  if (debug) AstTests::runAllTests(proj);

  // Create report of attributes on AST (before code changes):
  if(debug) std::cout << "Generating PDF report" << std::endl;
  if(genPDF) generatePDF(*proj);

  moveFilletSpansToNewBasicBlocks(proj);
    // and moves fillet attrib from these spans to the new BasicBlocks
  if (debug) AstTests::runAllTests(proj);

  outlineStatementsWithFilletAttrib(proj, outline);
  if (debug) AstTests::runAllTests(proj);
}

ext: cc

max_stars_repo_name: ouankou/rose

max_issues_repo_name: sujankh/rose-matlab

max_forks_repo_name: sujankh/rose-matlab


text:
// Copyright 2019-present MongoDB Inc.
//
// 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.

#include <testlib/helpers.hpp>
#include <yaml-cpp/yaml.h>

#include <boost/exception/diagnostic_information.hpp>

#include <bsoncxx/json.hpp>

#include <testlib/ActorHelper.hpp>
#include <testlib/MongoTestFixture.hpp>

namespace {
using namespace genny::testing;
namespace BasicBson = bsoncxx::builder::basic;

TEST_CASE_METHOD(MongoTestFixture, "MultiCollectionQuery", "[standalone][MultiCollectionQuery]") {

    dropAllDatabases();
    auto events = ApmEvents{};
    auto db = client.database("mydb");

    SECTION("Query documents in a collection with sort and limit") {
        genny::NodeSource config(R"(
      SchemaVersion: 2018-07-01
      Actors:
      - Name: MultiCollectionQuery
        Type: MultiCollectionQuery
        Phases:
        - Repeat: 1
          Database: mydb
          Threads: 1
          CollectionCount: 1
          Filter: {a: 1}
          Limit: 1
          Sort: {a: 1}
          ReadConcern:
            Level: local
      Metrics:
        Format: csv
      )",
                                 "");

        try {
            auto coll = db.collection("Collection1");
            coll.insert_one(BasicBson::make_document(BasicBson::kvp("a", 1)));
            coll.insert_one(BasicBson::make_document(BasicBson::kvp("a", 2)));

            auto count = coll.count_documents(BasicBson::make_document());
            REQUIRE(count == 2);

            auto apmCallback = makeApmCallback(events);
            genny::ActorHelper ah(
                config.root(), 1, MongoTestFixture::connectionUri().to_string(), apmCallback);
            ah.run([](const genny::WorkloadContext& wc) { wc.actors()[0]->run(); });

            for (auto&& event : events) {
                REQUIRE(event.command["limit"].get_int64() == 1);
                REQUIRE(event.command["sort"].get_document().view() ==
                        BasicBson::make_document(BasicBson::kvp("a", 1)));
                auto readMode = event.command["$readPreference"]["mode"].get_utf8().value;
                REQUIRE(std::string(readMode) == "primaryPreferred");
            }

        } catch (const std::exception& e) {
            auto diagInfo = boost::diagnostic_information(e);
            INFO("CAUGHT " << diagInfo);
            FAIL(diagInfo);
        }
    }
}
}  // namespace

max_stars_repo_name: samanca/genny

max_issues_repo_name: samanca/genny

max_forks_repo_name: samanca/genny


text:
/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright 2016-2017 Davide Faconti
*  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 Willow Garage, Inc. nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
* *******************************************************************/

#pragma once

#include <vector>
#include <deque>
#include <iostream>
#include <memory>
#include <boost/container/stable_vector.hpp>
#include <boost/noncopyable.hpp>

namespace Ros2Introspection {

/**
 * @brief Element of the tree. it has a single parent and N >= 0 children.
 */
template <typename T> class TreeNode
{
public:

  typedef std::vector<TreeNode> ChildrenVector; // dangerous because of pointer invalidation (but faster)

  TreeNode(const TreeNode* parent );

  const TreeNode* parent() const  { return _parent; }

  const T& value() const          { return _value; }
  void setValue( const T& value)  { _value = value; }

  const ChildrenVector& children()const   { return _children; }
  ChildrenVector& children()              { return _children; }

  const TreeNode* child(size_t index) const { return &(_children[index]); }
  TreeNode* child(size_t index) { return &(_children[index]); }

  TreeNode *addChild(const T& child );

  bool isLeaf() const { return _children.empty(); }

private:
  const TreeNode*   _parent;
  T                 _value;
  ChildrenVector    _children;
};

template <typename T> class Tree
{
public:
  Tree(): _root( new TreeNode<T>(nullptr) ) {}

   /// Mutable pointer to the root of the tree.
  TreeNode<T>* root() { return _root.get(); }

  const TreeNode<T>* root() const { return _root.get(); }

  friend std::ostream& operator<<(std::ostream& os, const Tree& _this){
    _this.print_impl(os, _this.croot() , 0);
    return os;
  }

private:

  void print_impl(std::ostream& os, const TreeNode<T> *node, int indent ) const;

  std::unique_ptr<TreeNode<T>> _root;
};

//-----------------------------------------

template <typename T> inline
std::ostream& operator<<(std::ostream &os, const std::pair<const TreeNode<T>*, const TreeNode<T>* >& tail_head )
{
  const TreeNode<T>* tail = tail_head.first;
  const TreeNode<T>* head = tail_head.second;

  if( !head ) return os;

  const TreeNode<T>* array[64];
  int index = 0;
  array[index++] = head;

  while( !head || head != tail)
  {
    head = head->parent();
    array[index++] = head;
  };
  array[index] = nullptr;
  index--;

  while ( index >=0)
  {
    if( array[index] ){
      os << array[index]->value();
    }
    if( index >0 )  os << ".";
    index--;
  }
  return os;
}

template <typename T> inline
void Tree<T>::print_impl(std::ostream &os, const TreeNode<T>* node, int indent) const
{
  for (int i=0; i<indent; i++) os << " ";
  os << node->value() << std::endl;

  for (const auto& child: node->children() )
  {
    print_impl(os, &child, indent+3);
  }
}

template <typename T> inline
TreeNode<T>::TreeNode(const TreeNode *parent):
  _parent(parent)
{

}

template <typename T> inline
TreeNode<T> *TreeNode<T>::addChild(const T& value)
{
  assert(_children.capacity() > _children.size() );
  _children.push_back( TreeNode<T>(this) );
  _children.back().setValue( value );
  return &_children.back();
}

}


text:
// optional_last_value function object (documented as part of Boost.Signals2)

// Copyright Frank Mori Hess 2007-2008.
// Copyright Douglas Gregor 2001-2003.
// Distributed under the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// See http://www.boost.org/libs/signals2 for library home page.

#ifndef BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
#define BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP

#include <boost/core/no_exceptions_support.hpp>
#include <boost/optional.hpp>
#include <boost/signals2/expired_slot.hpp>

namespace boost {
  namespace signals2 {

    template<typename T>
      class optional_last_value
    {
    public:
      typedef optional<T> result_type;

      template<typename InputIterator>
        optional<T> operator()(InputIterator first, InputIterator last) const
      {
        optional<T> value;
        while (first != last)
        {
          BOOST_TRY
          {
            value = *first;
          }
          BOOST_CATCH(const expired_slot &) {}
          BOOST_CATCH_END
          ++first;
        }
        return value;
      }
    };

    template<>
      class optional_last_value<void>
    {
    public:
      typedef void result_type;
      template<typename InputIterator>
        result_type operator()(InputIterator first, InputIterator last) const
      {
        while (first != last)
        {
          BOOST_TRY
          {
            *first;
          }
          BOOST_CATCH(const expired_slot &) {}
          BOOST_CATCH_END
          ++first;
        }
        return;
      }
    };
  } // namespace signals2
} // namespace boost
#endif // BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP