text:
/*=============================================================================
    Copyright (c) 2001-2003 Daniel Nuffer
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_ast.hpp>
#include <boost/assert.hpp>

#include <iostream>
#include <stack>
#include <functional>
#include <string>

// This example shows how to use an AST and tree_iter_node instead of
// tree_val_node
////////////////////////////////////////////////////////////////////////////
using namespace std;
using namespace BOOST_SPIRIT_CLASSIC_NS;

typedef char const*         iterator_t;
typedef tree_match<iterator_t, node_iter_data_factory<> >
    parse_tree_match_t;

typedef parse_tree_match_t::tree_iterator iter_t;

typedef ast_match_policy<iterator_t, node_iter_data_factory<> > match_policy_t;
typedef scanner<iterator_t, scanner_policies<iter_policy_t, match_policy_t> > scanner_t;
typedef rule<scanner_t> rule_t;

//  grammar rules
rule_t expression, term, factor, integer;

////////////////////////////////////////////////////////////////////////////
long evaluate(parse_tree_match_t hit);
long eval_expression(iter_t const& i);
long eval_term(iter_t const& i);
long eval_factor(iter_t const& i);
long eval_integer(iter_t const& i);

long evaluate(parse_tree_match_t hit)
{
    return eval_expression(hit.trees.begin());
}

long eval_expression(iter_t const& i)
{
    cout << "In eval_expression. i->value = " <<
        string(i->value.begin(), i->value.end()) <<
        " i->children.size() = " << i->children.size() << endl;

    cout << "ID: " << i->value.id().to_long() << endl;

    if (i->value.id() == integer.id())
    {
        BOOST_ASSERT(i->children.size() == 0);
        return strtol(i->value.begin(), 0, 10);
    }
    else if (i->value.id() == factor.id())
    {
        // factor can only be unary minus
        BOOST_ASSERT(*i->value.begin() == '-');
        return - eval_expression(i->children.begin());
    }
    else if (i->value.id() == term.id())
    {
        if (*i->value.begin() == '*')
        {
            BOOST_ASSERT(i->children.size() == 2);
            return eval_expression(i->children.begin()) *
                eval_expression(i->children.begin()+1);
        }
        else if (*i->value.begin() == '/')
        {
            BOOST_ASSERT(i->children.size() == 2);
            return eval_expression(i->children.begin()) /
                eval_expression(i->children.begin()+1);
        }
        else
            BOOST_ASSERT(0);
    }
    else if (i->value.id() == expression.id())
    {
        if (*i->value.begin() == '+')
        {
            BOOST_ASSERT(i->children.size() == 2);
            return eval_expression(i->children.begin()) +
                eval_expression(i->children.begin()+1);
        }
        else if (*i->value.begin() == '-')
        {
            BOOST_ASSERT(i->children.size() == 2);
            return eval_expression(i->children.begin()) -
                eval_expression(i->children.begin()+1);
        }
        else
            BOOST_ASSERT(0);
    }
    else
        BOOST_ASSERT(0); // error

   return 0;
}

////////////////////////////////////////////////////////////////////////////
int
main()
{
    BOOST_SPIRIT_DEBUG_RULE(integer);
    BOOST_SPIRIT_DEBUG_RULE(factor);
    BOOST_SPIRIT_DEBUG_RULE(term);
    BOOST_SPIRIT_DEBUG_RULE(expression);
    //  Start grammar definition
    integer     =   leaf_node_d[ lexeme_d[ (!ch_p('-') >> +digit_p) ] ];
    factor      =   integer
                |   inner_node_d[ch_p('(') >> expression >> ch_p(')')]
                |   (root_node_d[ch_p('-')] >> factor);
    term        =   factor >>
                    *(  (root_node_d[ch_p('*')] >> factor)
                      | (root_node_d[ch_p('/')] >> factor)
                    );
    expression  =   term >>
                    *(  (root_node_d[ch_p('+')] >> term)
                      | (root_node_d[ch_p('-')] >> term)
                    );
    //  End grammar definition

    cout << "/////////////////////////////////////////////////////////\n\n";
    cout << "\t\tThe simplest working calculator...\n\n";
    cout << "/////////////////////////////////////////////////////////\n\n";
    cout << "Type an expression...or [q or Q] to quit\n\n";

    string str;
    while (getline(cin, str))
    {
        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
            break;

        const char* str_begin = str.c_str();
        const char* str_end = str.c_str();
        while (*str_end)
            ++str_end;

        scanner_t scan(str_begin, str_end);

        parse_tree_match_t hit = expression.parse(scan);

        if (hit && str_begin == str_end)
        {
#if defined(BOOST_SPIRIT_DUMP_PARSETREE_AS_XML)
            // dump parse tree as XML
            std::map<rule_id, std::string> rule_names;
            rule_names[&integer] = "integer";
            rule_names[&factor] = "factor";
            rule_names[&term] = "term";
            rule_names[&expression] = "expression";
            tree_to_xml(cout, hit.trees, str.c_str(), rule_names);
#endif

            // print the result
            cout << "parsing succeeded\n";
            cout << "result = " << evaluate(hit) << "\n\n";
        }
        else
        {
            cout << "parsing failed\n";
        }
    }

    cout << "Bye... :-) \n\n";
    return 0;
}


text:
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2009. 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/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
//[doc_managed_copy_on_write
#include <boost/interprocess/managed_mapped_file.hpp>
#include <fstream> //std::fstream
#include <iterator>//std::distance

//<-
#include "../test/get_process_id_name.hpp"
//->

int main()
{
   using namespace boost::interprocess;

   //Define file names
   //<-
   #if 1
   std::string managed_file(boost::interprocess::ipcdetail::get_temporary_path());
   managed_file += "/"; managed_file += test::get_process_id_name();
   const char *ManagedFile = managed_file.c_str();
   std::string managed_file2(boost::interprocess::ipcdetail::get_temporary_path());
   managed_file2 += "/"; managed_file2 += test::get_process_id_name();  managed_file2 += "_2";
   const char *ManagedFile2 = managed_file2.c_str();
   #else
   //->
   const char *ManagedFile  = "MyManagedFile";
   const char *ManagedFile2 = "MyManagedFile2";
   //<-
   #endif
   //->

   //Try to erase any previous managed segment with the same name
   file_mapping::remove(ManagedFile);
   file_mapping::remove(ManagedFile2);
   remove_file_on_destroy destroyer1(ManagedFile);
   remove_file_on_destroy destroyer2(ManagedFile2);

   {
      //Create an named integer in a managed mapped file
      managed_mapped_file managed_file(create_only, ManagedFile, 65536);
      managed_file.construct<int>("MyInt")(0u);

      //Now create a copy on write version
      managed_mapped_file managed_file_cow(open_copy_on_write, ManagedFile);

      //Erase the int and create a new one
      if(!managed_file_cow.destroy<int>("MyInt"))
         throw int(0);
      managed_file_cow.construct<int>("MyInt2");

      //Check changes
      if(managed_file_cow.find<int>("MyInt").first && !managed_file_cow.find<int>("MyInt2").first)
         throw int(0);

      //Check the original is intact
      if(!managed_file.find<int>("MyInt").first && managed_file.find<int>("MyInt2").first)
         throw int(0);

      {  //Dump the modified copy on write segment to a file
         std::fstream file(ManagedFile2, std::ios_base::out | std::ios_base::binary);
         if(!file)
            throw int(0);
		 file.write(static_cast<const char *>(managed_file_cow.get_address()), (std::streamsize)managed_file_cow.get_size());
      }

      //Now open the modified file and test changes
      managed_mapped_file managed_file_cow2(open_only, ManagedFile2);
      if(managed_file_cow2.find<int>("MyInt").first && !managed_file_cow2.find<int>("MyInt2").first)
         throw int(0);
   }
   {
      //Now create a read-only version
      managed_mapped_file managed_file_ro(open_read_only, ManagedFile);

      //Check the original is intact
      if(!managed_file_ro.find<int>("MyInt").first && managed_file_ro.find<int>("MyInt2").first)
         throw int(0);

      //Check the number of named objects using the iterators
      if(std::distance(managed_file_ro.named_begin(),  managed_file_ro.named_end())  != 1 &&
         std::distance(managed_file_ro.unique_begin(), managed_file_ro.unique_end()) != 0 )
         throw int(0);
   }
   return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>

ext: cpp


text: #include <boost/mpl/aux_/preprocessed/msvc60/apply.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#pragma once

/*
   A standard two-phase approach for summary-based,
   _context-insensitive_ inter-procedural analysis.
*/

#include <crab/common/debug.hpp>
#include <crab/common/stats.hpp>
#include <crab/cfg/cfg.hpp>   // hasher of function declarations
#include <crab/cg/cg_bgl.hpp> // for sccg.hpp
#include <crab/analysis/graphs/sccg.hpp>
#include <crab/analysis/graphs/topo_order.hpp>
#include <crab/analysis/fwd_analyzer.hpp>
#include <crab/analysis/abs_transformer.hpp>
#include <crab/analysis/inter_fwd_analyzer_ds.hpp>
#include <crab/analysis/dataflow/liveness.hpp>

#include <boost/range/iterator_range.hpp>

#include <vector>
#include <set>
#include <string>
#include <memory>
#include <algorithm>
#include <unordered_map>

