text:
// --------------------------------------------------------------------------
//                   OpenMS -- Open-Source Mass Spectrometry
// --------------------------------------------------------------------------
// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
// ETH Zurich, and Freie Universitaet Berlin 2002-2021.
//
// This software is released under a three-clause BSD license:
//  * 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 any author or any participating institution
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
// For a full list of authors, refer to the file AUTHORS.
// --------------------------------------------------------------------------
// 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 ANY OF THE AUTHORS OR THE CONTRIBUTING
// INSTITUTIONS 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.
//
// --------------------------------------------------------------------------
// $Maintainer: Timo Sachsenberg $
// $Authors: Erhan Kenar $
// --------------------------------------------------------------------------

#include <OpenMS/ANALYSIS/ID/MetaboliteSpectralMatching.h>

#include <numeric>
#include <boost/math/special_functions/factorials.hpp>

#include <boost/dynamic_bitset.hpp>

#include <OpenMS/FILTERING/TRANSFORMERS/SpectraMerger.h>
#include <OpenMS/FILTERING/TRANSFORMERS/WindowMower.h>

using namespace std;

namespace OpenMS
{

  SpectralMatch::SpectralMatch() :
    observed_precursor_mass_(),
    observed_precursor_rt_(),
    found_precursor_mass_(),
    found_precursor_charge_(),
    matching_score_(),
    observed_spectrum_idx_(),
    matching_spectrum_idx_(),
    primary_id_(),
    secondary_id_(),
    common_name_(),
    sum_formula_(),
    inchi_string_(),
    smiles_string_(),
    precursor_adduct_()
  {
  }

  /// Default destructor
  SpectralMatch::~SpectralMatch()
  {
  }

  /// Copy constructor
  SpectralMatch::SpectralMatch(const SpectralMatch& sm) :
    observed_precursor_mass_(sm.observed_precursor_mass_),
    observed_precursor_rt_(sm.observed_precursor_rt_),
    found_precursor_mass_(sm.found_precursor_mass_),
    found_precursor_charge_(sm.found_precursor_charge_),
    matching_score_(sm.matching_score_),
    observed_spectrum_idx_(sm.observed_spectrum_idx_),
    matching_spectrum_idx_(sm.matching_spectrum_idx_),
    primary_id_(sm.primary_id_),
    secondary_id_(sm.secondary_id_),
    common_name_(sm.common_name_),
    sum_formula_(sm.sum_formula_),
    inchi_string_(sm.inchi_string_),
    smiles_string_(sm.smiles_string_),
    precursor_adduct_(sm.precursor_adduct_)
  {
  }

  /// Assignment operator
  SpectralMatch& SpectralMatch::operator=(const SpectralMatch& rhs)
  {
    if (this == &rhs) return *this;

    observed_precursor_mass_ = rhs.observed_precursor_mass_;
    observed_precursor_rt_ = rhs.observed_precursor_rt_;
    found_precursor_mass_ = rhs.found_precursor_mass_;
    found_precursor_charge_ = rhs.found_precursor_charge_;
    matching_score_ = rhs.matching_score_;
    observed_spectrum_idx_ = rhs.observed_spectrum_idx_;
    matching_spectrum_idx_ = rhs.matching_spectrum_idx_;
    primary_id_ = rhs.primary_id_;
    secondary_id_ = rhs.secondary_id_;
    common_name_ = rhs.common_name_;
    sum_formula_ = rhs.sum_formula_;
    inchi_string_ = rhs.inchi_string_;
    smiles_string_ = rhs.smiles_string_;
    precursor_adduct_ = rhs.precursor_adduct_;

    return *this;
  }

  double SpectralMatch::getObservedPrecursorMass() const
  {
    return observed_precursor_mass_;
  }

  void SpectralMatch::setObservedPrecursorMass(const double& qmass)
  {
    observed_precursor_mass_ = qmass;
  }

  double SpectralMatch::getObservedPrecursorRT() const
  {
    return observed_precursor_rt_;
  }

  void SpectralMatch::setObservedPrecursorRT(const double& prt)
  {
    observed_precursor_rt_ = prt;
  }

  double SpectralMatch::getFoundPrecursorMass() const
  {
    return found_precursor_mass_;
  }

  void SpectralMatch::setFoundPrecursorMass(const double& fmass)
  {
    found_precursor_mass_ = fmass;
  }

  Int SpectralMatch::getFoundPrecursorCharge() const
  {
    return found_precursor_charge_;
  }

  void SpectralMatch::setFoundPrecursorCharge(const Int& pch)
  {
    found_precursor_charge_ = pch;
  }

  double SpectralMatch::getMatchingScore() const
  {
    return matching_score_;
  }

  void SpectralMatch::setMatchingScore(const double& mscore)
  {
    matching_score_ = mscore;
  }

  Size SpectralMatch::getObservedSpectrumIndex() const
  {
    return observed_spectrum_idx_;
  }

  void SpectralMatch::setObservedSpectrumIndex(const Size& obs_spec_idx)
  {
    observed_spectrum_idx_ = obs_spec_idx;
  }

  Size SpectralMatch::getMatchingSpectrumIndex() const
  {
    return matching_spectrum_idx_;
  }

  void SpectralMatch::setMatchingSpectrumIndex(const Size& match_spec_idx)
  {
    matching_spectrum_idx_ = match_spec_idx;
  }

  String SpectralMatch::getPrimaryIdentifier() const
  {
    return primary_id_;
  }

  void SpectralMatch::setPrimaryIdentifier(const String& pid)
  {
    primary_id_ = pid;
  }

  String SpectralMatch::getSecondaryIdentifier() const
  {
    return secondary_id_;
  }

  void SpectralMatch::setSecondaryIdentifier(const String& sid)
  {
    secondary_id_ = sid;
  }

  String SpectralMatch::getCommonName() const
  {
    return common_name_;
  }

  void SpectralMatch::setCommonName(const String& cname)
  {
    common_name_ = cname;
  }

  String SpectralMatch::getSumFormula() const
  {
    return sum_formula_;
  }

  void SpectralMatch::setSumFormula(const String& sf)
  {
    sum_formula_ = sf;
  }

  String SpectralMatch::getInchiString() const
  {
    return inchi_string_;
  }

  void SpectralMatch::setInchiString(const String& istr)
  {
    inchi_string_ = istr;
  }

  String SpectralMatch::getSMILESString() const
  {
    return smiles_string_;
  }

  void SpectralMatch::setSMILESString(const String& sstr)
  {
    smiles_string_ = sstr;
  }

  String SpectralMatch::getPrecursorAdduct() const
  {
    return precursor_adduct_;
  }

  void SpectralMatch::setPrecursorAdduct(const String& padd)
  {
    precursor_adduct_ = padd;
  }

  MetaboliteSpectralMatching::MetaboliteSpectralMatching() :
    DefaultParamHandler("MetaboliteSpectralMatching"), ProgressLogger()
  {
    defaults_.setValue("prec_mass_error_value", 100.0, "Error allowed for precursor ion mass.");
    defaults_.setValue("frag_mass_error_value", 500.0, "Error allowed for product ions.");

    defaults_.setValue("mass_error_unit", "ppm", "Unit of mass error (ppm or Da)");
    defaults_.setValidStrings("mass_error_unit", {"ppm","Da"});

    defaults_.setValue("report_mode", "top3", "Which results shall be reported: the top-three scoring ones or the best scoring one?");
    defaults_.setValidStrings("report_mode", {"top3","best"});

    defaults_.setValue("ionization_mode", "positive", "Positive or negative ionization mode?");
    defaults_.setValidStrings("ionization_mode", {"positive","negative"});

    defaultsToParam_();

    this->setLogType(CMD);
  }

  MetaboliteSpectralMatching::~MetaboliteSpectralMatching()
  {
  }

  double MetaboliteSpectralMatching::computeHyperScore(
    double fragment_mass_error,
    bool fragment_mass_tolerance_unit_ppm,
    const MSSpectrum& exp_spectrum,
    const MSSpectrum& db_spectrum,
    double mz_lower_bound)
  {
    return computeHyperScore_(fragment_mass_error,
                              fragment_mass_tolerance_unit_ppm, exp_spectrum,
                              db_spectrum, 0, mz_lower_bound);
  }

  double MetaboliteSpectralMatching::computeHyperScore(
    double fragment_mass_error,
    bool fragment_mass_tolerance_unit_ppm,
    const MSSpectrum& exp_spectrum,
    const MSSpectrum& db_spectrum,
    vector<PeptideHit::PeakAnnotation>& annotations,
    double mz_lower_bound)
  {
    return computeHyperScore_(fragment_mass_error,
                              fragment_mass_tolerance_unit_ppm, exp_spectrum,
                              db_spectrum, &annotations, mz_lower_bound);
  }

  double MetaboliteSpectralMatching::computeHyperScore_(
    double fragment_mass_error,
    bool fragment_mass_tolerance_unit_ppm,
    const MSSpectrum& exp_spectrum,
    const MSSpectrum& db_spectrum,
    vector<PeptideHit::PeakAnnotation>* annotations,
    double mz_lower_bound)
  {
    if (exp_spectrum.empty()) return 0;

    // define m/z range to consider:
    double min_exp_mz = exp_spectrum[0].getMZ(); // lowest experimental m/z
    double mz_offset = fragment_mass_error;
    if (fragment_mass_tolerance_unit_ppm)
    {
      mz_offset = min_exp_mz * fragment_mass_error * 1e-6;
    }
    mz_lower_bound = max(mz_lower_bound, min_exp_mz - mz_offset);
    double max_exp_mz = exp_spectrum.back().getMZ(); // highest experimental m/z
    if (fragment_mass_tolerance_unit_ppm)
    {
      mz_offset = max_exp_mz * fragment_mass_error * 1e-6;
    }
    double mz_upper_bound = max_exp_mz + mz_offset;

    // for every DB (theoretical) peak in the valid m/z range, find the closest
    // matching experimental (observed) peak within the allowed tolerance;
    // in principle, multiple DB peaks can match to the same exp. peak:
    map<Size, vector<MSSpectrum::ConstIterator>> peak_matches;
    for (auto db_it = db_spectrum.MZBegin(mz_lower_bound);
         db_it != db_spectrum.MZEnd(mz_upper_bound); ++db_it)
    {
      double db_mz = db_it->getMZ();

      if (fragment_mass_tolerance_unit_ppm)
      {
        mz_offset = db_mz * fragment_mass_error * 1e-6;
      }

      Int index = exp_spectrum.findNearest(db_mz, mz_offset);
      if (index >= 0) peak_matches[index].push_back(db_it);
    }

    double dot_product = 0.0;
    for (const auto& match : peak_matches)
    {
      double db_intensity = 0.0;
      for (const auto& db_it : match.second)
      {
        db_intensity = max(db_intensity, double(db_it->getIntensity()));
      }
      dot_product += db_intensity * exp_spectrum[match.first].getIntensity();
    }

    // return annotations for matching peaks?
    if ((annotations != 0) &&
        !db_spectrum.getStringDataArrays().empty() &&
        !db_spectrum.getIntegerDataArrays().empty())
    {
      for (const auto& match : peak_matches)
      {
        const auto& exp_peak = exp_spectrum[match.first];
        // potentially add several annotations for the same peak if there are
        // multiple matches for that peak:
        for (const auto& db_it : match.second)
        {
          PeptideHit::PeakAnnotation ann;
          Size index = db_it - db_spectrum.begin();
          ann.annotation = db_spectrum.getStringDataArrays()[0].at(index);
          ann.charge = db_spectrum.getIntegerDataArrays()[0].at(index);
          ann.mz = exp_peak.getMZ();
          ann.intensity = exp_peak.getIntensity();
          annotations->push_back(ann);
        }
      }
    }

    Size matched_ions_count = peak_matches.size(); // count obs. peaks only once
    double matched_ions_term = 0.0;

    // return score 0 if too few matched ions
    if (matched_ions_count < 3)
    {
      return matched_ions_term;
    }

    if (matched_ions_count <= boost::math::max_factorial<double>::value)
    {
      matched_ions_term = log(boost::math::factorial<double>(matched_ions_count));
    }
    else
    {
      matched_ions_term = log(boost::math::factorial<double>(boost::math::max_factorial<double>::value));
    }

    double hyperscore = log(dot_product) + matched_ions_term;
    if (hyperscore < 0) hyperscore = 0;

    return hyperscore;
  }