namespace crab {

namespace analyzer {

/**
 * Abstract transformer specialized for computing summaries.
 * class SumTable stores the summaries.
 **/
template<class SumTable>
class bu_summ_abs_transformer final:
    public intra_abs_transformer<typename SumTable::abs_domain_t> {

public:

  typedef typename SumTable::abs_domain_t summ_abs_domain_t;
  typedef summ_abs_domain_t abs_dom_t;
  typedef typename abs_dom_t::number_t number_t;

private:

  typedef intra_abs_transformer<abs_dom_t> intra_abs_transform_t;
  typedef typename intra_abs_transform_t::abs_transform_api_t abs_transform_api_t;
  typedef typename abs_dom_t::varname_t varname_t;
  typedef typename abs_dom_t::variable_t variable_t;
  typedef typename abs_dom_t::linear_expression_t linear_expression_t;

  SumTable* m_sum_tbl;

public:

  using typename abs_transform_api_t::callsite_t;

  static void reuse_summary(abs_dom_t& caller,
			    const callsite_t& cs,
			    const typename SumTable::Summary& summ) {
    // Before a summary is plug-in we rename it with unique variable
    // names so we avoid naming clashes in cases like for instance
    // summary variables have same names as lhs of callsites.

    CRAB_LOG("inter",
	     crab::outs() << "    Reuse summary at " << cs << "\n";
	     crab::outs() << "    Summary:" << summ << "\n";);

    std::set<variable_t> actuals, formals;
    // --- matching formal and actual parameters
    auto inputs = summ.get_renamed_inputs();
    unsigned i=0;
    // XXX: propagating down
    for (auto p : inputs) {
      auto a = cs.get_arg_name(i);
      if (!(a == p)) {
	CRAB_LOG("inter",
		 crab::outs() << "\t\tPropagate from caller to callee "
		 << p << ":=" << a << "\n");
	inter_transformer_helpers<abs_dom_t>::unify(caller, p, a);
      }
      ++i;
      actuals.insert(a); formals.insert(p);
    }

    // --- meet caller's inv with summ
    auto sum_inv = summ.get_renamed_sum();
    caller = caller & sum_inv;
    CRAB_LOG("inter",
	     crab::outs() << "\t\tAfter meet caller and summary: "
	     <<  caller << "\n");

    // --- matching callsite's lhs and callee's return value
    // XXX: propagate from the return values in the callee to the
    // lhs variables of the callsite in the caller.
    auto const &caller_vts = cs.get_lhs();
    auto const &callee_outs = summ.get_renamed_outputs();
    assert(caller_vts.size() == callee_outs.size());

    auto caller_it = caller_vts.begin();
    auto caller_et = caller_vts.end();
    auto callee_it = callee_outs.begin();

    // XXX: propagating up
    for (; caller_it != caller_et; ++caller_it, ++callee_it){
      auto vt = *caller_it;
      auto r = *callee_it;
      CRAB_LOG("inter",
	       crab::outs() << "\t\tPropagate from callee to caller "
	       << vt << ":=" << r << "\n");
      inter_transformer_helpers<abs_dom_t>::unify(caller, vt, r);
      actuals.insert(vt); formals.insert(r);
    }

    // --- remove from caller only formal parameters so we can keep
    //     as much context from the caller as possible
    std::vector<variable_t> vs;
    std::set_difference(formals.begin(), formals.end(),
			actuals.begin(), actuals.end(), std::back_inserter(vs));
    caller.forget(vs);

    CRAB_LOG("inter",
	     crab::outs() << "\t\tAfter forgetting formal parameters {";
	     for(auto v: vs) crab::outs() << v << ";";
	     crab::outs() << "}=" <<  caller << "\n");
  }

public:

  bu_summ_abs_transformer(abs_dom_t* inv, SumTable* sum_tbl)
    : intra_abs_transform_t(inv)
    , m_sum_tbl(sum_tbl) { }

  ~bu_summ_abs_transformer() = default;

  virtual void exec(callsite_t& cs) override {
    if (!m_sum_tbl) {
      CRAB_WARN("The summary table is empty: ignored analysis of callsite");
    } else {
      if (m_sum_tbl->hasSummary(cs)) {
	auto summ = m_sum_tbl->get(cs);
	reuse_summary(*(this->m_inv), cs, summ);
      }
      else {
	CRAB_WARN("summary not found for ", cs);
	for (auto vt: cs.get_lhs()) {
	  *(this->m_inv) -= vt;  // havoc
	}
      }
    }
  }
};

/// Conversion between top-down and bottom-up domains.
template<typename Domain>
inline void convert_domains(Domain from, Domain& to) { to = from; }

template<typename Domain1, typename Domain2>
inline void convert_domains(Domain1 from, Domain2& to) {
  if (from.is_bottom()) {
    to.set_to_bottom();
    return;
  }

  CRAB_LOG("inter",
	   crab::outs() << "Converting from "
	                << Domain1::getDomainName() << " to "
	                << Domain2::getDomainName() << " might lose precision if "
	                << Domain1::getDomainName() << " is more precise than "
	                << Domain2::getDomainName() << "\n");

  bool pre_bot = false;
  if (::crab::CrabSanityCheckFlag) {
    pre_bot = from.is_bottom();
  }

  for (auto cst : from.to_linear_constraint_system()) {
    to += cst;
  }

  if (::crab::CrabSanityCheckFlag) {
    bool post_bot = to.is_bottom();
    if (!(pre_bot || !post_bot)) {
      CRAB_ERROR("Invariant became bottom after conversion between domains");
    }
  }

}

/**
 * Abstract transformer specialized for performing top-down forward
 * traversal while reusing summaries at the callsites.
 * class CallCtxTable stores the calling context.
 **/
template<class SumTable, class CallCtxTable>
class td_summ_abs_transformer final:
    public intra_abs_transformer<typename CallCtxTable::abs_domain_t> {

public:

  typedef typename SumTable::abs_domain_t     summ_abs_domain_t;
  typedef typename CallCtxTable::abs_domain_t call_abs_domain_t;
  typedef call_abs_domain_t abs_dom_t;
  typedef typename abs_dom_t::number_t number_t;

private:

  typedef intra_abs_transformer<abs_dom_t> intra_abs_transform_t;

public:

  typedef typename intra_abs_transform_t::abs_transform_api_t abs_transform_api_t;
  using typename abs_transform_api_t::callsite_t;

private:

  SumTable* m_sum_tbl;
  CallCtxTable* m_call_tbl;

public:

  td_summ_abs_transformer(abs_dom_t* inv,
			  SumTable* sum_tbl, CallCtxTable* call_tbl)
    : intra_abs_transform_t(inv),
      m_sum_tbl(sum_tbl),
      m_call_tbl(call_tbl) { }

  ~td_summ_abs_transformer() = default;

  virtual void exec(callsite_t& cs) override {
    if (!m_sum_tbl) {
      CRAB_WARN("The summary table is empty");
    } else if(m_sum_tbl->hasSummary(cs)) {
      auto summ = m_sum_tbl->get(cs);

      CRAB_LOG("inter",
	       crab::outs() << "    Pluging caller context into callee\n"
	                    << "    Summary: " << summ << "\n");

      ///////
      /// Generate the callee context and store it.
      ///////
      typedef typename abs_dom_t::variable_t variable_t;

      abs_dom_t callee_ctx_inv(*(this->m_inv));
      // --- matching formal and actual parameters
      // XXX: propagating down
      unsigned i=0;
      const std::vector<variable_t>& inputs = summ.get_inputs();
      for (variable_t p : inputs) {
	variable_t a = cs.get_arg_name(i);
	if (!(a == p)) {
	  inter_transformer_helpers<abs_dom_t>::unify(callee_ctx_inv, p, a);
	}
	++i;
      }

      // --- project only onto formal parameters
      callee_ctx_inv.project(inputs);
      // --- store the callee context
      CRAB_LOG("inter",
	       crab::outs() << "\t\tCallee context stored: "
	                    << callee_ctx_inv << "\n");

      m_call_tbl->insert(cs, callee_ctx_inv);

      /////
      // Generate the continuation at the caller
      /////

      // --- convert this->m_inv to the language of summ_abs_dom_t(summ)
      summ_abs_domain_t caller_ctx_inv;
      convert_domains(*(this->m_inv), caller_ctx_inv);
      // forget the variables of the lhs of the callsite, otherwise
      // caller_ctx_inv and m_inv may be inconsistent if the lhs
      // variables are constrained before the callsite (e.g., x=-5;
      // x := abs(x);)
      for (auto vt: cs.get_lhs()) {
	*(this->m_inv) -= vt;
      }

      CRAB_LOG("inter",
	       crab::outs() << "\t\tCaller context: " <<  caller_ctx_inv << "\n");

      // --- reuse summary to do the continuation
      bu_summ_abs_transformer<SumTable>::reuse_summary(caller_ctx_inv, cs, summ);
      CRAB_LOG("inter",
	       crab::outs() << "\t\tCaller context after plugin summary: "
	                    << caller_ctx_inv << "\n");

      // --- convert back inv to the language of abs_dom_t
      convert_domains(caller_ctx_inv, *(this->m_inv));
      CRAB_LOG("inter",
	       crab::outs() << "\t\tCaller continuation after "
	                    <<  cs << "=" <<  *(this->m_inv) << "\n");
      return;
    } else {
      // --- no summary found: havoc output variables
      CRAB_WARN("No summary found during top-down pass for ", cs);
    }

    // We could not reuse a summary or summary not found. We havoc
    // output variables of the callsite.
    for(auto vt: cs.get_lhs()) {
      *(this->m_inv) -= vt;
    }
  }
};

template<typename CallGraph,
	 // abstract domain used for the bottom-up phase
	 typename BU_Dom,
	 // abstract domain used for the top-down phase
	 typename TD_Dom>
class inter_fwd_analyzer {

  typedef typename CallGraph::node_t cg_node_t;
  typedef typename CallGraph::edge_t cg_edge_t;

  typedef inter_fwd_analyzer<CallGraph, BU_Dom, TD_Dom>  this_type;

public:

  typedef CallGraph cg_t;
  typedef typename cg_node_t::cfg_t cfg_t;
  typedef typename cfg_t::varname_t varname_t;
  typedef typename cfg_t::number_t number_t;
  typedef typename cfg_t::variable_t variable_t;
  typedef liveness<cfg_t> liveness_t;
  typedef std::unordered_map<cfg_t, const liveness_t*> liveness_map_t;

private:

  typedef summary_table <cfg_t, BU_Dom> summ_tbl_t;
  typedef call_ctx_table <cfg_t, TD_Dom> call_tbl_t;

public:

  typedef bu_summ_abs_transformer<summ_tbl_t> bu_abs_tr;
  typedef td_summ_abs_transformer<summ_tbl_t, call_tbl_t> td_abs_tr;
  typedef fwd_analyzer<cfg_t, bu_abs_tr> bu_analyzer;
  typedef fwd_analyzer<cfg_t, td_abs_tr> td_analyzer;
  typedef typename summ_tbl_t::Summary summary_t;
  typedef std::shared_ptr<summary_t> summary_ptr;
  // for checkers
  typedef TD_Dom abs_dom_t;
  typedef td_abs_tr abs_tr_t;

private:

  typedef std::shared_ptr<td_analyzer> td_analyzer_ptr;
  typedef std::unordered_map<std::size_t, td_analyzer_ptr> invariant_map_t;

  CallGraph m_cg;
  const liveness_map_t* m_live;
  invariant_map_t m_inv_map;
  summ_tbl_t m_summ_tbl;
  call_tbl_t m_call_tbl;
  unsigned int m_widening_delay;
  unsigned int m_descending_iters;
  size_t m_jump_set_size; // max size of the jump set (=0 if jump set disabled)

  const liveness_t* get_live(const cfg_t& c) {
    if (m_live) {
      auto it = m_live->find(c);
      if (it != m_live->end())
	return it->second;
    }
    return nullptr;
  }

public:

  inter_fwd_analyzer(CallGraph cg, const liveness_map_t* live,
		     // fixpoint parameters
		     unsigned int widening_delay=1,
		     unsigned int descending_iters=UINT_MAX,
		     size_t jump_set_size=0)
    : m_cg(cg), m_live(live),
      m_widening_delay(widening_delay),
      m_descending_iters(descending_iters),
      m_jump_set_size(jump_set_size) {
    CRAB_VERBOSE_IF(1, get_msg_stream() << "Type checking call graph ... ";);
    crab::CrabStats::resume("CallGraph type checking");
    cg.type_check();
    crab::CrabStats::stop("CallGraph type checking");
    CRAB_VERBOSE_IF(1, get_msg_stream() << "OK\n";);
  }

  inter_fwd_analyzer(const this_type& other) = delete;

  this_type& operator=(const this_type& other) = delete;

  void run(TD_Dom init = TD_Dom::top())  {

    CRAB_VERBOSE_IF(1, get_msg_stream() << "Started inter-procedural analysis\n";);
    CRAB_LOG("inter",
	     m_cg.write(crab::outs()); crab::outs() << "\n");

    crab::ScopedCrabStats __st__("Inter");

    bool has_noedges = true;
    for (auto const &n: boost::make_iterator_range(m_cg.nodes())) {
      if (m_cg.num_succs(n) > 0) {
	has_noedges = false;
	break;
      }
    }

    if (has_noedges) {
      // -- Special case when the program has been inlined.
      CRAB_LOG("inter",
	       crab::outs() << "Callgraph has no edges so no summaries are computed.\n");

      CRAB_LOG("inter",
	       m_cg.write(crab::outs());
	       crab::outs() << "\n";);

      for (auto &v: boost::make_iterator_range(m_cg.nodes())) {
	crab::ScopedCrabStats __st__("Inter.TopDown");

	auto cfg = v.get_cfg();
	assert(cfg.has_func_decl());
	auto fdecl = cfg.get_func_decl();
	std::string fun_name = fdecl.get_func_name();
	if (fun_name != "main") continue;

	CRAB_LOG("inter",
		 crab::outs() << "++ Analyzing function "
		 << fdecl.get_func_name() << "\n");

	auto abs_tr = std::make_shared<td_abs_tr>(&init, &m_summ_tbl, &m_call_tbl);
	auto a = std::make_shared<td_analyzer>(cfg, nullptr, &*abs_tr, get_live(cfg),
					       m_widening_delay,
					       m_descending_iters,
					       m_jump_set_size);

	a->run_forward();
	m_inv_map.insert({crab::cfg::cfg_hasher<cfg_t>::hash(fdecl), a});
      }
      return;
    }

    // -- General case
    std::vector<cg_node_t> rev_order;
    graph_algo::scc_graph<CallGraph> Scc_g(m_cg);
    graph_algo::rev_topo_sort(Scc_g, rev_order);

    CRAB_VERBOSE_IF(1,get_msg_stream() << "== Bottom-up phase ...\n";);
    for (auto n: rev_order) {
      crab::ScopedCrabStats __st__("Inter.BottomUp");
      std::vector<cg_node_t> &scc_mems = Scc_g.get_component_members(n);
      for (auto m: scc_mems) {

	auto cfg = m.get_cfg();
	assert(cfg.has_func_decl());
	auto fdecl = cfg.get_func_decl();
	std::string fun_name = fdecl.get_func_name();
	if (fun_name != "main") {
	  CRAB_VERBOSE_IF(1, get_msg_stream() << "++ Computing summary for "
	        	                      << fdecl.get_func_name() << "...\n";);
	  // --- collect inputs and outputs
	  std::vector<variable_t> formals, inputs, outputs;
	  formals.reserve(fdecl.get_num_inputs() + fdecl.get_num_outputs());
	  inputs.reserve(fdecl.get_num_inputs());
	  outputs.reserve(fdecl.get_num_outputs());

	  for (unsigned i=0; i < fdecl.get_num_inputs();i++) {
	    inputs.push_back(fdecl.get_input_name(i));
	    formals.push_back(fdecl.get_input_name(i));
	  }
	  for (unsigned i=0; i < fdecl.get_num_outputs();i++) {
	    outputs.push_back(fdecl.get_output_name(i));
	    formals.push_back(fdecl.get_output_name(i));
	  }

	  if (outputs.empty()) {
	    BU_Dom summary;
	    m_summ_tbl.insert(fdecl, summary, inputs, outputs);
	    CRAB_WARN("Skipped summary because function ", fdecl.get_func_name(),
		      " has no output parameters");
	  } else if (!cfg.has_exit()) {
	    CRAB_WARN("Skipped summary because function ", fdecl.get_func_name(),
		      " has no exit block");
	  } else {
	    // --- run the analysis
	    auto init_inv = BU_Dom::top();
	    bu_abs_tr abs_tr(&init_inv, &m_summ_tbl);
	    bu_analyzer a(cfg, nullptr, &abs_tr, get_live(cfg),
			  m_widening_delay, m_descending_iters, m_jump_set_size);
	    a.run_forward();

	      // --- project onto formal parameters and return values
	    BU_Dom summary = a.get_post(cfg.exit());
	    //crab::CrabStats::count(BU_Dom::getDomainName() + ".count.project");
	    summary.project(formals);
	    m_summ_tbl.insert(fdecl, summary, inputs, outputs);
	  }
	}
      }
    }

    CRAB_VERBOSE_IF(1, get_msg_stream() << "== Top-down phase ...\n";);
    bool is_root = true;
    for (auto n: boost::make_iterator_range(rev_order.rbegin(),
					    rev_order.rend())) {
      crab::ScopedCrabStats __st__("Inter.TopDown");
      std::vector<cg_node_t> &scc_mems = Scc_g.get_component_members(n);

      // The SCC is recursive if it has more than one element or
      // there is only one that calls directly to itself.
      bool is_recursive = (scc_mems.size() > 1) ||
	std::any_of(m_cg.succs(n).first, m_cg.succs(n).second,
		    [n](const cg_edge_t& e) {
		      return (n == e.dest());
		    });

      for (auto m: scc_mems) {
	auto cfg = m.get_cfg();
	assert(cfg.has_func_decl());
	auto fdecl = cfg.get_func_decl();
	CRAB_VERBOSE_IF(1, get_msg_stream() << "++ Analyzing function "
			<< fdecl.get_func_name() << "\n";);
	if (is_recursive) {
	  // If the SCC is recursive then what we have in
	  // m_call_tbl is incomplete and therefore it is unsound
	  // to use it. To remedy it, we insert another calling
	  // context with top value that approximates all the
	  // possible calling contexts during the recursive calls.
	  m_call_tbl.insert(fdecl, TD_Dom::top());
	}

	auto init_inv = init;
	if (is_root) {
	  is_root = false;
	} else {
	  init_inv = m_call_tbl.get_call_ctx(fdecl);
	}

	CRAB_LOG("inter",
		 crab::outs() << "    Starting analysis of "
		 << fdecl <<  " with " << init_inv << "\n");

	if (init_inv.is_bottom()) {
	  crab::outs() << "Top-down analysis for "
		       << fdecl.get_func_name()
		       << " started with bottom (i.e., dead function).\n";
	}
	auto abs_tr = std::make_shared<td_abs_tr>(&init_inv, &m_summ_tbl, &m_call_tbl);
	auto a = std::make_shared<td_analyzer>(cfg, nullptr, &*abs_tr, get_live(cfg),
					       m_widening_delay,
					       m_descending_iters,
					       m_jump_set_size);
	a->run_forward();
	m_inv_map.insert(std::make_pair(crab::cfg::cfg_hasher<cfg_t>::hash(fdecl), a));
      }
    }
    CRAB_VERBOSE_IF(1,get_msg_stream() << "Finished inter-procedural analysis\n";);
  }

  //! return the analyzed call graph
  CallGraph& get_call_graph() {
    return m_cg;
  }

  //! Return the invariants that hold at the entry of b in cfg
  TD_Dom get_pre(const cfg_t &cfg, typename cfg_t::basic_block_label_t b) const {
    assert(cfg.has_func_decl());
    auto fdecl = cfg.get_func_decl();
    auto const it = m_inv_map.find(crab::cfg::cfg_hasher<cfg_t>::hash(fdecl));
    if (it != m_inv_map.end()) {
      return it->second->get_pre(b);
    } else {
      return TD_Dom::top();
    }
  }

  //! Return the invariants that hold at the exit of b in cfg
  TD_Dom get_post(const cfg_t &cfg, typename cfg_t::basic_block_label_t b) const {
    assert(cfg.has_func_decl());
    auto fdecl = cfg.get_func_decl();
    auto const it = m_inv_map.find(crab::cfg::cfg_hasher<cfg_t>::hash(fdecl));
    if (it != m_inv_map.end()) {
      return it->second->get_post(b);
    } else {
      return TD_Dom::top();
    }
  }

  // clear all invariants
  void clear() {
    m_inv_map.clear();
  }

  //! Propagate inv through statements
  std::shared_ptr<abs_tr_t> get_abs_transformer(TD_Dom* inv) {
    return std::make_shared<abs_tr_t>(inv, &m_summ_tbl, &m_call_tbl);
  }

  //! Return true if there is a summary for a function
  bool has_summary(const cfg_t &cfg) const {
    assert(cfg.has_func_decl());
    auto fdecl = cfg.get_func_decl();
    return m_summ_tbl.hasSummary(fdecl);
  }

  //! Return the summary for a function
  summary_ptr get_summary(const cfg_t &cfg) const {
    assert(cfg.has_func_decl());
    auto fdecl = cfg.get_func_decl();
    if (m_summ_tbl.hasSummary(fdecl)) {
      summary_t summ = m_summ_tbl.get(fdecl);
      return std::make_shared<summary_t>(summ);
    } else {
      CRAB_WARN("Summary not found");
      return nullptr;
    }
  }

};

} // end namespace
} // end namespace


text:
#include <boost/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/int.hpp>
#include <boost/any.hpp>
#include <vector>
#include <algorithm>
#include "benchmark/benchmark.h"

namespace bm = benchmark;
namespace mpl = boost::mpl;

constexpr int nloops = 100;

using c1 = mpl::int_<1>;
using c2 = mpl::int_<2>;

struct virtual_unary {
    virtual ~virtual_unary() {}
    virtual double get(int) const noexcept = 0;
};

struct virtual_unary_val : virtual_unary {
    double val = 1.0;
    virtual double get(int) const noexcept { return val; }
};

struct virtual_unary_arr : virtual_unary {
    std::vector<double> x = std::vector<double>(nloops, 1.0);
    virtual double get(int i) const noexcept { return x[i]; }
};

static void virtual_method_1(bm::State& state) {
    while (state.KeepRunning()) {
        std::unique_ptr<virtual_unary> u(new virtual_unary_val());
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u->get(i));
    }
}

static void virtual_method_2(bm::State& state) {
    while (state.KeepRunning()) {
        std::unique_ptr<virtual_unary> u(new virtual_unary_arr());
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u->get(i));
    }
}

struct variant_unary {
    boost::variant<double, std::vector<double>> var;
    variant_unary(c1) : var(1.0) {}
    variant_unary(c2) : var(std::vector<double>(nloops, 1.0)) {}

    struct getter : boost::static_visitor<double> {
        int idx = 0;
        getter(int x) : idx(x) {}
        double operator()(const double& x) const noexcept {
            return x;
        }
        double operator()(const std::vector<double>& x) const noexcept {
            return x[idx];
        }
    };

    double get(int i) const noexcept {
        return boost::apply_visitor(getter(i), var);
    }
};

static void variant_method_1(bm::State& state) {
    c1 c;
    while (state.KeepRunning()) {
        variant_unary u(c);
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u.get(i));
    }
}

static void variant_method_2(bm::State& state) {
    c2 c;
    while (state.KeepRunning()) {
        variant_unary u(c);
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u.get(i));
    }
}

struct any_unary {
    boost::any var;
    any_unary(c1) : var(1.0) {}
    any_unary(c2) : var(std::vector<double>(nloops, 1.0)) {}
    double get(int i) const noexcept {
        if (var.type() == typeid(double))
            return boost::any_cast<const double&>(var);
        return boost::any_cast<const std::vector<double>&>(var)[i];
    }
};

static void any_method_1(bm::State& state) {
    c1 c;
    while (state.KeepRunning()) {
        any_unary u(c);
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u.get(i));
    }
}

static void any_method_2(bm::State& state) {
    c2 c;
    while (state.KeepRunning()) {
        any_unary u(c);
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u.get(i));
    }
}

struct nodefault {
    std::unique_ptr<double[]> p;
    nodefault(int n) : p(new double[n]) {
        std::fill(p.get(), p.get()+n, 1.0);
    }
    double operator[](int i) const noexcept { return p[i]; }
};

struct simple_unary {
    char type;
    union U {
        double val;
        nodefault arr;
        U(c1) : val(1.0) {}
        U(c2) : arr(100) {}
        ~U() {}
    } u;
    ~simple_unary() {
        if (type == 2)
            u.arr.~nodefault();
    }
    simple_unary(c1 c) : type(1), u(c) {}
    simple_unary(c2 c) : type(2), u(c) {}
    double get(int i) const noexcept {
        if (type == 1) return u.val;
        return u.arr[i];
    }
};

static void simple_method_1(bm::State& state) {
    c1 c;
    while (state.KeepRunning()) {
        simple_unary u(c);
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u.get(i));
    }
}

static void simple_method_2(bm::State& state) {
    c2 c;
    while (state.KeepRunning()) {
        simple_unary u(c);
        for (int i = 0; i < nloops; ++i)
            bm::DoNotOptimize(u.get(i));
    }
}

BENCHMARK(virtual_method_1);
BENCHMARK(virtual_method_2);
BENCHMARK(variant_method_1);
BENCHMARK(variant_method_2);
BENCHMARK(any_method_1);
BENCHMARK(any_method_2);
BENCHMARK(simple_method_1);
BENCHMARK(simple_method_2);