  void MetaboliteSpectralMatching::run(PeakMap& msexp, PeakMap& spec_db, MzTab& mztab_out)
  {
    sort(spec_db.begin(), spec_db.end(), PrecursorMZLess);

    vector<double> mz_keys;

    // copy precursor m/z values to vector for searching
    for (Size spec_idx = 0; spec_idx < spec_db.size(); ++spec_idx)
    {
      mz_keys.push_back(spec_db[spec_idx].getPrecursors()[0].getMZ());
    }

    // remove potential noise peaks by selecting the ten most intense peak per 100 Da window
    WindowMower wm;
    Param wm_param;

    wm_param.setValue("windowsize", 20.0);
    wm_param.setValue("movetype", "slide");
    wm_param.setValue("peakcount", 5);
    wm.setParameters(wm_param);

    wm.filterPeakMap(msexp);

    // merge MS2 spectra with same precursor mass
    SpectraMerger spme;
    spme.mergeSpectraPrecursors(msexp);
    wm.filterPeakMap(msexp);

    // container storing results
    vector<SpectralMatch> matching_results;

    bool fragment_error_unit_ppm(true);
    if (mz_error_unit_ == "Da") { fragment_error_unit_ppm = false; }

    for (Size spec_idx = 0; spec_idx < msexp.size(); ++spec_idx)
    {
      // cout << "merged spectrum no. " << spec_idx << " with #fragment ions: " << msexp[spec_idx].size() << endl;

      // iterate over all precursor masses
      for (Size prec_idx = 0; prec_idx < msexp[spec_idx].getPrecursors().size(); ++prec_idx)
      {
        // get precursor m/z
        double precursor_mz(msexp[spec_idx].getPrecursors()[prec_idx].getMZ());

        // cout << "precursor no. " << prec_idx << ": mz " << precursor_mz << " ";

        double prec_mz_lowerbound, prec_mz_upperbound;

        if (!fragment_error_unit_ppm) // Da
        {
          prec_mz_lowerbound = precursor_mz - precursor_mz_error_;
          prec_mz_upperbound = precursor_mz + precursor_mz_error_;
        }
        else // ppm
        {
          double ppm_offset(precursor_mz * 1e-6 * precursor_mz_error_);
          prec_mz_lowerbound = precursor_mz - ppm_offset;
          prec_mz_upperbound = precursor_mz + ppm_offset;
        }

        // cout << "lower mz: " << prec_mz_lowerbound << " ";
        // cout << "upper mz: " << prec_mz_upperbound << endl;

        vector<double>::const_iterator lower_it = lower_bound(mz_keys.begin(), mz_keys.end(), prec_mz_lowerbound);
        vector<double>::const_iterator upper_it = upper_bound(mz_keys.begin(), mz_keys.end(), prec_mz_upperbound);

        Size start_idx(lower_it - mz_keys.begin());
        Size end_idx(upper_it - mz_keys.begin());

        //cout << "identifying " << msexp[spec_idx].getMetaValue("Massbank_Accession_ID") << endl;

        vector<SpectralMatch> partial_results;

        for (Size search_idx = start_idx; search_idx < end_idx; ++search_idx)
        {
          // do spectral matching
          // cout << "scanning " << spec_db[search_idx].getPrecursors()[0].getMZ() << " " << spec_db[search_idx].getMetaValue("Metabolite_Name") << endl;

          // check for charge state of precursor ions: do they match?
          if ( (ion_mode_ == "positive" && spec_db[search_idx].getPrecursors()[0].getCharge() < 0) || (ion_mode_ == "negative" && spec_db[search_idx].getPrecursors()[0].getCharge() > 0))
          {
            continue;
          }

          double hyperscore(computeHyperScore(fragment_mz_error_, fragment_error_unit_ppm, msexp[spec_idx], spec_db[search_idx], 0.0));

          // cout << " scored with " << hyperScore << endl;
          if (hyperscore > 0)
          {
            // cout << "  ** detected " << spec_db[search_idx].getMetaValue("Massbank_Accession_ID") << " " << spec_db[search_idx].getMetaValue("Metabolite_Name") << " scored with " << hyperscore << endl;

            // score result temporarily
            SpectralMatch tmp_match;
            tmp_match.setObservedPrecursorMass(precursor_mz);
            tmp_match.setFoundPrecursorMass(spec_db[search_idx].getPrecursors()[0].getMZ());
            double obs_rt = floor(msexp[spec_idx].getRT() * 10)/10.0;
            tmp_match.setObservedPrecursorRT(obs_rt);
            tmp_match.setFoundPrecursorCharge(spec_db[search_idx].getPrecursors()[0].getCharge());
            tmp_match.setMatchingScore(hyperscore);
            tmp_match.setObservedSpectrumIndex(spec_idx);
            tmp_match.setMatchingSpectrumIndex(search_idx);

            tmp_match.setPrimaryIdentifier(spec_db[search_idx].getMetaValue("Massbank_Accession_ID"));
            tmp_match.setSecondaryIdentifier(spec_db[search_idx].getMetaValue("HMDB_ID"));
            tmp_match.setSumFormula(spec_db[search_idx].getMetaValue("Sum_Formula"));
            tmp_match.setCommonName(spec_db[search_idx].getMetaValue("Metabolite_Name"));
            tmp_match.setInchiString(spec_db[search_idx].getMetaValue("Inchi_String"));
            tmp_match.setSMILESString(spec_db[search_idx].getMetaValue("SMILES_String"));
            tmp_match.setPrecursorAdduct(spec_db[search_idx].getMetaValue("Precursor_Ion"));

            partial_results.push_back(tmp_match);
          }
        }

        // sort results by decreasing store
        sort(partial_results.begin(), partial_results.end(), SpectralMatchScoreGreater);

        // report mode: top3 or best?
        if (report_mode_ == "top3")
        {
          Size num_results(partial_results.size());

          Size last_result_idx = (num_results >= 3) ? 3 : num_results;

          for (Size result_idx = 0; result_idx < last_result_idx; ++result_idx)
          {
            // cout << "score: " << partial_results[result_idx].getMatchingScore() << " " << partial_results[result_idx].getMatchingSpectrumIndex() << endl;
            matching_results.push_back(partial_results[result_idx]);
          }
        }

        if (report_mode_ == "best")
        {
          if (partial_results.size() > 0)
          {
            matching_results.push_back(partial_results[0]);
          }
        }

      } // end precursor loop
    } // end spectra loop

    // write final results to MzTab
    exportMzTab_(matching_results, mztab_out);
  }

  /// protected methods

  void MetaboliteSpectralMatching::updateMembers_()
  {
    precursor_mz_error_ = (double)param_.getValue("prec_mass_error_value");
    fragment_mz_error_ = (double)param_.getValue("frag_mass_error_value");
    ion_mode_ = param_.getValue("ionization_mode").toString();

    mz_error_unit_ = param_.getValue("mass_error_unit").toString();
    report_mode_ = param_.getValue("report_mode").toString();
  }

  /// private methods

  void MetaboliteSpectralMatching::exportMzTab_(const vector<SpectralMatch>& overall_results, MzTab& mztab_out)
  {
    // iterate the overall results table
    MzTabSmallMoleculeSectionRows all_sm_rows;

    for (Size id_idx = 0; id_idx < overall_results.size(); ++id_idx)
    {
      SpectralMatch current_id(overall_results[id_idx]);

      MzTabSmallMoleculeSectionRow mztab_row_record;

      // set the identifier field
      String hid_temp = current_id.getPrimaryIdentifier();
      MzTabString prim_id;
      prim_id.set(hid_temp);
      vector<MzTabString> id_dummy;
      id_dummy.push_back(prim_id);
      MzTabStringList string_dummy_list;
      string_dummy_list.set(id_dummy);

      mztab_row_record.identifier = string_dummy_list;

      // set the chemical formula field
      MzTabString chem_form;
      String form_temp = current_id.getSumFormula();
      chem_form.set(form_temp);

      mztab_row_record.chemical_formula = chem_form;

      // set the smiles field
      String smi_temp = current_id.getSMILESString();     // extract SMILES from struct mapping file
      MzTabString smi_string;
      smi_string.set(smi_temp);

      mztab_row_record.smiles = smi_string;

      // set the inchi_key field
      String inchi_temp = current_id.getInchiString();    // extract INCHIKEY from struct mapping file
      MzTabString inchi_key;
      inchi_key.set(inchi_temp);

      mztab_row_record.inchi_key = inchi_key;

      // set description field (we use it for the common name of the compound)
      String name_temp = current_id.getCommonName();
      MzTabString common_name;
      common_name.set(name_temp);

      mztab_row_record.description = common_name;

      // set mass_to_charge field (precursor mass here)
      double mz_temp = current_id.getFoundPrecursorMass();
      MzTabDouble mass_to_charge;
      mass_to_charge.set(mz_temp);

      mztab_row_record.exp_mass_to_charge = mass_to_charge;  //TODO: distinguish the experimental precursor mass and spectral library precursor mass (later should probably go into cv_opt_ column)

      // set charge field
      Int ch_temp = current_id.getFoundPrecursorCharge();
      MzTabInteger mcharge;
      mcharge.set(ch_temp);

      mztab_row_record.charge = mcharge;

      // set RT field
      double rt_temp = current_id.getObservedPrecursorRT();
      MzTabDouble rt_temp2;
      rt_temp2.set(rt_temp);
      vector<MzTabDouble> rt_temp3;
      rt_temp3.push_back(rt_temp2);
      MzTabDoubleList observed_rt;
      observed_rt.set(rt_temp3);

      mztab_row_record.retention_time = observed_rt;

      // set database field
      String dbname_temp = "MassBank";
      MzTabString dbname;
      dbname.set(dbname_temp);

      mztab_row_record.database = dbname;

      // set database_version field
      String dbver_temp = "Sep 27, 2013";
      MzTabString dbversion;
      dbversion.set(dbver_temp);

      mztab_row_record.database_version = dbversion;

      // set smallmolecule_abundance_sub
      // check if we deal with a feature or consensus feature
      vector<MzTabDouble> int_temp3;

      double int_temp(0.0);
      MzTabDouble int_temp2;
      int_temp2.set(int_temp);
      int_temp3.push_back(int_temp2);

      for (Size i = 0; i != int_temp3.size(); ++i)
      {
        mztab_row_record.smallmolecule_abundance_study_variable[i + 1] = int_temp3[i];
      }

      // set smallmolecule_abundance_stdev_sub; not applicable for a single feature intensity, however must be filled. Otherwise, the mzTab export fails.
      double stdev_temp(0.0);
      MzTabDouble stdev_temp2;
      stdev_temp2.set(stdev_temp);
      vector<MzTabDouble> stdev_temp3;

      stdev_temp3.push_back(stdev_temp2);

      for (Size i = 0; i != stdev_temp3.size(); ++i)
      {
        mztab_row_record.smallmolecule_abundance_stdev_study_variable[i + 1] = stdev_temp3[i];
      }

      // set smallmolecule_abundance_std_error_sub; not applicable for a single feature intensity, however must be filled. Otherwise, the mzTab export fails.
      double stderr_temp(0.0);
      MzTabDouble stderr_temp2;
      stderr_temp2.set(stderr_temp);
      vector<MzTabDouble> stderr_temp3;

      stderr_temp3.push_back(stderr_temp2);

      for (Size i = 0; i != stderr_temp3.size(); ++i)
      {
        mztab_row_record.smallmolecule_abundance_std_error_study_variable[i + 1] = stderr_temp3[i];
      }

      // optional columns:
      vector<MzTabOptionalColumnEntry> optionals;

      // ppm error
      double error_ppm(((current_id.getFoundPrecursorMass() - current_id.getObservedPrecursorMass())/current_id.getFoundPrecursorMass())*1e6);
      error_ppm = floor(error_ppm*100)/100;

      MzTabString ppmerr;
      ppmerr.set(String(error_ppm));
      MzTabOptionalColumnEntry col0;
      col0.first = "opt_ppm_error";
      col0.second = ppmerr;
      optionals.push_back(col0);

      // set found adduct ion
      String addion_temp = current_id.getPrecursorAdduct();
      MzTabString addion;
      addion.set(addion_temp);
      MzTabOptionalColumnEntry col1;
      col1.first = "opt_adduct_ion";
      col1.second = addion;
      optionals.push_back(col1);

      // set isotope similarity score
      double sim_score_temp = current_id.getMatchingScore();
      stringstream read_in;
      read_in << sim_score_temp;
      String sim_score_temp2(read_in.str());
      MzTabString sim_score;
      sim_score.set(sim_score_temp2);
      MzTabOptionalColumnEntry col2;
      col2.first = "opt_match_score";
      col2.second = sim_score;
      optionals.push_back(col2);

      // set secondary ID (here HMDB id)
      String sec_id = current_id.getSecondaryIdentifier();
      MzTabString sec_id_str;
      sec_id_str.set(sec_id);
      MzTabOptionalColumnEntry col3;
      col3.first = "opt_sec_id";
      col3.second = sec_id_str;
      optionals.push_back(col3);

      // set source spectra index
      // TODO: this should use spectra_ref column
      String source_idx = String(current_id.getObservedSpectrumIndex());
      MzTabString source_idx_str;
      source_idx_str.set(source_idx);
      MzTabOptionalColumnEntry col4;
      col4.first = "opt_source_idx";
      col4.second = source_idx_str;
      optionals.push_back(col4);

      mztab_row_record.opt_ = optionals;

      all_sm_rows.push_back(mztab_row_record);
    }
    mztab_out.setSmallMoleculeSectionRows(all_sm_rows);
  }

} // closing namespace OpenMS