BENCHMARK_MAIN();


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

#pragma once
#include <string>
#include <vector>
#include <ostream>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

namespace cwcc {
	class mutability final {
		bool value{false};
	public:
		mutability() =default;
		mutability(bool value) : value{value} {}

		explicit
		operator bool() const noexcept { return value; }

		friend
		auto operator==(const mutability & lhs, const mutability & rhs) -> bool { return lhs.value == rhs.value; }
		friend
		auto operator<<(std::ostream & os, const mutability & self) -> std::ostream & { return os << (self.value ? "" : "const "); }
	};

	struct untemplated_type final {
		std::string name;

		friend
		auto operator==(const untemplated_type & lhs, const untemplated_type & rhs) -> bool { return lhs.name == rhs.name; }
		friend
		auto operator<<(std::ostream & os, const untemplated_type & self) -> std::ostream & { return os << self.name; }
	};

	struct array;
	struct array_ref;
	struct bitset;
	struct optional;
	struct optional_ref;
	struct tuple;
	struct variant;
	struct variant_ref;
	struct vector;
	struct intrusive_ptr;

	using templated_type = boost::variant<
		untemplated_type,
		boost::recursive_wrapper<array>,
		boost::recursive_wrapper<array_ref>,
		boost::recursive_wrapper<bitset>,
		boost::recursive_wrapper<optional>,
		boost::recursive_wrapper<optional_ref>,
		boost::recursive_wrapper<tuple>,
		boost::recursive_wrapper<variant>,
		boost::recursive_wrapper<variant_ref>,
		boost::recursive_wrapper<vector>,
		boost::recursive_wrapper<intrusive_ptr>
	>;

	struct mutability_type final {
		mutability mutable_;
		templated_type type;

		friend
		auto operator==(const mutability_type & lhs, const mutability_type & rhs) -> bool { return (lhs.mutable_ == rhs.mutable_) && (lhs.type == rhs.type); }
		friend
		auto operator<<(std::ostream & os, const mutability_type & self) -> std::ostream & {
			os << self.mutable_ << self.type;
			return os;
		}
	};

	struct array final {
		templated_type type;
		std::size_t size;

		friend
		auto operator==(const array & lhs, const array & rhs) -> bool { return (lhs.type == rhs.type) && (lhs.size == rhs.size); }
		friend
		auto operator<<(std::ostream & os, const array & self) -> std::ostream & { return os << "::cwc::array<" << self.type << ", " << self.size << '>'; }
	};

	struct array_ref final {
		mutability_type type;

		friend
		auto operator==(const array_ref & lhs, const array_ref & rhs) -> bool { return lhs.type == rhs.type; }
		friend
		auto operator<<(std::ostream & os, const array_ref & self) -> std::ostream & { return os << "::cwc::array_ref<" << self.type << '>'; }
	};

	struct bitset final {
		std::size_t size;

		friend
		auto operator==(const bitset & lhs, const bitset & rhs) -> bool { return lhs.size == rhs.size; }
		friend
		auto operator<<(std::ostream & os, const bitset & self) -> std::ostream & { return os << "::cwc::bitset<" << self.size << '>'; }
	};

	struct optional final {
		templated_type type;

		friend
		auto operator==(const optional & lhs, const optional & rhs) -> bool { return lhs.type == rhs.type; }
		friend
		auto operator<<(std::ostream & os, const optional & self) -> std::ostream & { return os << "::cwc::optional<" << self.type << '>'; }
	};

	struct optional_ref final {
		mutability_type type;

		friend
		auto operator==(const optional_ref & lhs, const optional_ref & rhs) -> bool { return lhs.type == rhs.type; }
		friend
		auto operator<<(std::ostream & os, const optional_ref & self) -> std::ostream & { return os << "::cwc::optional_ref<" << self.type << '>'; }
	};

	struct tuple final {
		std::vector<templated_type> types;

		friend
		auto operator==(const tuple & lhs, const tuple & rhs) -> bool { return lhs.types == rhs.types; }
		friend
		auto operator<<(std::ostream & os, const tuple & self) -> std::ostream & {
			assert(!self.types.empty());
			os << "::cwc::tuple<" << self.types[0];
			for(std::size_t i{1}; i < self.types.size(); ++i) os << ", " << self.types[i];
			os << '>';
			return os;
		}
	};

	struct variant final {
		std::vector<templated_type> types;

		friend
		auto operator==(const variant & lhs, const variant & rhs) -> bool { return lhs.types == rhs.types; }
		friend
		auto operator<<(std::ostream & os, const variant & self) -> std::ostream & {
			assert(!self.types.empty());
			os << "::cwc::variant<" << self.types[0];
			for(std::size_t i{1}; i < self.types.size(); ++i) os << ", " << self.types[i];
			os << '>';
			return os;
		}
	};

	struct variant_ref final {
		std::vector<mutability_type> types;

		friend
		auto operator==(const variant_ref & lhs, const variant_ref & rhs) -> bool { return lhs.types == rhs.types; }
		friend
		auto operator<<(std::ostream & os, const variant_ref & self) -> std::ostream & {
			assert(!self.types.empty());
			os << "::cwc::variant_ref<" << self.types[0];
			for(std::size_t i{1}; i < self.types.size(); ++i) os << ", " << self.types[i];
			os << '>';
			return os;
		}
	};

	struct vector final {
		templated_type type;

		friend
		auto operator==(const vector & lhs, const vector & rhs) -> bool { return lhs.type == rhs.type; }
		friend
		auto operator<<(std::ostream & os, const vector & self) -> std::ostream & { return os << "::cwc::vector<" << self.type << '>'; }
	};

	struct intrusive_ptr final {
		mutability_type type;

		friend
		auto operator==(const intrusive_ptr & lhs, const intrusive_ptr & rhs) -> bool { return lhs.type == rhs.type; }
		friend
		auto operator<<(std::ostream & os, const intrusive_ptr & self) -> std::ostream & { return os << "::cwc::intrusive_ptr<" << self.type << '>'; }
	};

	struct documentation final {
		std::string line;

		friend
		auto operator==(const documentation & lhs, const documentation & rhs) -> bool { return lhs.line == rhs.line; }
		friend
		auto operator<<(std::ostream & os, const documentation & self) -> std::ostream & { return os << "//" << self.line; }
	};

	struct param final {
		mutability mutable_;
		templated_type type;
		std::string name;

		friend
		auto operator==(const param & lhs, const param & rhs) -> bool { return (lhs.mutable_ == rhs.mutable_) && (lhs.type == rhs.type) && (lhs.name == rhs.name); }
	};

	struct enum_ final {
		static const std::size_t max_size{256};

		struct member final {
			std::vector<documentation> lines;
			std::string name;

			friend
			auto operator==(const member & lhs, const member & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name); }
			friend
			auto operator<<(std::ostream & os, const member & self) -> std::ostream &;
		};

		std::vector<documentation> lines;
		std::string name;
		std::vector<member> members;

		friend
		auto operator==(const enum_ & lhs, const enum_ & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.members == rhs.members); }
		friend
		auto operator<<(std::ostream & os, const enum_ & self) -> std::ostream &;
	};

	struct struct_ final {
		struct member final {
			std::vector<documentation> lines;
			templated_type type;
			std::vector<std::string> fields;

			friend
			auto operator==(const member & lhs, const member & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.type == rhs.type) && (lhs.fields == rhs.fields); }
			friend
			auto operator<<(std::ostream & os, const member & self) -> std::ostream &;
		};

		std::vector<documentation> lines;
		std::string name;
		std::vector<member> members;

		friend
		auto operator==(const struct_ & lhs, const struct_ & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.members == rhs.members); }
		friend
		auto operator<<(std::ostream & os, const struct_ & self) -> std::ostream &;
	};

	struct typedef_ final {
		std::vector<documentation> lines;
		std::string name;
		templated_type type;

		friend
		auto operator==(const typedef_ & lhs, const typedef_ & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.type == rhs.type); }
		friend
		auto operator<<(std::ostream & os, const typedef_ & self) -> std::ostream &;
	};

	struct interface final {
		struct method final {
			std::vector<documentation> lines;
			std::string name;
			std::vector<param> in;
			mutability mutable_;
			boost::optional<templated_type> out;

			auto params() const -> std::vector<param> {
				auto result = in;
				if(out) {
					param p;
					p.name = "cwc_ret";
					p.mutable_ = true;
					p.type = *out;
					result.push_back(p);
				}
				return result;
			}

			friend
			auto operator==(const method & lhs, const method & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.in == rhs.in) && (lhs.mutable_ == rhs.mutable_) && (lhs.out == rhs.out); }
		};
		std::vector<documentation> lines;
		std::string name;
		std::vector<method> methods;

		friend
		auto operator==(const interface & lhs, const interface & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.methods == rhs.methods); }
	};

	struct component final {
		struct constructor final {
			std::vector<documentation> lines;
			std::vector<param> params;

			friend
			auto operator==(const constructor & lhs, const constructor & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.params == rhs.params); }
		};
		std::vector<documentation> lines;
		std::string name;
		std::vector<std::string> interfaces;
		std::vector<constructor> members;

		auto factory() const -> interface;

		friend
		auto operator==(const component & lhs, const component & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.interfaces == rhs.interfaces) && (lhs.members == rhs.members); }
	};

	struct delegate final {
		std::vector<documentation> lines;
		std::string name;
		std::vector<param> in;
		boost::optional<templated_type> out;

		friend
		auto operator==(const delegate & lhs, const delegate & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.in == rhs.in) && (lhs.out == rhs.out); }
	};

	struct bundle final {
		std::vector<documentation> lines;
		std::string name;
		std::vector<boost::variant<component, enum_, struct_, typedef_, interface, delegate>> members;

		friend
		auto operator==(const bundle & lhs, const bundle & rhs) -> bool { return (lhs.lines == rhs.lines) && (lhs.name == rhs.name) && (lhs.members == rhs.members); }
	};
}

max_stars_repo_name: jmairboeck/CWC

max_issues_repo_name: jmairboeck/CWC

max_forks_repo_name: jmairboeck/CWC


text:
/* Boost numeric test of the runge kutta steppers test file

 Copyright 2012 Mario Mulansky
 Copyright 2012 Karsten Ahnert

 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)
*/

// disable checked iterator warning for msvc
#include <boost/config.hpp>
#ifdef BOOST_MSVC
    #pragma warning(disable:4996)
#endif

#define BOOST_TEST_MODULE numeric_runge_kutta

#include <iostream>
#include <cmath>

#include <boost/array.hpp>

#include <boost/test/unit_test.hpp>

#include <boost/mpl/vector.hpp>

#include <boost/numeric/odeint.hpp>

using namespace boost::unit_test;
using namespace boost::numeric::odeint;
namespace mpl = boost::mpl;

typedef double value_type;

typedef boost::array< double , 1 > state_type;

// harmonic oscillator, analytic solution x[0] = sin( t )
struct osc
{
    void operator()( const state_type &x, const state_type &v, state_type &a,
                     const double t ) const
    {
        a[0] = -x[0];
    }
};

BOOST_AUTO_TEST_SUITE( velocity_verlet_test )