max_stars_repo_name: vmusch/OpenMS

max_issues_repo_name: vmusch/OpenMS

max_forks_repo_name: vmusch/OpenMS


text:
#include "QueryExpressionParser.h"
#include "components/Exceptions.h"
#include "search/query/QueryExpression.h"
#include "search/query/QueryExpressionImpl.h"
#include "utils/Log.h"

#include <memory>
#include <functional>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_distinct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

namespace carto {
    namespace queryexpressionimpl {
        namespace phx = boost::phoenix;
        namespace qi = boost::spirit::qi;
        namespace repo = boost::spirit::repository::qi;
        namespace encoding = boost::spirit::iso8859_1;

        template <typename Iterator>
        struct Grammar : qi::grammar<Iterator, std::shared_ptr<QueryExpression>(), encoding::space_type> {
            Grammar() : Grammar::base_type(expression) {
                using qi::_val;
                using qi::_1;
                using qi::_2;

                unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n')
                ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
                ("\\\'", '\'')("\\\"", '\"');

                is_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["is"]];
                or_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["or"]];
                and_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["and"]];
                not_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["not"]];
                null_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["null"]];
                false_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["false"]];
                true_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["true"]];
                collate_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["collate"]];
                regexp_like_kw = repo::distinct(qi::char_("a-zA-Z0-9_"))[qi::no_case["regexp_like"]];

                string =
                    '\'' >> *(unesc_char | "\\x" >> qi::hex | (qi::print - '\'')) >> '\'';

                value =
                      null_kw       [_val = phx::construct<Value>()]
                    | false_kw      [_val = phx::construct<Value>(false)]
                    | true_kw       [_val = phx::construct<Value>(true)]
                    | qi::long_long [_val = phx::construct<Value>(_1)]
                    | qi::double_   [_val = phx::construct<Value>(_1)]
                    | string        [_val = phx::construct<Value>(_1)]
                    ;

                identifier %=
                    qi::lexeme[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z0-9_")] >> -(qi::string("::") >> identifier)
                    ;

                expression =
                    term1 [_val = _1] >> *((("||" | or_kw) > term1) [_val = phx::bind(&OrExpression::create, _val, _1)])
                    ;

                term1 =
                    term2 [_val = _1] >> *((("&&" | and_kw) > term1) [_val = phx::bind(&AndExpression::create, _val, _1)])
                    ;

                term2 =
                      term3 [_val = _1]
                    | (("!" || not_kw) >> term3) [_val = phx::bind(&NotExpression::create, _1)]
                    ;

                term3 =
                      predicate [_val = _1]
                    | (regexp_like_kw >> '(' > operand > ',' > operand > ')')  [_val = phx::bind(&BinaryPredicateExpression<RegexpLikePredicate>::create, _1, _2)]
                    | ('(' >> expression > ')') [_val = _1]
                    ;

                predicate =
                      (operand >> "<=" > operand) [_val = phx::bind(&BinaryPredicateExpression<LtePredicate>::create, _1, _2)]
                    | (operand >> ">=" > operand) [_val = phx::bind(&BinaryPredicateExpression<GtePredicate>::create, _1, _2)]
                    | (operand >> "<"  > operand) [_val = phx::bind(&BinaryPredicateExpression<LtPredicate>::create, _1, _2)]
                    | (operand >> ">"  > operand) [_val = phx::bind(&BinaryPredicateExpression<GtPredicate>::create, _1, _2)]
                    | (operand >> (qi::lit("==") | qi::lit("=") ) > operand) [_val = phx::bind(&BinaryPredicateExpression<EqPredicate>::create, _1, _2)]
                    | (operand >> (qi::lit("<>") | qi::lit("!=")) > operand) [_val = phx::bind(&BinaryPredicateExpression<NeqPredicate>::create, _1, _2)]
                    | (operand >> is_kw >> null_kw)           [_val = phx::bind(&UnaryPredicateExpression<IsNullPredicate>::create, _1)]
                    | (operand >> is_kw >> not_kw >> null_kw) [_val = phx::bind(&UnaryPredicateExpression<IsNotNullPredicate>::create, _1)]
                    ;

                operand =
                      value [_val = phx::bind(&ConstOperand::create, _1)]
                    | (identifier >> collate_kw > identifier) [_val = phx::bind(&VariableOperand::createEx, _1, _2)]
                    | identifier [_val = phx::bind(&VariableOperand::create, _1)]
                    ;
            }

            qi::symbols<char const, char const> unesc_char;
            qi::rule<Iterator, qi::unused_type()> is_kw, or_kw, and_kw, not_kw, null_kw, false_kw, true_kw, collate_kw, regexp_like_kw;
            qi::rule<Iterator, std::string()> string;
            qi::rule<Iterator, Value()> value;
            qi::rule<Iterator, std::string()> identifier;
            qi::rule<Iterator, std::shared_ptr<Expression>(), encoding::space_type> expression, term1, term2, term3, predicate;
            qi::rule<Iterator, std::shared_ptr<Operand>(), encoding::space_type> operand;
        };
    }

    std::shared_ptr<QueryExpression> QueryExpressionParser::parse(const std::string& expr) {
        std::string::const_iterator it = expr.begin();
        std::string::const_iterator end = expr.end();
        queryexpressionimpl::encoding::space_type space;
        std::shared_ptr<QueryExpression> queryExpr;
        bool result = boost::spirit::qi::phrase_parse(it, end, queryexpressionimpl::Grammar<std::string::const_iterator>(), space, queryExpr);
        if (!result) {
            throw ParseException("Failed to parse query expression", expr);
        } else if (it != expr.end()) {
            throw ParseException("Could not parse to the end of query expression", expr, static_cast<int>(expr.end() - it));
        }
        return queryExpr;
    }

    QueryExpressionParser::QueryExpressionParser() {
    }

}

ext: cpp

max_stars_repo_name: JianYT/mobile-sdk

max_issues_repo_name: JianYT/mobile-sdk

max_forks_repo_name: JianYT/mobile-sdk


text:
// Copyright (C) 2018 Vicente J. Botet Escriba
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on https://github.com/akrzemi1/explicit/blob/master/test/test_explicit.cpp

// <experimental/.../utility/narrow.hpp>

#define JASEL_CONFIG_CONTRACT_VIOLATION_THROWS_V 1

#include <experimental/utility.hpp>
#include <limits>
#include <memory>

#include <boost/detail/lightweight_test.hpp>

namespace stdex = std::experimental;

#if __cplusplus >= 201402L
static_assert(stdex::narrow_to<short>(1) == std::make_pair(true, short(1)), "error");
static_assert(stdex::narrow_to<short>(100000) == std::make_pair(false, short(0)), "error");
static_assert(stdex::can_narrow_to<short>(100000) == false, "error");
#endif

void test_narrow_throws_when_narrowing_with_value_loss()
{
	BOOST_TEST(!stdex::can_narrow_to<char>(300));
	try
	{
		auto x = stdex::narrow<char>(300);
		(void)x;
		BOOST_TEST(false);
	}
	catch (stdex::narrowing_error &)
	{
	}
	catch (...)
	{
		BOOST_TEST(false);
	}

	BOOST_TEST(!stdex::can_narrow_to<char>(-30 - 128));
	try
	{
		auto x = stdex::narrow<signed char>(-30 - 128);
		(void)x;
		BOOST_TEST(false);
	}
	catch (stdex::narrowing_error &)
	{
	}
	catch (...)
	{
		BOOST_TEST(false);
	}
	try
	{
		signed char d = -128;
		BOOST_TEST(!stdex::can_narrow_to<signed char>(-d));
		auto x = stdex::narrow<signed char>(-d);
		(void)x;
		BOOST_TEST(false);
	}
	catch (stdex::narrowing_error &)
	{
	}
	catch (...)
	{
		BOOST_TEST(false);
	}

	BOOST_TEST(!stdex::can_narrow_to<unsigned char>(-128));
	try
	{
		auto x = stdex::narrow<unsigned char>(-128);
		(void)x;
		BOOST_TEST(false);
	}
	catch (stdex::narrowing_error &)
	{
	}
	catch (...)
	{
		BOOST_TEST(false);
	}

	const auto int32_min = std::numeric_limits<std::int32_t>::min();
	BOOST_TEST(!stdex::can_narrow_to<uint32_t>(int32_min));
	try
	{
		auto x = stdex::narrow<uint32_t>(int32_min);
		(void)x;
		BOOST_TEST(false);
	}
	catch (stdex::narrowing_error &)
	{
	}
	catch (...)
	{
		BOOST_TEST(false);
	}

	const auto uint32_max = std::numeric_limits<std::uint32_t>::max();
	BOOST_TEST(!stdex::can_narrow_to<int32_t>(uint32_max));
	try
	{
		auto x = stdex::narrow<int32_t>(uint32_max);
		(void)x;
		BOOST_TEST(false);
	}
	catch (stdex::narrowing_error &)
	{
	}
	catch (...)
	{
		BOOST_TEST(false);
	}
}