BOOST_AUTO_TEST_CASE( numeric_velocity_verlet_test )
{

    velocity_verlet<state_type> stepper;
    const int steps = 10;
    // order of the error is order of approximation + 1
    const int o = stepper.order() + 1;

    const state_type x0 = {{ 0.0 }};
    const state_type v0 = {{ 1.0 }};
    state_type x = x0;
    state_type v = v0;
    const double t = 0.0;
    /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */
    double dt = 0.5;
    for ( int step = 0; step < steps; ++step )
    {
        stepper.do_step(
            osc(), std::make_pair( boost::ref( x ), boost::ref( v ) ), t, dt );
    }
    const double f = steps * std::abs( sin( steps * dt ) - x[0] ) /
                     std::pow( dt, o ); // upper bound

    std::cout << o << " , " << f << std::endl;

    /* as long as we have errors above machine precision */
    while( f*std::pow( dt , o ) > 1E-16 )
    {
        x = x0;
        v = v0;
        stepper.reset();
        for ( int step = 0; step < steps; ++step )
        {
            stepper.do_step( osc() , std::make_pair(boost::ref(x), boost::ref(v)) , t , dt );
        }
        std::cout << "Testing dt=" << dt << std::endl;
        BOOST_CHECK_LT( std::abs( sin( steps * dt ) - x[0] ),
                        f * std::pow( dt, o ) );
        dt *= 0.5;
    }
};

BOOST_AUTO_TEST_SUITE_END()


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

#include "drcWidget.h"

#include <QApplication>
#include <QDebug>
#include <QFileDialog>
#include <QHeaderView>
#include <QVBoxLayout>
#include <boost/property_tree/json_parser.hpp>
#include <array>
#include <fstream>
#include <iomanip>
#include <map>
#include <regex>
#include <sstream>

#include "utl/Logger.h"

Q_DECLARE_METATYPE(gui::DRCViolation*);

namespace gui {

///////

DRCViolation::DRCViolation(const std::string& name,
                           const std::string& type,
                           const std::vector<std::any>& srcs,
                           const std::vector<DRCShape>& shapes,
                           odb::dbTechLayer* layer,
                           const std::string& comment,
                           int file_line)
    : name_(name),
      type_(type),
      srcs_(srcs),
      shapes_(shapes),
      layer_(layer),
      comment_(comment),
      file_line_(file_line),
      viewed_(false)
{
  computeBBox();
}

DRCViolation::DRCViolation(const std::string& name,
                           const std::string& type,
                           const std::vector<DRCShape>& shapes,
                           const std::string& comment,
                           int file_line)
    : DRCViolation(name, type, {}, shapes, nullptr, comment, file_line)
{
}

void DRCViolation::computeBBox()
{
  QPolygon outline;
  for (const auto& shape : shapes_) {
    if (auto s = std::get_if<DRCLine>(&shape)) {
      outline << QPoint((*s).first.x(), (*s).first.y());
      outline << QPoint((*s).second.x(), (*s).second.y());
    } else if (auto s = std::get_if<DRCRect>(&shape)) {
      outline = outline.united(
          QRect((*s).xMin(), (*s).yMin(), (*s).dx(), (*s).dy()));
    } else if (auto s = std::get_if<DRCPoly>(&shape)) {
      for (const auto& pt : *s) {
        outline << QPoint(pt.x(), pt.y());
      }
    }
  }

  QRect bounds = outline.boundingRect();
  bbox_
      = odb::Rect(bounds.left(), bounds.bottom(), bounds.right(), bounds.top());
}

void DRCViolation::paint(Painter& painter)
{
  for (const auto& shape : shapes_) {
    if (auto s = std::get_if<DRCLine>(&shape)) {
      const odb::Point& p1 = (*s).first;
      const odb::Point& p2 = (*s).second;
      painter.drawLine(p1.x(), p1.y(), p2.x(), p2.y());
    } else if (auto s = std::get_if<DRCRect>(&shape)) {
      painter.drawRect(*s);
    } else if (auto s = std::get_if<DRCPoly>(&shape)) {
      painter.drawPolygon(*s);
    }
  }
}

///////

DRCDescriptor::DRCDescriptor(const std::vector<std::unique_ptr<DRCViolation>>& violations) :
    violations_(violations)
{
}

std::string DRCDescriptor::getName(std::any object) const
{
  auto vio = std::any_cast<DRCViolation*>(object);
  return vio->getType();
}

std::string DRCDescriptor::getTypeName() const
{
  return "DRC";
}

bool DRCDescriptor::getBBox(std::any object, odb::Rect& bbox) const
{
  auto vio = std::any_cast<DRCViolation*>(object);
  bbox = vio->getBBox();
  return true;
}

void DRCDescriptor::highlight(std::any object,
                              Painter& painter,
                              void* additional_data) const
{
  auto vio = std::any_cast<DRCViolation*>(object);
  vio->paint(painter);
}

Descriptor::Properties DRCDescriptor::getProperties(std::any object) const
{
  auto vio = std::any_cast<DRCViolation*>(object);
  Properties props;

  auto gui = Gui::get();

  auto layer = vio->getLayer();
  if (layer != nullptr) {
    props.push_back({"Layer", gui->makeSelected(layer)});
  }

  auto srcs = vio->getSources();
  if (!srcs.empty()) {
    SelectionSet sources;
    for (auto src : srcs) {
      auto select = gui->makeSelected(src);
      if (select) {
        sources.insert(select);
      }
    }
    props.push_back({"Sources", sources});
  }

  auto& comment = vio->getComment();
  if (!comment.empty()) {
    props.push_back({"Comment", vio->getComment()});
  }

  int line_number = vio->getFileLine();
  if (line_number != 0) {
    props.push_back({"Line number:", line_number});
  }

  return props;
}

Selected DRCDescriptor::makeSelected(std::any object,
                                     void* additional_data) const
{
  if (auto vio = std::any_cast<DRCViolation*>(&object)) {
    return Selected(*vio, this, additional_data);
  }
  return Selected();
}

bool DRCDescriptor::lessThan(std::any l, std::any r) const
{
  auto l_drc = std::any_cast<DRCViolation*>(l);
  auto r_drc = std::any_cast<DRCViolation*>(r);
  return l_drc < r_drc;
}

bool DRCDescriptor::getAllObjects(SelectionSet& objects) const
{
  for (auto& violation : violations_) {
    objects.insert(makeSelected(violation.get(), nullptr));
  }
  return true;
}

///////

QVariant DRCItemModel::data(const QModelIndex& index, int role) const
{
  if (role == Qt::FontRole) {
    auto item_data = itemFromIndex(index)->data();
    if (item_data.isValid()) {
      DRCViolation* item = item_data.value<DRCViolation*>();
      QFont font = QApplication::font();
      font.setBold(!item->isViewed());
      return font;
    }
  }

  return QStandardItemModel::data(index, role);
}

///////

DRCWidget::DRCWidget(QWidget* parent)
    : QDockWidget("DRC Viewer", parent),
      logger_(nullptr),
      view_(new QTreeView(this)),
      model_(new DRCItemModel(this)),
      block_(nullptr),
      load_(new QPushButton("Load...", this)),
      renderer_(std::make_unique<DRCRenderer>(violations_))
{
  setObjectName("drc_viewer");  // for settings

  model_->setHorizontalHeaderLabels({"Type", "Violation"});
  view_->setModel(model_);

  QHeaderView* header = view_->header();
  header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
  header->setSectionResizeMode(1, QHeaderView::Stretch);

  QWidget* container = new QWidget(this);
  QVBoxLayout* layout = new QVBoxLayout;
  layout->addWidget(view_);
  layout->addWidget(load_);

  container->setLayout(layout);
  setWidget(container);

  connect(view_,
          SIGNAL(clicked(const QModelIndex&)),
          this,
          SLOT(clicked(const QModelIndex&)));
  connect(view_->selectionModel(),
          SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
          this,
          SLOT(selectionChanged(const QItemSelection&, const QItemSelection&)));
  connect(load_, SIGNAL(released()), this, SLOT(selectReport()));

  Gui::get()->registerDescriptor<DRCViolation*>(new DRCDescriptor(violations_));
}

void DRCWidget::setLogger(utl::Logger* logger)
{
  logger_ = logger;
}

void DRCWidget::selectReport()
{
  // OpenLane uses .drc and OpenROAD-flow-scripts uses .rpt
  QString filename = QFileDialog::getOpenFileName(
      this,
      tr("DRC Report"),
      QString(),
      tr("DRC Report (*.rpt *.drc *.json);;TritonRoute Report (*.rpt *.drc);;JSON (*.json);;All (*)"));
  if (!filename.isEmpty()) {
    loadReport(filename);
  }
}

void DRCWidget::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
{
  auto indexes = selected.indexes();
  if (indexes.isEmpty()) {
    return;
  }

  emit clicked(indexes.first());
}

void DRCWidget::clicked(const QModelIndex& index)
{
  QStandardItem* item = model_->itemFromIndex(index);
  QVariant data = item->data();
  if (data.isValid()) {
    auto violation = data.value<DRCViolation*>();
    if (qGuiApp->keyboardModifiers() & Qt::ControlModifier) {
      violation->clearViewed();
    } else {
      Selected t = Gui::get()->makeSelected(violation);
      emit selectDRC(t);
    }
  }
}

void DRCWidget::setBlock(odb::dbBlock* block)
{
  block_ = block;
}

void DRCWidget::showEvent(QShowEvent* event)
{
  toggleRenderer(true);
}

void DRCWidget::hideEvent(QHideEvent* event)
{
  toggleRenderer(false);
}

void DRCWidget::toggleRenderer(bool visible)
{
  if (!Gui::enabled()) {
    return;
  }

  auto gui = Gui::get();
  if (visible) {
    gui->registerRenderer(renderer_.get());
  } else {
    gui->unregisterRenderer(renderer_.get());
  }
}

void DRCWidget::updateModel()
{
  auto makeItem = [](const QString& text) {
    QStandardItem* item = new QStandardItem(text);
    item->setEditable(false);
    item->setSelectable(false);
    return item;
  };

  model_->removeRows(0, model_->rowCount());

  std::map<std::string, std::vector<DRCViolation*>> violation_by_type;
  for (const auto& violation : violations_) {
    violation_by_type[violation->getType()].push_back(violation.get());
  }

  for (const auto& [type, violation_list] : violation_by_type) {
    QStandardItem* type_group = makeItem(QString::fromStdString(type));

    int violation_idx = 1;
    for (const auto& violation : violation_list) {
      QStandardItem* violation_item
          = makeItem(QString::fromStdString(violation->getName()));
      violation_item->setSelectable(true);
      violation_item->setData(QVariant::fromValue(violation));
      QStandardItem* violation_index
          = makeItem(QString::number(violation_idx++));
      violation_index->setData(QVariant::fromValue(violation));

      type_group->appendRow({violation_index, violation_item});
    }

    model_->appendRow(
        {type_group,
         makeItem(QString::number(violation_list.size()) + " violations")});
  }

  toggleRenderer(!this->isHidden());
  renderer_->redraw();
}

void DRCWidget::updateSelection(const Selected& selection)
{
  const std::any& object = selection.getObject();
  if (auto s = std::any_cast<DRCViolation*>(&object)) {
    (*s)->setViewed();
    emit update();
  }
}

void DRCWidget::loadReport(const QString& filename)
{
  Gui::get()->removeSelected<DRCViolation*>();

  violations_.clear();

  try {
    // OpenLane uses .drc and OpenROAD-flow-scripts uses .rpt
    if (filename.endsWith(".rpt") || filename.endsWith(".drc")) {
      loadTRReport(filename);
    } else if (filename.endsWith(".json")) {
      loadJSONReport(filename);
    } else {
      logger_->error(utl::GUI,
                     32,
                     "Unable to determine type of {}",
                     filename.toStdString());
    }
  } catch (std::runtime_error&) {
  }  // catch errors

  updateModel();
  raise();
}

void DRCWidget::loadTRReport(const QString& filename)
{
  std::ifstream report(filename.toStdString());
  if (!report.is_open()) {
    logger_->error(utl::GUI,
                   30,
                   "Unable to open TritonRoute DRC report: {}",
                   filename.toStdString());
  }

  std::regex violation_type("\\s*violation type: (.*)");
  std::regex srcs("\\s*srcs: (.*)");
  std::regex bbox_layer("\\s*bbox = (.*) on Layer (.*)");
  std::regex bbox_corners(
      "\\s*\\(\\s*(.*),\\s*(.*)\\s*\\)\\s*-\\s*\\(\\s*(.*),\\s*(.*)\\s*\\)");

  int line_number = 0;
  auto tech = block_->getDataBase()->getTech();
  while (!report.eof()) {
    std::string line;
    std::smatch base_match;

    // type of violation
    line_number++;
    std::getline(report, line);
    if (line.empty()) {
      continue;
    }

    int violation_line_number = line_number;
    std::string type;
    if (std::regex_match(line, base_match, violation_type)) {
      type = base_match[1].str();
    } else {
      logger_->error(
          utl::GUI, 45, "Unable to parse line as violation type (line: {}): {}", line_number, line);
    }

    // sources of violation
    line_number++;
    int source_line_number = line_number;
    std::getline(report, line);
    std::string sources;
    if (std::regex_match(line, base_match, srcs)) {
      sources = base_match[1].str();
    } else {
      logger_->error(
          utl::GUI, 46, "Unable to parse line as violation source (line: {}): {}", line_number, line);
    }

    line_number++;
    std::getline(report, line);
    // bounding box and layer
    if (!std::regex_match(line, base_match, bbox_layer)) {
      logger_->error(
          utl::GUI, 47, "Unable to parse line as violation location (line: {}): {}", line_number, line);
    }

    std::string bbox = base_match[1].str();
    odb::dbTechLayer* layer = tech->findLayer(base_match[2].str().c_str());
    if (layer == nullptr) {
      logger_->warn(
          utl::GUI, 40, "Unable to find tech layer (line: {}): {}", line_number, base_match[2].str());
    }

    odb::Rect rect;
    if (std::regex_match(bbox, base_match, bbox_corners)) {
      try {
        rect.set_xlo(std::stod(base_match[1].str())
                     * block_->getDbUnitsPerMicron());
        rect.set_ylo(std::stod(base_match[2].str())
                     * block_->getDbUnitsPerMicron());
        rect.set_xhi(std::stod(base_match[3].str())
                     * block_->getDbUnitsPerMicron());
        rect.set_yhi(std::stod(base_match[4].str())
                     * block_->getDbUnitsPerMicron());
      } catch (std::invalid_argument&) {
        logger_->error(utl::GUI, 48, "Unable to parse bounding box (line: {}): {}", line_number, bbox);
      } catch (std::out_of_range&) {
        logger_->error(utl::GUI, 49, "Unable to parse bounding box (line: {}): {}", line_number, bbox);
      }
    } else {
      logger_->error(utl::GUI, 50, "Unable to parse bounding box (line: {}): {}", line_number, bbox);
    }

    std::vector<std::any> srcs_list;
    std::stringstream srcs_stream(sources);
    std::string single_source;
    std::string comment = "";

    // split sources list
    while (getline(srcs_stream, single_source, ' ')) {
      if (single_source.empty()) {
        continue;
      }

      auto ident = single_source.find(":");
      std::string item_type = single_source.substr(0, ident);
      std::string item_name = single_source.substr(ident + 1);

      std::any item;

      if (item_type == "net") {
        odb::dbNet* net = block_->findNet(item_name.c_str());
        if (net != nullptr) {
          item = net;
        } else {
          logger_->warn(utl::GUI, 44, "Unable to find net (line: {}): {}", source_line_number, item_name);
        }
      } else if (item_type == "inst") {
        odb::dbInst* inst = block_->findInst(item_name.c_str());
        if (inst != nullptr) {
          item = inst;
        } else {
          logger_->warn(utl::GUI, 43, "Unable to find instance (line: {}): {}", source_line_number, item_name);
        }
      } else if (item_type == "iterm") {
        odb::dbITerm* iterm = block_->findITerm(item_name.c_str());
        if (iterm != nullptr) {
          item = iterm;
        } else {
          logger_->warn(utl::GUI, 42, "Unable to find iterm (line: {}): {}", source_line_number, item_name);
        }
      } else if (item_type == "bterm") {
        odb::dbBTerm* bterm = block_->findBTerm(item_name.c_str());
        if (bterm != nullptr) {
          item = bterm;
        } else {
          logger_->warn(utl::GUI, 41, "Unable to find bterm (line: {}): {}", source_line_number, item_name);
        }
      } else if (item_type == "obstruction") {
        bool found = false;
        if (layer != nullptr) {
          for (const auto& obs : block_->getObstructions()) {
            auto obs_bbox = obs->getBBox();
            if (obs_bbox->getTechLayer() == layer) {
              odb::Rect obs_rect;
              obs_bbox->getBox(obs_rect);
              if (obs_rect.intersects(rect)) {
                srcs_list.push_back(obs);
                found = true;
              }
            }
          }
        }
        if (!found) {
          logger_->warn(utl::GUI, 52, "Unable to find obstruction (line: {})", source_line_number);
        }
      } else {
        logger_->warn(utl::GUI, 51, "Unknown source type (line: {}): {}", source_line_number, item_type);
      }

      if (item.has_value()) {
        srcs_list.push_back(item);
      } else {
        if (!item_name.empty()) {
          comment += single_source + " ";
        }
      }
    }

    std::string name = "Layer: ";
    if (layer != nullptr) {
      name += layer->getName();
    } else {
      name += "<unknown>";
    }
    name += ", Sources: " + sources;

    std::vector<DRCViolation::DRCShape> shapes({rect});
    violations_.push_back(std::make_unique<DRCViolation>(
        name, type, srcs_list, shapes, layer, comment, violation_line_number));
  }

  report.close();
}

void DRCWidget::loadJSONReport(const QString& filename)
{
  boost::property_tree::ptree tree;
  try {
    boost::property_tree::json_parser::read_json(filename.toStdString(), tree);
  }
  catch (const boost::property_tree::json_parser_error& e1) {
    logger_->error(utl::GUI, 55, "Unable to parse JSON file {}: {}", filename.toStdString(), e1.what());
  }

  for (const auto& rule : tree.get_child("DRC")) {
    auto& drc_rule = rule.second;

    const std::string violation_type = drc_rule.get<std::string>("name");
    const std::string violation_text = drc_rule.get<std::string>("description");

    int  i = 0;
    for (const auto& violation_shape : drc_rule.get_child("violations")) {
      auto& shape = violation_shape.second;

      std::vector<odb::Point> shape_points;
      for (const auto& shape_pt : shape.get_child("shape")) {
        auto& pt = shape_pt.second;
        shape_points.push_back(odb::Point(
            pt.get<double>("x") * block_->getDbUnitsPerMicron(),
            pt.get<double>("y") * block_->getDbUnitsPerMicron()));
      }

      std::vector<DRCViolation::DRCShape> shapes;
      const std::string shape_type = shape.get<std::string>("type");
      if (shape_type == "box") {
        shapes.push_back(DRCViolation::DRCRect(shape_points[0], shape_points[1]));
      } else if (shape_type == "edge") {
        shapes.push_back(DRCViolation::DRCLine(shape_points[0], shape_points[1]));
      } else if (shape_type == "polygon") {
        shapes.push_back(DRCViolation::DRCPoly(shape_points));
      } else {
        logger_->error(utl::GUI, 56, "Unable to parse violation shape: {}", shape_type);
      }

      std::string name = violation_type + " - " + std::to_string(++i);
      violations_.push_back(std::make_unique<DRCViolation>(
          name,
          violation_type,
          shapes,
          violation_text,
          0));
    }
  }
}

////////

DRCRenderer::DRCRenderer(const std::vector<std::unique_ptr<DRCViolation>>& violations) :
    violations_(violations)
{
}

void DRCRenderer::drawObjects(Painter& painter)
{
  int min_box = 20.0 / painter.getPixelsPerDBU();
  Painter::Color pen_color = Painter::white;
  Painter::Color brush_color = pen_color;
  brush_color.a = 50;

  painter.setPen(pen_color, true, 0);
  painter.setBrush(brush_color, Painter::Brush::DIAGONAL);
  for (const auto& violation : violations_) {
    const odb::Rect& box = violation->getBBox();
    if (std::max(box.dx(), box.dy()) < min_box) {
      // box is too small to be useful, so draw X instead
      odb::Point center(box.xMin() + box.dx() / 2, box.yMin() + box.dy() / 2);
      painter.drawLine({center.x() - min_box / 2, center.y() - min_box / 2},
                       {center.x() + min_box / 2, center.y() + min_box / 2});
      painter.drawLine({center.x() - min_box / 2, center.y() + min_box / 2},
                       {center.x() + min_box / 2, center.y() - min_box / 2});
    } else {
      violation->paint(painter);
    }
  }
}

SelectionSet DRCRenderer::select(odb::dbTechLayer* layer, const odb::Rect& region)
{
  if (layer != nullptr) {
    return SelectionSet();
  }

  auto gui = Gui::get();

  SelectionSet selections;
  for (const auto& violation : violations_) {
    if (violation->getBBox().intersects(region)) {
      selections.insert(gui->makeSelected(violation.get()));
    }
  }
  return selections;
}

}  // namespace gui