void test_narrow_allows_narrowing_without_value_loss()
{

	{
		using T = int;
		using U = int;
		U u     = 1;
		T t     = static_cast<T>(u);
		BOOST_TEST(static_cast<U>(t) == u);
		BOOST_TEST((stdex::detail::have_same_sign<T, U>::value));
		BOOST_TEST((t < T{}) == (u < U{}));
	}
	BOOST_TEST(stdex::can_narrow_to<int>(1));
	BOOST_TEST(stdex::can_narrow_to<unsigned int>(1));
	{
		std::uint8_t t = static_cast<std::uint8_t>(std::int32_t(0));
		BOOST_TEST_EQ(static_cast<std::int32_t>(t), std::int32_t(0));

		// (!detail::have_same_sign<T, U>::value && ((t < T{}) != (u < U{})))

		BOOST_TEST((!stdex::detail::have_same_sign<std::uint8_t, std::int32_t>::value));
		BOOST_TEST((t < std::uint8_t{}) == (std::int32_t(0) < std::int32_t{}));
	}
	{
		using T = std::uint8_t;
		using U = std::int32_t;
		U u     = 1;
		T t     = static_cast<T>(u);
		BOOST_TEST(static_cast<U>(t) == u);
		BOOST_TEST(!(stdex::detail::have_same_sign<T, U>::value));
		BOOST_TEST((t < T{}) == (u < U{}));
	}
	BOOST_TEST(stdex::can_narrow_to<std::uint8_t>(int32_t(0)));
	BOOST_TEST(stdex::narrow<std::uint8_t>(int32_t(0)) == 0);
	BOOST_TEST(stdex::can_narrow_to<std::uint16_t>(int32_t(30)));
	BOOST_TEST(stdex::narrow<std::uint16_t>(int32_t(30)) == 30);

	BOOST_TEST(stdex::narrow<std::uint32_t>(int32_t(0)) == 0);
	BOOST_TEST(stdex::can_narrow_to<std::uint32_t>(int32_t(0)));
	BOOST_TEST(stdex::narrow<std::uint32_t>(int32_t(1)) == 1);

	const auto int32_max = std::numeric_limits<std::int32_t>::max();
	BOOST_TEST(stdex::narrow<std::uint32_t>(int32_max) == static_cast<std::uint32_t>(int32_max));
	BOOST_TEST(stdex::can_narrow_to<std::uint32_t>(int32_max));

	const auto uint32_min = std::numeric_limits<std::uint32_t>::min();
	BOOST_TEST(stdex::narrow<std::int32_t>(uint32_min) == static_cast<std::int32_t>(uint32_min));

#if __cplusplus > 201103L
	static_assert(stdex::narrow<std::uint16_t>(int32_t(30)) == 30, "");
#endif
}

int main()
{
	test_narrow_throws_when_narrowing_with_value_loss();
	test_narrow_allows_narrowing_without_value_loss();

	return ::boost::report_errors();
}

max_stars_repo_name: jwakely/std-make

max_issues_repo_name: jwakely/std-make

max_forks_repo_name: jwakely/std-make


text:
// Software License for MTL
//
// Copyright (c) 2007 The Trustees of Indiana University.
//               2008 Dresden University of Technology and the Trustees of Indiana University.
//               2010 SimuNova UG (haftungsbeschränkt), www.simunova.com.
// All rights reserved.
// Authors: Peter Gottschling and Andrew Lumsdaine
//
// This file is part of the Matrix Template Library
//
// See also license.mtl.txt in the distribution.

#ifndef MTL_VEC_SCAL_AOP_EXPR_INCLUDE
#define MTL_VEC_SCAL_AOP_EXPR_INCLUDE

#include <boost/numeric/mtl/utility/exception.hpp>
#include <boost/numeric/mtl/vector/vec_expr.hpp>
#include <boost/numeric/mtl/operation/sfunctor.hpp>
#include <boost/numeric/mtl/interface/vpt.hpp>

namespace mtl { namespace vec {

// Generic assign operation expression template for vectors
// Model of VectorExpression
template <class E1, class E2, typename SFunctor>
struct vec_scal_aop_expr
    : public vec_expr< vec_scal_aop_expr<E1, E2, SFunctor> >
{
    typedef vec_expr< vec_scal_aop_expr<E1, E2, SFunctor> >  expr_base;
    typedef vec_scal_aop_expr                                self;
    typedef typename E1::value_type              value_type;

    // temporary solution
    typedef typename E1::size_type               size_type;
    //typedef typename utilities::smallest< typename E1::size_type, typename E2::size_type >::type                          size_type ;

    typedef value_type reference_type ;

    typedef E1 first_argument_type ;
    typedef E2 second_argument_type ;

    vec_scal_aop_expr( first_argument_type& v1, second_argument_type const& v2, bool delay= false )
      : first( v1 ), second( v2 ), delayed_assign( delay ), with_comma( false ), index(0)
    {}

    ~vec_scal_aop_expr()
    {
	if (!delayed_assign) {
	    vampir_trace<2018> tracer;
	    if (with_comma) {
		MTL_DEBUG_THROW_IF(index != mtl::vec::size(first), incompatible_size("Not all vector entries initialized!"));
	    } else
		for (size_type i= 0; i < mtl::vec::size(first); ++i)
		    SFunctor::apply( first(i), second );
	}
    }

    void delay_assign() const
    {
	MTL_DEBUG_THROW_IF(with_comma, logic_error("Comma notation conflicts with rich expression templates."));
	delayed_assign= true;
    }

    //friend size_type inline size(const self& v) { return size(v.first); }
    template <typename EE1, typename EE2, typename SSFunctor>
    friend std::size_t size(const vec_scal_aop_expr<EE1, EE2, SSFunctor>& v);

    value_type& operator() ( size_type i ) const
    {
	assert( delayed_assign && !with_comma);
	return SFunctor::apply( first(i), second );
    }

    value_type& operator[] ( size_type i ) const
    {
	assert( delayed_assign );
	return SFunctor::apply( first(i), second );
    }

    template <unsigned Offset>
    value_type& at(size_type i) const {
	assert(delayed_assign);
	return SFunctor::apply(first(i+Offset), second);
    }

    template <typename Source>
    self& operator, (Source val)
    {
	//std::cout << "vec_scal_aop_expr::operator,\n";
	if (!with_comma) {
	    with_comma= true;
	    assert(index == 0);
	    SFunctor::apply( first(index++), second); // We haven't set v[0] yet
	}
	MTL_DEBUG_THROW_IF(index >= mtl::vec::size(first), range_error());
	SFunctor::apply( first(index++), val);
	return *this;
    }

  private:
    first_argument_type&         first ;
    second_argument_type const&  second ;
    mutable bool                 delayed_assign, with_comma;
    size_type                    index;
} ; // vec_scal_aop_expr

template <typename E1, typename E2, typename SFunctor>
inline std::size_t size(const vec_scal_aop_expr<E1, E2, SFunctor>& v)
{
    return size(v.first);
}

} } // Namespace mtl::vector

#endif

ext: hpp


text:
#ifndef STAN_LANG_AST_BLOCK_VAR_TYPE_HPP
#define STAN_LANG_AST_BLOCK_VAR_TYPE_HPP

#include <boost/variant/recursive_variant.hpp>
#include <stan/lang/ast/node/expression.hpp>
#include <stan/lang/ast/node/offset_multiplier.hpp>
#include <stan/lang/ast/node/range.hpp>
#include <cstddef>
#include <string>
#include <vector>

namespace stan {
namespace lang {

/**
 * Block variable types
 */

struct block_array_type;
struct cholesky_factor_corr_block_type;
struct cholesky_factor_cov_block_type;
struct corr_matrix_block_type;
struct cov_matrix_block_type;
struct double_block_type;
struct ill_formed_type;
struct int_block_type;
struct matrix_block_type;
struct ordered_block_type;
struct positive_ordered_block_type;
struct row_vector_block_type;
struct simplex_block_type;
struct unit_vector_block_type;
struct vector_block_type;

struct block_var_type {
  /**
   * Recursive wrapper for block variable types.
   */
  typedef boost::variant<
      boost::recursive_wrapper<ill_formed_type>,
      boost::recursive_wrapper<cholesky_factor_corr_block_type>,
      boost::recursive_wrapper<cholesky_factor_cov_block_type>,
      boost::recursive_wrapper<corr_matrix_block_type>,
      boost::recursive_wrapper<cov_matrix_block_type>,
      boost::recursive_wrapper<double_block_type>,
      boost::recursive_wrapper<int_block_type>,
      boost::recursive_wrapper<matrix_block_type>,
      boost::recursive_wrapper<ordered_block_type>,
      boost::recursive_wrapper<positive_ordered_block_type>,
      boost::recursive_wrapper<row_vector_block_type>,
      boost::recursive_wrapper<simplex_block_type>,
      boost::recursive_wrapper<unit_vector_block_type>,
      boost::recursive_wrapper<vector_block_type>,
      boost::recursive_wrapper<block_array_type>>
      block_t;

  /**
   * The block variable type held by this wrapper.
   */
  block_t var_type_;

  /**
   * Construct a block var type with default values.
   */
  block_var_type();

  /**
   * Construct a block var type with the specified type.
   *
   * @param type block variable type
   */
  block_var_type(const block_var_type &type);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const ill_formed_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(
      const cholesky_factor_corr_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(
      const cholesky_factor_cov_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const corr_matrix_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const cov_matrix_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const double_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const int_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const matrix_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const ordered_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(
      const positive_ordered_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const row_vector_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const simplex_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const unit_vector_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const vector_block_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const block_array_type &x);  // NOLINT(runtime/explicit)

  /**
   * Construct a block var type with the specified type.
   *
   * @param x block variable type
   */
  block_var_type(const block_t &x);  // NOLINT(runtime/explicit)

  /**
   * Returns expression for length of vector types or
   * number of rows for matrix type, nil otherwise.
   */
  expression arg1() const;

  /**
   * Returns expression for number of columns for matrix types,
   * nil otherwise.
   */
  expression arg2() const;

  /**
   * If `var_type` is `block_array_type`, returns the innermost type
   * contained in the array, otherwise will return `ill_formed_type`.
   */
  block_var_type array_contains() const;

  /**
   * Returns number of array dimensions for this type.
   * Returns 0 for non-array types.
   */
  int array_dims() const;

  /**
   * Returns array element type if `var_type_` is `block_array_type`,
   * ill_formed_type otherwise.  (Call `is_array_type()` first.)
   */
  block_var_type array_element_type() const;

  /**
   * Returns array length for block_array_type, nil otherwise.
   */
  expression array_len() const;

  /**
   * Returns vector of array lengths for block_array_type,
   * empty vector otherwise.
   */
  std::vector<expression> array_lens() const;

  /**
   * Returns equivalent bare_expr_type (unsized) for this block type.
   */
  bare_expr_type bare_type() const;

  /**
   * Returns bounds for this type.
   */
  range bounds() const;

  /**
   * Returns true if there are specified upper and/or lower bounds
   * for this type (contained type for arrays), false otherwise.
   */
  bool has_def_bounds() const;

  /**
   * Returns offset and multiplier for this type.
   */
  offset_multiplier ls() const;

  /**
   * Returns true if there are specified offset and/or multiplier
   * for this type (contained type for arrays), false otherwise.
   */
  bool has_def_offset_multiplier() const;

  /**
   * Returns true if `var_type_` is `block_array_type`, false otherwise.
   */
  bool is_array_type() const;

  /**
   * Returns true if `var_type_` has either specified bounds or
   * is a specialized vector or matrix type.
   */
  bool is_constrained() const;

  /**
   * Returns true if `var_type_` is a specialized vector or matrix type.
   * If `var_type_` is array type, evaluates contained type.
   */
  bool is_specialized() const;

  /**
   * If array type, returns innermost type,
   * otherwise returns this type.
   */
  block_var_type innermost_type() const;

  /**
   * Returns Stan language type name.
   */
  std::string name() const;

  /**
   * Returns total number of dimensions for container type.
   * Returns 0 for scalar types.
   */
  int num_dims() const;

  /**
   * Returns an expression for the number of parameters
   * a parameter variable of this type contributes to a model.
   */
  expression params_total() const;
};

/**
 * Stream a user-readable version of the block_var_type to the
 * specified output stream, returning the specified argument
 * output stream to allow chaining.
 *
 * @param o output stream
 * @param x expression type
 * @return argument output stream
 */
std::ostream &operator<<(std::ostream &o, const block_var_type &x);

}  // namespace lang
}  // namespace stan
#endif

max_stars_repo_name: alashworth/stan-monorepo

max_issues_repo_name: alashworth/stan-monorepo

max_forks_repo_name: alashworth/stan-monorepo


text:
char const* NOTES =
  "ZF_and_E means unnormalized scaled features.\n"
  "For grammars with one nonterminal: F_and_E is joint,\n"
  "F_given_E and E_given_F are conditional.\n"
  "TODO: group rules by root nonterminal and then normalize.\n";

#include <iostream>
#include <fstream>
#include <tr1/unordered_map>

#include <boost/program_options.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/functional/hash.hpp>

#include "prob.h"
#include "filelib.h"
#include "trule.h"
#include "weights.h"

namespace po = boost::program_options;
using namespace std;

typedef std::tr1::unordered_map<vector<WordID>, prob_t, boost::hash<vector<WordID> > > MarginalMap;

void InitCommandLine(int argc, char** argv, po::variables_map* conf) {
  po::options_description opts("Configuration options");
  opts.add_options()
        ("grammar,g", po::value<string>(), "Grammar file")
        ("weights,w", po::value<string>(), "Weights file")
    ("unnormalized,u", "Always include ZF_and_E unnormalized score (default: only if sum was >1)")
    ;
  po::options_description clo("Command line options");
  clo.add_options()
        ("config,c", po::value<string>(), "Configuration file")
        ("help,h", "Print this help message and exit");
  po::options_description dconfig_options, dcmdline_options;
  dconfig_options.add(opts);
  dcmdline_options.add(opts).add(clo);

  po::store(parse_command_line(argc, argv, dcmdline_options), *conf);
  if (conf->count("config")) {
    const string cfg = (*conf)["config"].as<string>();
    cerr << "Configuration file: " << cfg << endl;
    ifstream config(cfg.c_str());
    po::store(po::parse_config_file(config, dconfig_options), *conf);
  }
  po::notify(*conf);

  if (conf->count("help") || !conf->count("grammar") || !conf->count("weights")) {
    cerr << dcmdline_options << endl;
    cerr << NOTES << endl;
    exit(1);
  }
}

int main(int argc, char** argv) {
  po::variables_map conf;
  InitCommandLine(argc, argv, &conf);
  const string wfile = conf["weights"].as<string>();
  const string gfile = conf["grammar"].as<string>();
  Weights wm;
  wm.InitFromFile(wfile);
  vector<double> w;
  wm.InitVector(&w);
  MarginalMap e_tots;
  MarginalMap f_tots;
  prob_t tot;
  {
    ReadFile rf(gfile);
    assert(*rf.stream());
    istream& in = *rf.stream();
    cerr << "Computing marginals...\n";
    int lc = 0;
    while(in) {
      string line;
      getline(in, line);
      ++lc;
      if (line.empty()) continue;
      TRule tr(line, true);
      if (tr.GetFeatureValues().empty())
        cerr << "Line " << lc << ": empty features - may introduce bias\n";
      prob_t prob;
      prob.logeq(tr.GetFeatureValues().dot(w));
      e_tots[tr.e_] += prob;
      f_tots[tr.f_] += prob;
      tot += prob;
    }
  }
  bool normalized = (fabs(log(tot)) < 0.001);
  cerr << "Total: " << tot << (normalized ? " [normalized]" : " [scaled]") << endl;
  ReadFile rf(gfile);
  istream&in = *rf.stream();
  while(in) {
    string line;
    getline(in, line);
    if (line.empty()) continue;
    TRule tr(line, true);
    const double lp = tr.GetFeatureValues().dot(w);
    if (isinf(lp)) { continue; }
    tr.scores_.clear();

    cout << tr.AsString() << " ||| F_and_E=" << lp - log(tot);
    if (!normalized || conf.count("unnormalized")) {
      cout << ";ZF_and_E=" << lp;
    }
    cout << ";F_given_E=" << lp - log(e_tots[tr.e_])
         << ";E_given_F=" << lp - log(f_tots[tr.f_]) << endl;
  }
  return 0;
}

ext: cc

max_stars_repo_name: agesmundo/FasterCubePruning

max_issues_repo_name: jhclark/cdec

max_forks_repo_name: jhclark/cdec


text:
/* Copyright (C) 2014 InfiniDB, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; version 2 of
   the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301, USA. */

#include <unistd.h>
#include <iostream>
#include <sstream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/thread/thread.hpp>

#include "configcpp.h"                   // for Config
#include "oamcache.h"
#include "liboamcpp.h"
#include "IDBPolicy.h"
#include "PosixFileSystem.h"
//#include "HdfsFileSystem.h"
//#include "HdfsFsCache.h"
#include "IDBLogger.h"
#include "IDBFactory.h"
#ifdef _MSC_VER
#include "utils_utf8.h"  // idb_wcstombs()
#endif

#include "installdir.h"
#include "vlarray.h"

using namespace std;

namespace idbdatafile
{

bool IDBPolicy::s_usehdfs = false;
bool IDBPolicy::s_usecloud = false;
bool IDBPolicy::s_bUseRdwrMemBuffer = false;
int64_t IDBPolicy::s_hdfsRdwrBufferMaxSize = 0;
std::string IDBPolicy::s_hdfsRdwrScratch;
bool IDBPolicy::s_configed = false;
boost::mutex IDBPolicy::s_mutex;
std::vector<uint16_t> IDBPolicy::s_PreallocSpace;

void IDBPolicy::init( bool bEnableLogging, bool bUseRdwrMemBuffer, const string& hdfsRdwrScratch, int64_t hdfsRdwrBufferMaxSize )
{
    IDBFactory::installDefaultPlugins();

    IDBLogger::enable( bEnableLogging );

    s_bUseRdwrMemBuffer = bUseRdwrMemBuffer;
    s_hdfsRdwrBufferMaxSize = hdfsRdwrBufferMaxSize;
    s_hdfsRdwrScratch = hdfsRdwrScratch;

    // Create our scratch directory
    if ( hdfsRdwrScratch.length() > 0 )
    {
        // TODO-check to make sure this directory has sufficient space, whatever that means.

        boost::filesystem::path tmpfilepath( hdfsRdwrScratch );

        if (boost::filesystem::exists(tmpfilepath))
        {
            if (!boost::filesystem::is_directory(tmpfilepath) && useHdfs())
            {
                // We found a file named what we want our scratch directory to be named.
                // Major issue, since we can't assume anything about where to put our tmp files
                ostringstream oss;
                oss << "IDBPolicy::init: scratch diretory setting " << hdfsRdwrScratch.c_str()
                    << " exists as a file. Can't create hdfs buffer files.";
                throw runtime_error(oss.str());
            }
        }
        else
        {
			cout << tmpfilepath << endl;
            bool itWorked = false;

            try
            {
                itWorked = boost::filesystem::create_directories(tmpfilepath);
            }
            catch (...)
            { }
            if (!itWorked)
            {
                // We failed to create the scratch directory
                ostringstream oss;
                oss << "IDBPolicy::init: failed to create hdfs scratch directory "
                    << hdfsRdwrScratch.c_str() << ". Can't create hdfs buffer files.";
                throw runtime_error(oss.str());
            }
        }
    }
}

bool IDBPolicy::installPlugin(const std::string& plugin)
{
    bool ret = IDBFactory::installPlugin(plugin);

    vector<IDBDataFile::Types> plugins = IDBFactory::listPlugins();
    for (uint i = 0; i < plugins.size(); i++)
        if (plugins[i] == IDBDataFile::HDFS)
            s_usehdfs = true;
        else if (plugins[i] == IDBDataFile::CLOUD)
            s_usecloud = true;

    return ret;
}

bool IDBPolicy::isLocalFile( const std::string& path )
{
    boost::filesystem::path filepath( path );
#ifdef _MSC_VER
    size_t strmblen = utf8::idb_wcstombs(0, filepath.extension().c_str(), 0) + 1;
    char* outbuf = (char*)alloca(strmblen * sizeof(char));
    strmblen = utf8::idb_wcstombs(outbuf, filepath.extension().c_str(), strmblen);
    string fileExt(outbuf, strmblen);
#else
    //string fileExt  = filepath.extension().c_str();
#endif
    bool isXml = filepath.extension() == ".xml";
    //bool isDbrm = path.find("dbrm") != string::npos;   // StorageManager: debatable whether dbrm files should go in the cloud
    bool isVb = filepath.filename() == "versionbuffer.cdf";
    bool isScratch = path.find(s_hdfsRdwrScratch) == 0;

    return isXml || isVb || isScratch;
    //return isXml || isDbrm || isVb || isScratch;
}

IDBDataFile::Types IDBPolicy::getType( const std::string& path, Contexts ctxt )
{
    bool isLocal = isLocalFile( path );

    if (isLocal || (!useHdfs() && !useCloud()))
        if (ctxt == PRIMPROC)
            return IDBDataFile::UNBUFFERED;
        else
            return IDBDataFile::BUFFERED;
    else if (useHdfs())
        return IDBDataFile::HDFS;
    else if (useCloud())
        return IDBDataFile::CLOUD;
    throw runtime_error("IDBPolicy: No appropriate data file type");

#if 0
    if ( ctxt == PRIMPROC )
    {
        if ( isLocal || !useHdfs() )
            return IDBDataFile::UNBUFFERED;
        else
            return IDBDataFile::HDFS;
    }
    else
    {
        if ( isLocal || !useHdfs() )
            return IDBDataFile::BUFFERED;
        else
            return IDBDataFile::HDFS;
    }
#endif
}

IDBFileSystem& IDBPolicy::getFs( const std::string& path )
{
    // for now context doesn't actually matter so just pass PRIMPROC
    // later the whole logic around file -> filesystem type mapping
    // needs to be data driven
    return IDBFactory::getFs( getType( path, PRIMPROC) );
}

// ported from we_config.cpp
void IDBPolicy::configIDBPolicy()
{
    // make sure this is done once.
    boost::mutex::scoped_lock lk(s_mutex);

    if (s_configed)
        return;

    config::Config* cf = config::Config::makeConfig();

    //--------------------------------------------------------------------------
    // IDBDataFile logging
    //--------------------------------------------------------------------------
    bool idblog = false;
    string idblogstr = cf->getConfig("SystemConfig", "DataFileLog");

    // Must be faster.
    if ( idblogstr.size() == 2
                && ( idblogstr[0] == 'O' || idblogstr[0] == 'o' )
                && ( idblogstr[1] == 'N' || idblogstr[1] == 'n' ))
    {
        idblog = true;
    }

    //--------------------------------------------------------------------------
    // Optional File System Plugin - if a HDFS type plugin is loaded
    // then the system will use HDFS for all IDB data files
    //--------------------------------------------------------------------------
    string fsplugin = cf->getConfig("SystemConfig", "DataFilePlugin");

    if ( fsplugin.length() != 0 )
    {
        IDBPolicy::installPlugin(fsplugin);
    }

    //--------------------------------------------------------------------------
    // HDFS file buffering
    //--------------------------------------------------------------------------
    // Maximum amount of memory to use for hdfs buffering.
    bool bUseRdwrMemBuffer = true;  // If true, use in-memory buffering, else use file buffering
    int64_t hdfsRdwrBufferMaxSize = 0;
    string strBufferMaxSize = cf->getConfig("SystemConfig", "hdfsRdwrBufferMaxSize");

    // Default is use membuf with no maximum size unless changed by config file.
    if (strBufferMaxSize.length() > 0)
    {
        hdfsRdwrBufferMaxSize = static_cast<int64_t>(cf->uFromText(strBufferMaxSize));

        if ( hdfsRdwrBufferMaxSize == 0 )
        {
            // If we're given a size of 0, turn off membuffering.
            bUseRdwrMemBuffer = false;
        }
    }

    // Directory in which to place file buffer temporary files.
    string tmpDir = startup::StartUp::tmpDir();

    string scratch = cf->getConfig("SystemConfig", "hdfsRdwrScratch");
    string hdfsRdwrScratch = tmpDir + scratch;

    // MCOL-498. Use DBRootX.PreallocSpace to disable
    // dbroots file space preallocation.
    // The feature is used in the FileOp code and enabled by default.
    char configSectionPref[] = "DBRoot";
    int confSectionLen = sizeof(configSectionPref)+oam::MAX_MODULE_ID_SIZE;
    utils::VLArray<char, 1024> configSection(confSectionLen);

    IDBPolicy::init( idblog, bUseRdwrMemBuffer, hdfsRdwrScratch, hdfsRdwrBufferMaxSize );
    s_configed = true;

    oam::OamCache* oamcache = oam::OamCache::makeOamCache();
    int PMId = oamcache->getLocalPMId();

    oam::OamCache::PMDbrootsMap_t pmDbrootsMap;
    pmDbrootsMap.reset(new oam::OamCache::PMDbrootsMap_t::element_type());
    oam::systemStorageInfo_t t;
    oam::Oam oamInst;
    t = oamInst.getStorageConfig();

    oam::DeviceDBRootList moduledbrootlist = boost::get<2>(t);
    oam::DeviceDBRootList::iterator pt = moduledbrootlist.begin();

    while ( pt != moduledbrootlist.end() && (*pt).DeviceID != PMId)
    {
        pt++;
        continue;
    }

    // CS could return here b/c it initialised this singleton and
    // there is no DBRootX sections in XML.
    if (pt == moduledbrootlist.end())
    {
        return;
    }

    oam::DBRootConfigList &dbRootVec = (*pt).dbrootConfigList;
    s_PreallocSpace.reserve(dbRootVec.size()>>1);
    {
        int rc;
        oam::DBRootConfigList::iterator dbRootIter = dbRootVec.begin();
        for(; dbRootIter != dbRootVec.end(); dbRootIter++)
        {
            ::memset(configSection.data() + sizeof(configSectionPref), 0, oam::MAX_MODULE_ID_SIZE);
            rc = snprintf(configSection.data(), confSectionLen, "%s%d", configSectionPref, *dbRootIter);
            // gcc 8.2 warnings
            if ( rc < 0 || rc >= confSectionLen)
            {
                ostringstream oss;
                oss << "IDBPolicy::configIDBPolicy: failed to parse DBRootX section.";
                throw runtime_error(oss.str());
            }
            string setting = cf->getConfig(configSection.data(), "PreallocSpace");

            if ( setting.length() != 0 )
            {
                if ( setting.size() == 2
                    && ( setting[0] == 'O' || setting[0] == 'o' )
                    && ( setting[1] == 'N' || setting[1] == 'n' )
                )
                {
                    // int into uint16_t implicit conversion
                    s_PreallocSpace.push_back(*dbRootIter);
                }
            }
        }
    }
}

void IDBPolicy::enablePreallocSpace(uint16_t dbRoot)
{
   s_PreallocSpace.push_back(dbRoot);
}

}

max_stars_repo_name: zettadb/zettalib

max_issues_repo_name: zettadb/zettalib

max_forks_repo_name: zettadb/zettalib


text: #include <boost/flyweight/assoc_container_factory.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <armadillo>
#include <map>

#include <bounce/game/game.hpp>
#include <bounce/physics/engine/engine.hpp>
#include <bounce/scene/scene.hpp>

void PhysicsEngine::check_set_time()
{
    Duration d = Clock::now() - this->epoch;
    this->irl_time = d.count();
}

void PhysicsEngine::timestep()
{
    this->check_set_time();
    while (this->time < this->irl_time) {
        this->timestep_objects();
    }
}

void PhysicsEngine::timestep_objects()
{
    this->time += this->dt/this->timescale;
    auto *scene = Game::ref().get_active_scene();

    // No active scene; don't run physics
    if (!scene)
        return;

    std::list<Collider *> colliders;
    scene->find_in_children_cast("collider", colliders);
    std::list<Rigidbody *> rigidbodies;
    for (Collider * collider : colliders) {
        if (collider->is_a("rigidbody")) {
            rigidbodies.push_back((Rigidbody *)collider);
        }
    }

    // resolve force fields acting on objects
    for (auto *rb : rigidbodies) {
        arma::vec2 f = rb->get_force();
        for (auto *field : scene->get_fields()) {
            f += field->measure_at(rb);
        }
        rb->set_force(f);
    }

    // Get proposed new positions for objects
    for (auto *rb : rigidbodies) {
        rb->on_physics_update();
        rb->timestep_force(this->dt);
    }

    // Check for and resolve any collisions
    int i = 0, j = 0;
    for (auto *a : rigidbodies) {
        CollisionInformation next_collision = {nullptr, {0, 0}, {0, 0}, 1e9, CD_LEFT, CD_LEFT};

        j = 0;
        for (auto *b : rigidbodies) {
            if (j >= i) break;
            CollisionInformation ci = {b, {0, 0}, {0, 0}, 1e9, CD_LEFT, CD_RIGHT};
            if (this->check_will_collide(a, b, ci)) {
                if (ci.when < next_collision.when) {
                    next_collision = ci;
                }
            }

            j++;
        }
        if (next_collision.b) {
            a->set_touching(next_collision.adir);
            next_collision.b->set_touching(next_collision.bdir);
            this->resolve_collision(a, next_collision.b, next_collision.normal);
        }

        i++;
    }

    // Accept resolved positions; zero forces
    for (auto *rb : rigidbodies) {
        rb->timestep_velocity(this->dt);
        rb->set_force({0, 0});
    }
}

max_stars_repo_name: cbosoft/bounce

max_issues_repo_name: cbosoft/bounce

max_forks_repo_name: cbosoft/bounce


text:
/*
 *   Copyright (C) 2016 Anton Haubner <anton.haubner@outlook.de>
 *
 *   This file is part of the IPFind library.
 *
 *   This software is provided 'as-is', without any express or implied
 *   warranty.  In no event will the authors be held liable for any damages
 *   arising from the use of this software.
 *
 *   Permission is granted to anyone to use this software for any purpose,
 *   including commercial applications, and to alter it and redistribute it
 *   freely, subject to the following restrictions:
 *
 *   1. The origin of this software must not be misrepresented; you must not
 *   claim that you wrote the original software. If you use this software
 *   in a product, an acknowledgment in the product documentation would be
 *   appreciated but is not required.
 *
 *   2. Altered source versions must be plainly marked as such, and must not be
 *   misrepresented as being the original software.
 *
 *   3. This notice may not be removed or altered from any source distribution.
 *
 *   4. Source versions may not be "relicensed" under a different license
 *   without my explicitly written permission.
 *
*/

#include <IPFind/Client.hpp>

#include <thread>
#include <atomic>

#include <boost/asio.hpp>

#include <IPFind/Utils.hpp>

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

namespace IPFind
{
	Client::Client()
	{

	}