max_stars_repo_name: erictaur/OpenROAD

max_issues_repo_name: erictaur/OpenROAD

max_forks_repo_name: erictaur/OpenROAD


text:
#include <gtest/gtest.h>
#include <boost/lexical_cast.hpp>
#include <stan/callbacks/writer.hpp>

class StanInterfaceCallbacksWriter : public ::testing::Test {
 public:
  void SetUp() {}
  void TearDown() {}
  stan::callbacks::writer writer;
};

TEST_F(StanInterfaceCallbacksWriter, double_vector) {
  const int N = 5;
  std::vector<double> x;
  for (int n = 0; n < N; ++n)
    x.push_back(n);

  EXPECT_NO_THROW(writer(x));
}

TEST_F(StanInterfaceCallbacksWriter, string_vector) {
  const int N = 5;
  std::vector<std::string> x;
  for (int n = 0; n < N; ++n)
    x.push_back(boost::lexical_cast<std::string>(n));

  EXPECT_NO_THROW(writer(x));
}

TEST_F(StanInterfaceCallbacksWriter, null) { EXPECT_NO_THROW(writer()); }

TEST_F(StanInterfaceCallbacksWriter, string) {
  EXPECT_NO_THROW(writer("message"));
}

max_stars_repo_name: sthagen/stan-dev-stan

max_issues_repo_name: sthagen/stan-dev-stan

max_forks_repo_name: sthagen/stan-dev-stan


text:
/* --------------------------------------------------------------------------
*
* (C) Copyright …
*
* ---------------------------------------------------------------------------
*/

/*!
 * @file SelectionTester.hpp
 * @date 11/05/2018
 * @author Alessandro Bianco
 */

/*!
 * @addtogroup GuiTests
 *
 * This class will test requirement 4.1.1.8 of deliverable 5.5.
 * "90% of manually defined matches on manually defined features should be detected correctly.  Manually defined matches are considered to be matches between features made by a human
 * on close inspection of a set of features on a pair of images.  A human will inspect each set of matches and identify those that are incorrect."
 *
 * @{
 */

#ifndef SELECTION_TESTER_HPP
#define SELECTION_TESTER_HPP

/* --------------------------------------------------------------------------
 *
 * Includes
 *
 * --------------------------------------------------------------------------
 */
#include <FeaturesDescription3D/FeaturesDescription3DInterface.hpp>
#include <FeaturesMatching3D/FeaturesMatching3DInterface.hpp>
#include <Errors/Assert.hpp>

#include <Types/CPP/VisualPointFeatureVector3D.hpp>
#include <Types/CPP/PointCloud.hpp>
#include <Types/CPP/Pose.hpp>
#include <Types/CPP/BaseTypes.hpp>
#include <Types/CPP/CorrespondenceMap3D.hpp>
#include <Converters/PclPointCloudToPointCloudConverter.hpp>
#include <Converters/SupportTypes.hpp>

#include <stdlib.h>
#include <fstream>
#include <string>
#include <vector>
#include <boost/make_shared.hpp>

/* --------------------------------------------------------------------------
 *
 * Class definition
 *
 * --------------------------------------------------------------------------
 */
class SelectionTester
	{
	/* --------------------------------------------------------------------
	 * Public
	 * --------------------------------------------------------------------
	 */
	public:
		SelectionTester();
		~SelectionTester();

		void SetDfns(CDFF::DFN::FeaturesDescription3DInterface* descriptor, CDFF::DFN::FeaturesMatching3DInterface* matcher);
		void SetConfigurationFilePaths(const std::string& featuresDescriptorConfigurationFilePath, const std::string& featuresMatcherConfigurationFilePath);
		void SetInputFilesPaths(const std::string& sourceCloudFilePath, const std::string& sinkCloudFilePath, const std::string& correspondencesFilePath);
		void ExecuteDfns();
		bool AreCorrespondencesValid(float percentageThreshold);

	/* --------------------------------------------------------------------
	 * Protected
	 * --------------------------------------------------------------------
	 */
	protected:

	/* --------------------------------------------------------------------
	 * Private
	 * --------------------------------------------------------------------
	 */
	private:
		typedef Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign> AffineTransform;

		std::string featuresDescriptorConfigurationFilePath;
		std::string featuresMatcherConfigurationFilePath;
		std::string sourceCloudFilePath;
		std::string sinkCloudFilePath;
		std::string correspondencesFilePath;

		PointCloudWrapper::PointCloudConstPtr inputSourceCloud, inputSinkCloud;
		VisualPointFeatureVector3DWrapper::VisualPointFeatureVector3DConstPtr inputSourceKeypointsVector, inputSinkKeypointsVector;
		VisualPointFeatureVector3DWrapper::VisualPointFeatureVector3DConstPtr sourceFeaturesVector, sinkFeaturesVector;
		CorrespondenceMap3DWrapper::CorrespondenceMap3DConstPtr outputCorrespondenceMap;
		CorrespondenceMap3DWrapper::CorrespondenceMap3DConstPtr referenceCorrespondenceMap;
		PoseWrapper::Pose3DConstPtr sourcePoseInSink;
		bool matcherSuccess;

		Converters::PclPointCloudToPointCloudConverter pointCloudConverter;
		CDFF::DFN::FeaturesDescription3DInterface* descriptor;
		CDFF::DFN::FeaturesMatching3DInterface* matcher;

		bool dfnsWereLoaded;
		bool inputCloudsWereLoaded;
		bool inputKeypointsWereLoaded;
		bool precisionReferenceWasLoaded;

		void LoadInputCloud(const std::string& cloudFilePath, PointCloudWrapper::PointCloudConstPtr& cloud);
		void LoadReferenceCorrespondenceMap();
		void ConfigureDfns();

		bool ValidateCorrespondences(float percentageThreshold);
		bool CorrespondencesAreTheSame(int referenceIndex, int outputIndex);

		void ComputeMatchesFromPose();
		BaseTypesWrapper::Point3D TransformPoint(const BaseTypesWrapper::Point3D& point, const AffineTransform& affineTransform);
		BaseTypesWrapper::Point3D FindClosestSinkPointTo(const BaseTypesWrapper::Point3D& sourcePoint, float& closestDistance);
	};

#endif

/* SelectionTester.hpp */
/** @} */


text:
// Copyright (c) 2012-2018 LG Electronics, 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.
//
// SPDX-License-Identifier: Apache-2.0

#include "core/base/call_chain.h"

#include <algorithm>

#include <boost/bind.hpp>

#include "core/base/jutil.h"
#include "core/base/lsutils.h"

CallItem::CallItem()
    : m_chainData(pbnjson::Object())
{
}

void CallItem::setError(int errorCode, std::string errorText)
{
    m_errInfo.setError(errorCode, errorText);
}

ErrorInfo CallItem::getError() const
{
    return m_errInfo;
}

void CallItem::setChainData(pbnjson::JValue chainData)
{
    m_chainData = chainData.duplicate();
}

pbnjson::JValue CallItem::getChainData() const
{
    return m_chainData.duplicate();
}

void CallItem::setStatus(const std::string& status)
{
    m_status = status;
}

const std::string& CallItem::getStatus() const
{
    return m_status;
}

void CallItem::setMsg(const std::string& msg)
{
    m_msg = msg;
}

const std::string& CallItem::getMsg() const
{
    return m_msg;
}

LSCallItem::LSCallItem(LSHandle *handle, const char *uri, const char *payload)
    : m_handle(handle)
    , m_uri(uri)
    , m_payload(payload)
{
}

bool LSCallItem::Call()
{
    LSErrorSafe lserror;
    ErrorInfo errInfo;

    if (!onBeforeCall())
    {
        errInfo.setError(CALLCHANIN_ERR_GENERAL, "Cancelled");
        onError(errInfo);
        return false;
    }

    if (!LSCallOneReply(m_handle, m_uri.c_str(), m_payload.c_str(),
        LSCallItem::handler, this, NULL, &lserror))
    {
        errInfo.setError(CALLCHANIN_ERR_GENERAL, lserror.message);
        onError(errInfo);
        return false;
    }

    return true;
}

bool LSCallItem::onBeforeCall()
{
    return true;
}

bool LSCallItem::onReceiveCall(pbnjson::JValue message)
{
    return true;
}

void LSCallItem::setPayload(const char *payload)
{
    m_payload = payload;
}

bool LSCallItem::handler(LSHandle *lshandle, LSMessage *message, void *user_data)
{
    LSCallItem *call = reinterpret_cast<LSCallItem*>(user_data);
    if (!call)
        return false;

    pbnjson::JValue json = JUtil::parse(LSMessageGetPayload(message), std::string(""));

    bool result = call->onReceiveCall(json);

    call->onFinished(result, call->getError());

    return result;
}

gboolean CallChain::cbAsyncDelete(gpointer data)
{
    CallChain *p = reinterpret_cast<CallChain*>(data);
    if (!p) return false;

    delete p;
    return false;
}

CallChain& CallChain::acquire(CallCompleteHandler handler, CallNotifier notifier, void *user_data)
{
    CallChain *chain = new CallChain(handler, notifier, user_data);
    return *chain;
}

CallChain::CallChain(CallCompleteHandler handler, CallNotifier notifier, void *user_data)
    : m_handler(handler)
    , m_notifier(notifier)
    , m_user_data(user_data)
{
}

CallChain::~CallChain()
{
}

CallChain& CallChain::add(CallItemPtr call, bool push_front)
{
    call->onFinished.connect(boost::bind(&CallChain::onCallFinished, this, _1, _2));
    call->onError.connect(boost::bind(&CallChain::onCallError, this, _1));

    if (push_front) m_calls.push_front(call);
    else m_calls.push_back(call);
    return *this;
}

CallChain& CallChain::add_if(CallItemPtr condition_call, bool expected_result, CallItemPtr target_call)
{
    m_conditions.push_back(std::make_shared<CallCondition>(condition_call, expected_result, target_call));
    return *this;
}

bool CallChain::run(pbnjson::JValue chainData)
{
    return proceed(chainData);
}

bool CallChain::proceed(pbnjson::JValue chainData)
{
    if (m_calls.empty())
    {
        ErrorInfo errInfo;
        chainData.put("returnValue", true);
        finish(chainData, errInfo);
        return true;
    }

    CallItemPtr call = m_calls.front();

    call->setChainData(chainData);
    if (!call->Call())
    {
        return false;
    }

    return true;
}

void CallChain::finish(pbnjson::JValue chainData, ErrorInfo errInfo)
{
    if (m_handler)
        m_handler(chainData, errInfo, m_user_data);

    g_timeout_add(0, cbAsyncDelete, (gpointer)this);
}

void CallChain::onCallError(ErrorInfo errInfo)
{
    CallItemPtr call = m_calls.front();
    if(!call)
    {
        pbnjson::JValue result = pbnjson::Object();
        result.put("returnValue", false);
        finish(result, errInfo);
    }
    else
    {
        pbnjson::JValue chainData = call->getChainData();
        chainData.put("returnValue", false);
        finish(chainData, errInfo);
    }
}

void CallChain::onCallFinished(bool result, ErrorInfo errInfo)
{
    CallItemPtr call = m_calls.front();
    if (!call)
    {
        pbnjson::JValue chainData = pbnjson::Object();
        chainData.put("returnValue", false);

        ErrorInfo errCallInfo;
        errCallInfo.setError(CALLCHANIN_ERR_GENERAL, "Callchain broken");
        finish(chainData, errCallInfo);
        return;
    }
    m_calls.pop_front();

    if (m_notifier && !((call->getStatus()).empty()))
        m_notifier(call->getStatus(), call->getMsg(), result, m_user_data);

    if(!errInfo.errorText.empty())
    {
        //if errorText is not empty, do not process next callChain.
        pbnjson::JValue chainData = call->getChainData();
        chainData.put("returnValue", false);
        finish(chainData, errInfo);
        return;
    }

    bool processNext = result;

    std::vector<CallConditionPtr>::iterator it = std::find_if(m_conditions.begin(), m_conditions.end(),
        [=] (const CallConditionPtr p) -> bool { return p->condition_call == call; }
        );
    if (it != m_conditions.end())
    {
        if (result == (*it)->expected_result)
        {
            add((*it)->target_call, true);
            processNext = true;
        }

        m_conditions.erase(it);
    }

    if (processNext)
    {
        proceed(call->getChainData());
    }
    else
    {
        pbnjson::JValue chainData = call->getChainData();
        chainData.put("returnValue", false);
        finish(chainData, errInfo);
    }
}

max_stars_repo_name: webosce/sam

max_issues_repo_name: webosce/sam

max_forks_repo_name: webosce/sam


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T. Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_IDIVFIX_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_IDIVFIX_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!

    @ingroup group-arithmetic
    Function object implementing idivfix capabilities

    Computes the integer conversion of the truncated division of its parameters.

    @par semantic:
    For any given value @c x,  @c y of type @c T:

    @code
    T r = idivfix(x, y);
    @endcode

    The code is similar to:

    @code
    as_integer_t<T> r = toints(trunc(x/y));
    @endcode

    If y is @ref Zero, it returns @ref Valmax (resp. @ref Valmin)
    if x is positive (resp. negative) and 0 if x is @ref Zero.

    @see toints, trunc
  **/
  const boost::dispatch::functor<tag::idivfix_> idivfix = {};
} }
#endif

#include <boost/simd/function/scalar/idivfix.hpp>
#include <boost/simd/function/simd/idivfix.hpp>

#endif


text:
/*=============================================================================

  NifTK: A software platform for medical image computing.

  Copyright (c) University College London (UCL). All rights reserved.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.

  See LICENSE.txt in the top level directory for details.

=============================================================================*/

#include <niftkMeshGenerator.h>
#include <niftkMeshMerger.h>
#include <niftkCommandLineParser.h>

#include <vtkSmartPointer.h>
#include <vtkUnstructuredGridWriter.h>
#include <vtkErrorCode.h>

#include <boost/tokenizer.hpp>

#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <iterator>