	std::string Client::find(Utils::Port port, unsigned int retries, std::chrono::seconds timeout)
	{
		boost::asio::io_service io_service;

		udp::socket Socket(io_service, udp::endpoint(udp::v4(), 0));
		Socket.set_option(boost::asio::socket_base::broadcast(true));

		udp::endpoint Endpoint(address_v4::broadcast(), port);

		atomic_bool NeedCancel(true);
		atomic_bool Success(false);

		for (decltype(retries) i = 0; i < retries; i++)
		{
			Utils::BroadcastPackage Buffer {1};
			Socket.send_to(boost::asio::buffer(Buffer), Endpoint);

			//Antwort empfangen
			udp::endpoint ServerEnd;
			Utils::BroadcastPackage RecvBuffer;

			NeedCancel = true;
			std::thread CancelThread([&io_service, &Socket, timeout, &NeedCancel]()
			{
				this_thread::sleep_for(timeout);

				if (NeedCancel)
				{
					Socket.cancel();
				}
			});

			Socket.async_receive_from(boost::asio::buffer(RecvBuffer), ServerEnd,
									  [&CancelThread, &NeedCancel, &ServerEnd, &Buffer, &Success](boost::system::error_code const & error, std::size_t received)
			{
				NeedCancel = false;
				if (CancelThread.joinable())
				{
					CancelThread.join();
				}

				if (received == Buffer.size() && !error)
				{
					//Etwas empfangen -> Server gefunden!
					Success = true;
				}
			});

			io_service.run();
			io_service.reset();
			if (CancelThread.joinable())
			{
				CancelThread.join();
			}

			if (Success)
			{
				return ServerEnd.address().to_string();
			}
		}

		return {};
	}
}

max_stars_repo_name: ahaubner/IPFind

max_issues_repo_name: ahaubner/IPFind

max_forks_repo_name: ahaubner/IPFind


text:
/**
 * Copyright Pieter Lexis <pieter.lexis@powerdns.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "remote-backend.hh"
#include "iputils/iputils.hh"
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

namespace pdns_sysrepo::remote_backend {
  nlohmann::json::array_t RemoteBackend::getRecordsFromRRSetNode(const libyang::S_Data_Node &node, const string &rrsetLocation) {
    auto ret = nlohmann::json::array();
    auto nodeSchemaPath = node->schema()->path();
    if (nodeSchemaPath != fmt::format("/pdns-server:zones/pdns-server:zones/pdns-server:{}", rrsetLocation)) {
        throw std::range_error(fmt::format("Node {} is not /pdns-server:zones/pdns-server:zones/pdns-server:{}", nodeSchemaPath, rrsetLocation));
    }

    // childNode is rrset[owner][type]/any_of(owner,rdata,ttl,....)
    auto childNode = node->child();

    string qname, qtype;
    uint32_t ttl;
    nlohmann::json record;
    for (auto const &rrsetNode : childNode->tree_for()) {
      if ((rrsetNode->schema()->nodetype() & LYS_CONTAINER) && string(rrsetNode->schema()->name()) == "rdata") {
        // rdataNode is rrset[owner][type]/rdata/<type container>
        auto rdataNode = rrsetNode->child();
        std::vector<string> parts;
        std::string path(rdataNode->path());
        boost::split(parts, path, boost::is_any_of("/"));
        if (parts.back() == "SOA") {
          // rdataNode is now the 'rrset/rdata/<TYPE>/<SOME_NODE>' node or one of its siblings
          rdataNode = rdataNode->child();
          std::map<string, string> recordElements;
          for (auto const& soaNode : rdataNode->tree_for()) {
            auto rdataLeaf = std::make_shared<libyang::Data_Node_Leaf_List>(soaNode);
            string leafName = rdataLeaf->schema()->name();
            recordElements[leafName] = rdataLeaf->value_str();
          }
          record["content"] = fmt::format("{} {} {} {} {} {} {}", recordElements["mname"], recordElements["rname"], recordElements["serial"], recordElements["refresh"], recordElements["retry"], recordElements["expire"], recordElements["minimum"]);
          ret.push_back(record);
        } else if (parts.back() == "MX") {
          bool havePref = false;
          uint16_t pref;
          bool haveExchange = false;
          string exchange;
          for (auto const &n : rdataNode->tree_dfs()) {
            string name(n->schema()->name());
            if (name == "preference") {
              havePref = true;
              auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(n);
              pref = leaf->value()->uint16();
            } else if (name == "exchange") {
              haveExchange = true;
              auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(n);
              exchange = leaf->value_str();
            }
            if (haveExchange && havePref) {
              havePref = false;
              haveExchange = false;
              record["content"] = fmt::format("{} {}", pref, exchange);
              ret.push_back(record);
            }
          }
        } else if (parts.back() == "SRV") {
          bool havePrio = false;
          uint16_t prio;
          bool haveWeight = false;
          uint16_t weight;
          bool havePort = false;
          uint16_t port;
          bool haveTarget = false;
          string target;
          for (auto const &n : rdataNode->tree_dfs()) {
            string nodeName(n->schema()->name());
            std::shared_ptr<libyang::Data_Node_Leaf_List> leaf;
            if (n->schema()->nodetype() == LYS_LEAF) {
              leaf = std::make_shared<libyang::Data_Node_Leaf_List>(n);
            }
            if (nodeName == "priority") {
              havePrio = true;
              prio = leaf->value()->uint16();
            } else if (nodeName == "weight") {
              haveWeight = true;
              weight = leaf->value()->uint16();
            } else if (nodeName == "port") {
              havePort = true;
              port = leaf->value()->uint16();
            } else if (nodeName == "target") {
              haveTarget = true;
              target = leaf->value_str();
            }
            if (havePrio && haveWeight && havePort && haveTarget) {
              havePrio = false;
              haveWeight = false;
              havePort = false;
              haveTarget = false;
              record["content"] = fmt::format("{} {} {} {}", prio, weight, port, target);
              ret.push_back(record);
            }
          }
        } else {
          // This is for all records with one leaf or leaf-list like A, AAAA and CNAME
          // rdataNode is now the 'rrset/rdata/<rrset type>/<whatever the node is called>' node
          rdataNode = rdataNode->child();
          if (rdataNode->schema()->nodetype() & LYS_LEAF) {
              auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(rdataNode);
              record["content"] = leaf->value_str();
              ret.push_back(record);
          } else if (rdataNode->schema()->nodetype() & LYS_LEAFLIST) {
            for (auto const &dataNode : rdataNode->tree_for()) {
              auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(dataNode);
              record["content"] = leaf->value_str();
              ret.push_back(record);
            }
          }
        }
      }

      if (!(rrsetNode->schema()->nodetype() & (LYS_LEAFLIST | LYS_LEAF))) {
        continue;
      }
      auto leaf = std::make_shared<libyang::Data_Node_Leaf_List>(rrsetNode);
      string leafName(rrsetNode->schema()->name());
      if (leafName == "owner") {
        record["qname"] = leaf->value_str();
        qname = leaf->value_str();
      }
      if (leafName  == "type") {
        record["qtype"] = leaf->value_str();
        qtype = leaf->value_str();
      }
      if (leafName  == "ttl") {
        record["ttl"] = leaf->value()->uint32();
        ttl = leaf->value()->uint32();
      }
    }
    // Set the qname, qtype and TTL explicitly in case the nodes were not in the YANG order
    for (auto &r: ret) {
      r["qname"] = qname;
      r["qtype"] = qtype;
      r["ttl"] = ttl;
    }
    return ret;
  }

  libyang::S_Data_Node RemoteBackend::getZoneTree(sysrepo::S_Session session) {
    static const string zonesRootPath = "/pdns-server:zones";
    if (!session) {
      session = getSession();
    }
    auto ret = session->get_subtree(zonesRootPath.c_str());
    if (!ret) {
      throw std::range_error(fmt::format("{} not found in sysrepo", zonesRootPath));
    }
    return ret;
  }

  sessionErrors RemoteBackend::getErrorsFromSession(const sysrepo::S_Session& session) {
    if (!session) {
      throw std::logic_error("Session is a nullptr");
    }

    sessionErrors ret;
    auto errors = session->get_error();
    for (size_t i = 0; i < errors->error_cnt(); i++) {
      string xpath = errors->xpath(i) == nullptr ? "" : errors->xpath(i);
      string message = errors->message(i) == nullptr ? "" : errors->message(i);
      ret.push_back(std::make_pair(xpath, message));
    }
    return ret;
  }

  void RemoteBackend::logSessionErrors(const sysrepo::S_Session& session, const spdlog::level::level_enum &level) {
    auto errors = getErrorsFromSession(session);
    for (auto const& error : errors) {
      spdlog::log(level, "  Error xpath='{}' message='{}'", error.first, error.second);
    }
  }
}

max_stars_repo_name: PowerDNS/pdns-sysrepo

max_issues_repo_name: PowerDNS/pdns-sysrepo

max_forks_repo_name: PowerDNS/pdns-sysrepo


text:
/**
 * DeepDetect
 * Copyright (c) 2020 Jolibrain
 * Author:  Guillaume Infantes <guillaume.infantes@jolibrain.com>
 *
 * This file is part of deepdetect.
 *
 * deepdetect is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * deepdetect is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with deepdetect.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "basegraph.h"
#include <iostream>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/graphviz.hpp>
#include <iterator>
#include <climits>

#include "operators.h"

namespace dd::graph
{
  Vertex BaseGraph::create_var(std::string name)
  {
    _finalized = false;
    _sorted = false;
    Vertex varVertex = boost::add_vertex(_graph);
    _graph[varVertex].name = name;
    _graph[varVertex].op = false;
    ;
    _varIndex[name] = varVertex;
    return varVertex;
  }

  Vertex BaseGraph::create_op(std::string name, std::string type)
  {
    _finalized = false;
    _sorted = false;
    Vertex l = boost::add_vertex(_graph);
    _graph[l].name = name;
    _graph[l].type = type;
    _graph[l].op = true;
    _opIndex[name] = l;
    return l;
  }

  void BaseGraph::set_input_dim(std::vector<int> &inputdim)
  {
    if (_graph[_input].dim == inputdim)
      return;
    _graph[_input].dim = inputdim;
    _finalized = false;
  }

  Vertex BaseGraph::set_input(std::string name, std::vector<int> &inputdim)
  {
    _inputname = name;
    _finalized = false;
    if (_varIndex.find(name) == _varIndex.end())
      _input = create_var(name);
    else
      _graph[_input].name = name;
    _graph[_input].dim = inputdim;
    return _input;
  }

  void BaseGraph::add_layer(std::string opname, std::string optype,
                            std::vector<std::string> &inputs,
                            std::vector<std::string> &outputs)
  {
    Vertex v = add_layer(opname, optype);
    add_inputs(v, inputs);
    add_outputs(v, outputs);
  }

  Vertex BaseGraph::add_layer(std::string opname, std::string optype)
  {
    return create_op(opname, optype);
  }

  std::vector<Vertex> BaseGraph::add_outputs(std::string opname,
                                             std::vector<std::string> &outputs)
  {
    std::unordered_map<std::string, Vertex>::iterator it
        = _opIndex.find(opname);
    if (it == _opIndex.end())
      {
        std::cerr << "cannot add output to non existent layer " << opname
                  << std::endl;
        std::vector<Vertex> ev;
        return ev;
      }
    return add_outputs(it->second, outputs);
  }

  std::vector<Vertex> BaseGraph::add_outputs(Vertex v,
                                             std::vector<std::string> &outputs)
  {
    std::vector<Vertex> outverts;
    for (std::string output : outputs)
      outverts.push_back(add_output(v, output));
    return outverts;
  }

  Vertex BaseGraph::add_output(std::string opname, std::string varname)
  {
    std::unordered_map<std::string, Vertex>::iterator it
        = _opIndex.find(opname);
    if (it == _opIndex.end())
      {
        std::cerr << "cannot add output to non existent layer " << opname
                  << std::endl;
        return LONG_MAX;
      }
    return add_output(it->second, varname);
  }

  Vertex BaseGraph::add_output(Vertex v, std::string varname)
  {
    std::unordered_map<std::string, Vertex>::iterator it
        = _varIndex.find(varname);
    Vertex varVertex;
    if (it == _varIndex.end())
      varVertex = create_var(varname);
    else
      varVertex = it->second;
    if (boost::in_degree(varVertex, _graph) != 0)
      std::cerr << "trying to add multiple producers for  var "
                << _graph[varVertex].name << std::endl;
    else
      {
        boost::add_edge(v, varVertex, _graph);
        _finalized = false;
      }
    return varVertex;
  }

  std::vector<Vertex> BaseGraph::add_inputs(std::string opname,
                                            std::vector<std::string> &inputs)
  {
    std::unordered_map<std::string, Vertex>::iterator it
        = _opIndex.find(opname);
    if (it == _opIndex.end())
      {
        std::cerr << "cannot add inputs to non existent layer " << opname
                  << std::endl;
        std::vector<Vertex> ev;
        return ev;
      }
    return add_inputs(it->second, inputs);
  }

  std::vector<Vertex> BaseGraph::add_inputs(Vertex v,
                                            std::vector<std::string> &inputs)
  {
    std::vector<Vertex> iv;
    for (std::string input : inputs)
      iv.push_back(add_input(v, input));
    return iv;
  }

  Vertex BaseGraph::add_input(std::string opname, std::string varname)
  {
    std::unordered_map<std::string, Vertex>::iterator it
        = _opIndex.find(opname);
    if (it == _opIndex.end())
      {
        std::cerr << "cannot add inputs to non existent layer " << opname
                  << std::endl;
        return LONG_MAX;
      }
    return add_input(it->second, varname);
  }

  Vertex BaseGraph::add_input(Vertex v, std::string varname)
  {
    std::unordered_map<std::string, Vertex>::iterator it
        = _varIndex.find(varname);
    Vertex varVertex;
    if (it == _varIndex.end())
      varVertex = create_var(varname);
    else
      varVertex = it->second;
    _finalized = false;
    boost::add_edge(varVertex, v, _graph);
    return varVertex;
  }

  void BaseGraph::sort_all()
  {
    if (_sorted)
      return;
    _sortedOps.clear();
    _sortedVars.clear();
    boost::topological_sort(_graph, std::back_inserter(_sortedAll));
    std::reverse(_sortedAll.begin(), _sortedAll.end());
    for (Vertex v : _sortedAll)
      {
        if (_graph[v].op)
          _sortedOps.push_back(v);
        else
          _sortedVars.push_back(v);
      }
    _sorted = true;
  }

  void BaseGraph::finalize()
  {
    if (_finalized)
      return;
    // TODO :  some sanity checks,
    // is there a path from input to ouput ?
    // check if all necessary vars are produced
    //
    sort_all();
    compute_blob_sizes();
    _finalized = true;
  }

  void BaseGraph::compute_dims_operator(Vertex op)
  {
    std::vector<std::vector<int>> inputsdims;

    std::vector<Vertex> inputs;

    auto es = boost::in_edges(op, _graph);
    for (auto eit = es.first; eit != es.second; ++eit)
      inputs.push_back(boost::source(*eit, _graph));

    for (unsigned int i = 0; i < inputs.size(); ++i)
      {
        std::vector<int> dims;
        for (int d : _graph[inputs[i]].dim)
          dims.push_back(d);
        inputsdims.push_back(dims);
      }

    std::vector<std::vector<int>> outputsdims;

    op::dispatcher::compute_outputs_dims(_graph[op], inputsdims, outputsdims);

    op::dispatcher::update_alloc_status(_graph[op], inputsdims, outputsdims);

    _graph[op].outputsdims = outputsdims;
    _graph[op].inputsdims = inputsdims;
  }

  void BaseGraph::compute_dims_var(Vertex var)
  {
    auto es = boost::in_edges(var, _graph);
    auto eit = es.first;
    Vertex producer = boost::source(*eit, _graph);

    auto ies = boost::out_edges(producer, _graph);
    unsigned int outputindex = 0;
    for (auto eit = ies.first; eit != ies.second; ++eit)
      {
        if (boost::target(*eit, _graph) == var)
          break;
        outputindex++;
      }

    _graph[var].dim = _graph[producer].outputsdims[outputindex];
  }

  void BaseGraph::compute_blob_sizes()
  {
    for (Vertex v : _sortedAll)
      {
        if (v == _input)
          continue;
        if (_graph[v].op)
          compute_dims_operator(v);
        else
          compute_dims_var(v);
      }
  }

  void BaseGraph::todot(std::ostream &out)
  {
    boost::write_graphviz(
        out, _graph,
        make_vertex_writer(boost::get(&VertexProperty::name, _graph),
                           boost::get(&VertexProperty::op, _graph),
                           boost::get(&VertexProperty::dim, _graph)));
  }

  std::vector<Vertex> BaseGraph::inputs(Vertex v)
  {
    std::vector<Vertex> inputs;
    NNGraph::in_edge_iterator eit, eend;
    auto es = boost::in_edges(v, _graph);
    for (auto eit = es.first; eit != es.second; ++eit)
      inputs.push_back(boost::source(*eit, _graph));
    return inputs;
  }

  std::vector<Vertex> BaseGraph::outputs(Vertex v)
  {
    std::vector<Vertex> outputs;
    NNGraph::out_edge_iterator eit, eend;
    auto es = boost::out_edges(v, _graph);
    for (auto eit = es.first; eit != es.second; ++eit)
      outputs.push_back(boost::target(*eit, _graph));
    return outputs;
  }

  int BaseGraph::dim(Vertex v, int num_input, int ndim)
  {
    return _graph[inputs(v)[num_input]].dim[ndim];
  }

  bool BaseGraph::allocated()
  {
    for (Vertex v : _sortedOps)
      if (_graph[v].alloc_needed)
        return false;
    return true;
  }
}

max_stars_repo_name: dgtlmoon/deepdetect

max_issues_repo_name: dgtlmoon/deepdetect

max_forks_repo_name: dgtlmoon/deepdetect


text:
// Copyright (c) 2015-2017
// Author: Chrono Law
#ifndef _NGX_LIST_HPP
#define _NGX_LIST_HPP

//#include <boost/iterator/iterator_facade.hpp>
//#include <boost/core/explicit_operator_bool.hpp>

#include "NgxPool.hpp"

template<typename T>
class NgxListIterator final :
        public boost::iterator_facade<
                    NgxListIterator<T>, T,
                    boost::single_pass_traversal_tag>
{
public:
    typedef boost::iterator_facade<
                    NgxListIterator<T>, T,
                    boost::single_pass_traversal_tag>
            super_type;
    typedef typename super_type::reference reference;
public:
    NgxListIterator(ngx_list_t* l):
        m_part(&l->part),
        m_data(static_cast<T*>(m_part->elts))
    {}

    NgxListIterator() = default;
    ~NgxListIterator() = default;
public:
    NgxListIterator(NgxListIterator const&) = default;
    NgxListIterator& operator=(const NgxListIterator&) = default;
public:
    BOOST_EXPLICIT_OPERATOR_BOOL()

    // check invalid
    bool operator!() const
    {
        return !m_part || !m_data || !m_part->nelts;
    }

private:
    friend class boost::iterator_core_access;

    reference dereference() const
    {
        NgxException::require(m_data);
        return m_data[m_count];
    }

    void increment()
    {
        if(!m_part || !m_data)
        {
            return;
        }

        ++m_count;

        if(m_count >= m_part->nelts)
        {
            m_count = 0;
            m_part = m_part->next;

            m_data = m_part?
                     static_cast<T*>(m_part->elts):
                     nullptr;
        }
    }

    bool equal(NgxListIterator const& o) const
    {
        return m_part == o.m_part &&
               m_data == o.m_data &&
               m_count == o.m_count;
    }
private:
    ngx_list_part_t* m_part = nullptr;
    T* m_data = nullptr;
    ngx_uint_t m_count = 0;
};

template<typename T>
class NgxList final : public NgxWrapper<ngx_list_t>
{
public:
    typedef NgxWrapper<ngx_list_t> super_type;
    typedef NgxList this_type;

    typedef T value_type;
public:
    NgxList(const NgxPool& p, ngx_uint_t n = 10):
        super_type(p.list<T>(n))
    {}

    NgxList(ngx_list_t* l):super_type(l)
    {}

    NgxList(ngx_list_t& l):super_type(&l)
    {}

    ~NgxList() = default;
public:
    T& prepare() const
    {
        auto tmp = ngx_list_push(get());

        NgxException::require(tmp);

        assert(tmp);
        return *reinterpret_cast<T*>(tmp);
    }

    void push(const T& x) const
    {
        prepare() = x;
    }
public:
    bool empty() const
    {
        return !get()->part->nelts;
    }

public:
    void clear() const
    {
        get()->part.nelts = 0;
        get()->part.next = nullptr;
        get()->last = &get()->part;
    }
public:
    template<typename U>
    NgxList<U> reshape(ngx_uint_t n = 0, ngx_pool_t* pool = nullptr) const
    {
        auto rc = ngx_list_init(get(),
                    pool ? pool: get()->pool,
                    n ? n : get()->nalloc,
                    sizeof(U)
                    );

        NgxException::require(rc);

        return get();
    }

    void reinit(ngx_uint_t n = 0) const
    {
        reshape<T>(n);
    }
public:
    void merge(const this_type& l) const
    {
        auto f = [this](const value_type& v)
        {
            prepare() = v;
        };

        l.visit(f);
    }
public:
    typedef NgxListIterator<T> iterator;
    typedef const iterator const_iterator;

    iterator begin() const
    {
        return iterator(get());
    }

    iterator end() const
    {
        return iterator();
    }
public:
    template<typename V>
    void visit(V v) const
    {
        auto iter = begin();
        for(; iter; ++iter)
        {
            v(*iter);
        }
    }
public:
    // use predicate to find some value
    template<typename Predicate>
    iterator find(Predicate p) const
    {
        auto iter = begin();
        for(; iter; ++iter)
        {
            if(p(*iter))
            {
                return iter;
            }
        }

        return end();
    }
};

#endif  //_NGX_LIST_HPP


text:
/*!
@file
Forward declares `boost::hana::comparing`.

@copyright Louis Dionne 2013-2016
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_HANA_FWD_COMPARING_HPP
#define BOOST_HANA_FWD_COMPARING_HPP

#include <boost/hana/config.hpp>

BOOST_HANA_NAMESPACE_BEGIN
    //! Returns a function performing `equal` after applying a transformation
    //! to both arguments.
    //! @ingroup group-Comparable
    //!
    //! `comparing` creates an equivalence relation based on the result of
    //! applying a function to some objects, which is especially useful in
    //! conjunction with algorithms that accept a custom predicate that must
    //! represent an equivalence relation.
    //!
    //! Specifically, `comparing` is such that
    //! @code
    //!     comparing(f) == equal ^on^ f
    //! @endcode
    //! or, equivalently,
    //! @code
    //!     comparing(f)(x, y) == equal(f(x), f(y))
    //! @endcode
    //!
    //! @note
    //! This is not a tag-dispatched method (hence it can't be customized),
    //! but just a convenience function provided with the `Comparable` concept.
    //!
    //!
    //! Signature
    //! ---------
    //! Given a Logical `Bool` and a Comparable `B`, the signature is
    //! @f$ \mathtt{comparing} : (A \to B) \to (A \times A \to Bool) @f$.
    //!
    //!
    //! Example
    //! -------
    //! @include example/comparing.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    constexpr auto comparing = [](auto&& f) {
        return [perfect-capture](auto&& x, auto&& y) {
            return equal(f(forwarded(x)), f(forwarded(y)));
        };
    };
#else
    struct comparing_t {
        template <typename F>
        constexpr auto operator()(F&& f) const;
    };

    constexpr comparing_t comparing{};
#endif
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_FWD_COMPARING_HPP

max_stars_repo_name: EuroLine/nheqminer


text:
#include "CorePch.h"
#include <rtp++/rfc3261/TransactionUser.h>
#include <boost/bind.hpp>

namespace rtp_plus_plus
{
namespace rfc3261
{

TransactionUser::TransactionUser(boost::asio::io_service& ioService, const SipContext& sipContext, TransportLayer& transportLayer)
  :m_ioService(ioService),
  m_sipContext(sipContext),
  m_transportLayer(transportLayer),
  m_uiLastTxId(0)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::TransactionUser";
#endif
}

TransactionUser::~TransactionUser()
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::~TransactionUser";
#endif
}

boost::system::error_code TransactionUser::beginTransaction(uint32_t& uiTxId, const SipMessage& sipMessage,
                                                            const std::string& sDestination, const uint16_t uiPort,
                                                            TransactionProtocol eProtocol)
{
  uiTxId = m_uiLastTxId++;
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::beginTransaction: " << uiTxId;
#endif
  boost::system::error_code ec;
  // create new client transaction object
  std::unique_ptr<ClientTransaction> pClientTransaction = std::unique_ptr<ClientTransaction>(
    new ClientTransaction(m_ioService, uiTxId, m_transportLayer,
    sipMessage, sDestination, uiPort, eProtocol,
    boost::bind(&TransactionUser::onClientResponseNotification, this, _1, _2, _3, _4),
    boost::bind(&TransactionUser::onTransactionTermination, this, _1),
    ec));
  if (ec)
  {
    LOG(WARNING) << "Error sending message: " << ec.message();
  }
  else
  {
    m_mClientTransactions[uiTxId] = std::move(pClientTransaction);
  }
  return ec;
}

boost::system::error_code TransactionUser::cancelTransaction(const uint32_t uiTxId)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::cancelTransaction: " << uiTxId;
#endif
  auto it = m_mClientTransactions.find(uiTxId);
  if (it == m_mClientTransactions.end())
    return boost::system::error_code(boost::system::errc::no_such_file_or_directory, boost::system::generic_category());

  boost::system::error_code ec = it->second->cancelRequest();
  if (ec)
  {
    LOG(WARNING) << "Error cancelling message: " << ec.message();
  }
  return ec;
}

boost::system::error_code TransactionUser::completeTransaction(const uint32_t uiTxId, const SipMessage& sipMessage)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::completeTransaction: " << uiTxId;
#endif
  return boost::system::error_code();
}

// THIS method can be removed?!?
void TransactionUser::onTransactionComplete()
{
//  VLOG(2) << "TransactionUser::completeTransaction: " << uiTxId;

}

boost::system::error_code TransactionUser::beginServerTransaction(uint32_t& uiTxId, const SipMessage& sipRequest, const std::string& sSource, const uint16_t uiPort, TransactionProtocol eProtocol)
{
  uiTxId = m_uiLastTxId++;
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::beginServerTransaction: " << uiTxId;
#endif
  boost::system::error_code ec;
  std::unique_ptr<ServerTransaction> pServerTransaction = std::unique_ptr<ServerTransaction>(
    new ServerTransaction(m_ioService, m_sipContext, *this, uiTxId, m_transportLayer, sipRequest, sSource, uiPort, eProtocol,
                          boost::bind(&TransactionUser::onServerTransactionNotification, this, _1, _2, _3),
                          boost::bind(&TransactionUser::onServerTransactionTermination, this, _1),
                          ec));
  m_mServerTransactions[uiTxId] = std::move(pServerTransaction);
  return ec;
}

void TransactionUser::onServerTransactionNotification(const uint32_t uiTxId, const boost::system::error_code& ec, const SipMessage& sipResponse)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::onServerTransactionNotification: " << uiTxId;
#endif
}

void TransactionUser::onServerTransactionTermination(uint32_t uiTxId)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::onServerTransactionTermination: " << uiTxId;
#endif
  // NB: by removing the unique_ptr from memory, the tx object becomes invalid!!
  m_mServerTransactions.erase(uiTxId);
}

void TransactionUser::processIncomingRequestFromTransactionLayer(const uint32_t uiTxId, const SipMessage& sipRequest, bool& bTUWillSendResponseWithin200Ms, SipMessage& sipResponse)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::processIncomingRequestFromTransactionLayer: " << uiTxId;
#endif
  // let the Transport layer handle sending a provisional response
  bTUWillSendResponseWithin200Ms = false;
  // pass on request to the
}

void TransactionUser::onTransactionTermination(uint32_t uiTxId)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::onTransactionTermination: " << uiTxId;
#endif
  // remove transaction so that further responses are forwarded directly as specified in 17.1.1.2:
  // The client transaction MUST be destroyed the instant it enters the
  // "Terminated" state.This is actually necessary to guarantee correct
  // operation.The reason is that 2xx responses to an INVITE are treated
  // differently; each one is forwarded by proxies, and the ACK handling
  // in a UAC is different.Thus, each 2xx needs to be passed to a proxy
  // core(so that it can be forwarded) and to a UAC core(so it can be
  // acknowledged).No transaction layer processing takes place.
  // Whenever a response is received by the transport, if the transport
  // layer finds no matching client transaction(using the rules of
  // Section 17.1.3), the response is passed directly to the core.Since
  // the matching client transaction is destroyed by the first 2xx,
  // subsequent 2xx will find no match and therefore be passed to the
  // core.

  // NB: by removing the unique_ptr from memory, the tx object becomes invalid!!
  m_mClientTransactions.erase(uiTxId);
}

void TransactionUser::onClientResponseNotification(const boost::system::error_code& ec, uint32_t uiTxId, const SipMessage& sipRequest, const SipMessage& sipResponse)
{
#ifdef DEBUG_TX
  VLOG(2) << "TransactionUser::onClientResponseNotification: " << uiTxId;
#endif
  if (ec)
  {
    LOG(WARNING) << "Client TX Transport error: " << ec.message();
  }
  else
  {
    VLOG(6) << "Client response: " << responseCodeString(sipResponse.getResponseCode());
    processIncomingResponse(ec, uiTxId, sipRequest, sipResponse);
  }
}

void TransactionUser::processIncomingResponse(const boost::system::error_code& ec, const uint32_t uiTxId, const SipMessage& sipRequest, const SipMessage& sipResponse)
{
  VLOG(2) << "Sub-class must implement this";
}

} // rfc3261
} // rtp_plus_plus