static niftk::CommandLineArgumentDescription g_opts[] = {
    { OPT_SWITCH, "surf", 0, "Generate only a surface mesh" },
    { OPT_SWITCH, "separate", 0, "Generate one mesh from every label separately. If this flag is set, the output path (specified with the \"output\" flag) is treated as a prefix and the resulting meshes will receive a suffix based on the labels from which the mesh was generated." },
    { OPT_STRING, "output", "PATH TO OUTPUT FILE", "Output path (default: \"./out.vtk\" or \"./out\")" },
    { OPT_STRING, "labels", "LABEL VALUES", "Request sub-mesh with specific label value. Labels are specified as comma separated list LABEL1,LABEL2..,LABELN. If one mesh is to be generated from more than one label the corresponding labels need to be separated with semicolons (LABELP; ..; LABELQ), also the \"separate\" flag needs to be set."},
    { OPT_FLOAT, "facet-angle", "MIN. ADMISSIBLE FACET ANGLE", "Mesh quality criterion: min. admissible surface facet angle, in deg. (default: 30)." },
    { OPT_FLOAT, "facet-edge", "MAX. ADMISSIBLE FACET EDGE LEN.", "Mesh quality criterion: max. admissible surface facet edge length (default: 6)." },
    { OPT_FLOAT, "bdy-error", "MAX. ADMISSIBLE BDY APPROX. ERR", "Mesh quality criterion: max. admissible boundary approximation error (default: 4)." },
    { OPT_FLOAT, "cell-size", "MAX. ADMISSIBLE CELL SIZE", "Mesh quality criterion: max. admissible tetrahedron edge (default: 8)." },
    { OPT_FLOAT, "edge-radius", "MAX. EDGE-CIRCUMBALL-RADIUS RATIO", "Mesh quality criterion: max. admissible ratio of cell circumball radius-min. edge (default: 3)." },
    { OPT_STRING | OPT_LONELY | OPT_REQ, "LABEL VOLUME", "PATH TO INPUT LABEL VOL", "The input image." },
    { OPT_DONE, NULL, NULL, "Program to generate meshes from label volumes." }
};

enum _cmdLineArgs {
    O_SURF = 0, O_SEPARATE, O_OUTPUT, O_LABELS, O_FACETANGLE, O_FACETEDGE, O_FACETERROR, O_CELLSIZE, O_CELLRATIO, O_INPUT_VOL
};

static bool _ParseLabel(std::vector<int> &r_dstList, const std::string &labelString)
{
  std::istringstream tokISS(labelString);
  int label;

  tokISS >> label;
  if (tokISS.fail()) {
    std::cerr << "Invalid token in label argument: " << labelString << std::endl;

    return false;
  }
  r_dstList.push_back(label);

  return true;
}

static bool _ParseLabelList(std::vector<int> &r_dstList, const std::string &labelList, const boost::char_separator<char> &separator)
{
  boost::tokenizer<boost::char_separator<char> > tokeniser(labelList, separator);
  boost::tokenizer<boost::char_separator<char> >::iterator i_token;

  for (i_token = tokeniser.begin(); i_token != tokeniser.end(); ++i_token) {
    if (!_ParseLabel(r_dstList, *i_token))
      return false;
  }

  return true;
}

static bool _WriteMesh(vtkSmartPointer<vtkUnstructuredGrid> sp_grid, const std::string &path)
{
  vtkSmartPointer<vtkUnstructuredGridWriter> sp_writer;

  sp_writer = vtkSmartPointer<vtkUnstructuredGridWriter>::New();
  sp_writer->SetFileName(path.c_str());
  sp_writer->SetInputData(sp_grid);
  sp_writer->Update();

  if (sp_writer->GetErrorCode() != 0) {
    std::cerr << "Error writing file " << path << ": " << vtkErrorCode::GetStringFromErrorCode(sp_writer->GetErrorCode());

    return false;
  }

  return true;
}

static std::string _LabelListToString(const std::vector<int> &labels)
{
  std::ostringstream oss;

  oss << "_";
  std::copy(labels.begin(), labels.end() - 1, std::ostream_iterator<int>(oss, "_"));
  oss << labels.back();
  oss << ".vtk";

  return oss.str();
}

int main(int argc, char *argv[])
{
  niftk::CommandLineParser cliOpts(argc, argv, g_opts, true);
  std::string inputFileName, outputFileName;
  std::vector<std::vector<int> > meshLabels;
  niftk::MeshGenerator gen;
  niftk::MeshMerger merger;
  bool doSurf, doSeparateMeshes;
  std::string labelList;
  float facetAngle, facetEdgeLen, facetError, cellSize, cellRatio;

  labelList = "";
  cliOpts.GetArgument(O_LABELS, labelList);

  doSurf = false;
  cliOpts.GetArgument(O_SURF, doSurf);
  doSeparateMeshes = false;
  cliOpts.GetArgument(O_SEPARATE, doSeparateMeshes);

  if (doSeparateMeshes) {
    boost::tokenizer<boost::char_separator<char> > tokeniser(labelList, boost::char_separator<char>(","));
    boost::tokenizer<boost::char_separator<char> >::iterator i_token;

    for (i_token = tokeniser.begin(); i_token != tokeniser.end(); ++i_token) {
      meshLabels.push_back(std::vector<int>());
      if (i_token->find_first_of(";") != i_token->npos) {
	if (!_ParseLabelList(meshLabels.back(), *i_token, boost::char_separator<char>(";"))) {
	  cliOpts.PrintUsage();

	  return EXIT_FAILURE;
	}
      } else {
	if (!_ParseLabel(meshLabels.back(), *i_token)) {
	  cliOpts.PrintUsage();

	  return EXIT_FAILURE;
	}
      }
    }
  } else {
    meshLabels.resize(1);
    if (!_ParseLabelList(meshLabels.front(), labelList, boost::char_separator<char>(","))) {
      cliOpts.PrintUsage();

      return EXIT_FAILURE;
    }
  }

  if (doSeparateMeshes)
    outputFileName = "out";
  else
    outputFileName = "out.vtk";

  cliOpts.GetArgument(O_OUTPUT, outputFileName);

  facetAngle = 30;
  cliOpts.GetArgument(O_FACETANGLE, facetAngle);
  gen.SetFacetMinAngle(facetAngle);

  facetEdgeLen = 6;
  cliOpts.GetArgument(O_FACETEDGE, facetEdgeLen);
  gen.SetFacetMaxEdgeLength(facetEdgeLen);

  facetError = 4;
  cliOpts.GetArgument(O_FACETERROR, facetError);
  gen.SetBoundaryApproximationError(facetError);

  cellSize = 8;
  cliOpts.GetArgument(O_CELLSIZE, cellSize);
  gen.SetCellMaxSize(cellSize);

  cellRatio = 3;
  cliOpts.GetArgument(O_CELLRATIO, cellRatio);
  gen.SetCellMaxRadiusEdgeRatio(cellRatio);

  try {
    cliOpts.GetArgument(O_INPUT_VOL, inputFileName);

    gen.SetDoSurface(doSurf);
    gen.SetFileName(inputFileName);
    gen.Update();
    merger.SetInput(gen.GetOutput());

    if (doSeparateMeshes) {
      std::vector<std::vector<int> >::const_iterator ic_labels;

      merger.SetMeshLabels(gen.GetMeshLabels());
      for (ic_labels = meshLabels.begin(); ic_labels < meshLabels.end(); ic_labels++) {
	merger.SetDesiredLabels(*ic_labels);
	merger.Update();

	if (!_WriteMesh(merger.GetOutput(), outputFileName + _LabelListToString(*ic_labels))) {
	  cliOpts.PrintUsage();

	  return EXIT_FAILURE;
	}
      }
    } else {
      merger.SetMeshLabels(gen.GetMeshLabels());
      merger.SetDesiredLabels(meshLabels.front());
      merger.Update();

      if (!_WriteMesh(merger.GetOutput(), outputFileName)) {
	cliOpts.PrintUsage();

	return EXIT_FAILURE;
      }
    }
  } catch (niftk::ExceptionObject &r_ex) {
    std::cerr << r_ex.what() << std::endl;
    cliOpts.PrintUsage();

    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

ext: cxx

max_stars_repo_name: NifTK/NifTK

max_issues_repo_name: NifTK/NifTK

max_forks_repo_name: NifTK/NifTK


text:
//
// Boost.Process
// Regression tests for the pistream class.
//
// Copyright (c) 2006 Julio M. Merino Vidal.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt.)
//

#include <ostream>

#include <boost/process/detail/pipe.hpp>
#include <boost/process/detail/systembuf.hpp>
#include <boost/process/pistream.hpp>
#include <boost/test/unit_test.hpp>

namespace bp = ::boost::process;
namespace bpd = ::boost::process::detail;
namespace but = ::boost::unit_test;

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

static
void
test_it(void)
{
    bpd::pipe p;
    bp::pistream rend(p.rend());
    bpd::systembuf wbuf(p.wend().get());
    std::ostream wend(&wbuf);

    // XXX This assumes that the pipe's buffer is big enough to accept
    // the data written without blocking!
    wend << "1Test 1message" << std::endl;
    std::string tmp;
    rend >> tmp;
    BOOST_CHECK_EQUAL(tmp, "1Test");
    rend >> tmp;
    BOOST_CHECK_EQUAL(tmp, "1message");
}

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

but::test_suite *
init_unit_test_suite(int argc, char* argv[])
{
    but::test_suite* test = BOOST_TEST_SUITE("pistream test suite");

    test->add(BOOST_TEST_CASE(&test_it));

    return test;
}

max_stars_repo_name: saga-project/saga-cpp

max_issues_repo_name: saga-project/saga-cpp

max_forks_repo_name: saga-project/saga-cpp


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

#ifndef QCTOOL_CALL_COMPARER_COMPONENT_HPP
#define QCTOOL_CALL_COMPARER_COMPONENT_HPP

#include <boost/noncopyable.hpp>
#include "genfile/CohortIndividualSource.hpp"
#include "appcontext/OptionProcessor.hpp"
#include "appcontext/UIContext.hpp"
#include "PairwiseCallComparerManager.hpp"
#include "components/SNPSummaryComponent/SNPSummaryComputation.hpp"
#include "components/SNPSummaryComponent/SNPSummaryComputationManager.hpp"
#include "qcdb/Storage.hpp"

struct CallComparerProcessor: public SNPSummaryComputation
{
public:
	typedef std::auto_ptr< CallComparerProcessor > UniquePtr ;
	static UniquePtr create(
		PairwiseCallComparerManager::UniquePtr call_comparer,
		std::vector< std::string > const& call_fields
	) ;

public:
	CallComparerProcessor(
		PairwiseCallComparerManager::UniquePtr call_comparer,
		std::vector< std::string > const& call_fields
	) ;

	public:

		void operator()( VariantIdentifyingData const&, Genotypes const&, Ploidy const&, genfile::VariantDataReader&, ResultCallback ) ;
		std::string get_summary( std::string const& prefix = "", std::size_t column_width = 20 ) const ;

	private:
		PairwiseCallComparerManager::UniquePtr m_call_comparer ;
		std::vector< std::string > m_call_fields ;
		bool m_begun ;
		PairwiseCallComparerManager::MergeClient::UniquePtr m_consensus_caller ;
		Eigen::MatrixXd m_calls ;
} ;

struct CallComparerComponent: public boost::noncopyable
{
	static void declare_options( appcontext::OptionProcessor& options ) ;

	typedef std::auto_ptr< CallComparerComponent > UniquePtr ;
	static UniquePtr create(
		genfile::CohortIndividualSource const& samples,
		appcontext::OptionProcessor const& options,
		appcontext::UIContext& ui_context
	) ;

public:
	CallComparerComponent(
		genfile::CohortIndividualSource const& m_samples,
		appcontext::OptionProcessor const& options,
		appcontext::UIContext& ui_context
	) ;

	void setup( SNPSummaryComputationManager&, qcdb::Storage::SharedPtr ) const ;

private:
	genfile::CohortIndividualSource const& m_samples ;
	appcontext::OptionProcessor const& m_options ;
} ;

#endif

max_stars_repo_name: CreRecombinase/qctool

max_issues_repo_name: CreRecombinase/qctool

max_forks_repo_name: CreRecombinase/qctool