text:
/* Copyright (C) 2017 IBM Corp.
 * 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.
 */
/*****************************************************************************
 obfus.cpp - implementing NFA obfuscation
 *****************************************************************************/
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
#include <sys/stat.h>
#include <unistd.h>

#include <cmath>
#include "DGaussSampler.h"
#include "GGH15.h"
#include "obfus.h"
#include "CRTmatrix.h"
#include <NTL/mat_ZZ.h>
#include <NTL/mat_lzz_p.h>
#include <NTL/BasicThreadPool.h>

NTL_CLIENT

//#define PRINTDOT
#ifdef PRINTDOT
#define printDot cerr << "." << std::flush
#else
#define printDot
#endif

//#define DEBUG
//#define DEBUGPRINT

static void prepare4encoding(const NTL::Mat< NTL::Mat<long> >& trans,
			     Mat<GGH15ptxt>& mainGGH15ptxt,
			     Mat<GGH15ptxt>& dummyGGH15ptxt,
			     CRTmatrix& An, TDMatrixParams* params,
			     long nThreads);
static void encodeBranch(const std::string& dirName,
			 const Mat<GGH15ptxt>& branch,
			 CRTmatrix& An, TDMatrixParams* params,
			 SynchronizedPipe<GGH15node*>* inPipe=NULL,
			 SynchronizedPipe<encPair>* outPipe=NULL);
static void readNodesPipe(SynchronizedPipe<GGH15node*>& pipe,
			  const Mat<GGH15ptxt>& mainBranch,
			  const Mat<GGH15ptxt>& dummyBranch,
			  TDMatrixParams* params);
static void writeEncodingPipe(SynchronizedPipe<encPair>& pipe);
static GGH15node* getNode(long idx, TDMatrixParams* params);
static void evalBranch(GGH15encoding& mainPathEnc,
		       const NTL::Vec<int>& indexes,
		       const NTL::Vec<long>& symbolString,
		       TDMatrixParams* params);

// Obfuscate the given NFA and store the result in the directory 'name'
void initObfuscateNFA(const std::string& dirName,
                      const NTL::Mat< NTL::Mat<long> >& trans, long sec,
		      TDMatrixParams* params, bool bPipe, long threads)
{
    FHE_TIMER_START;

    long L = trans.NumRows(); // BP-length, # of edges
    if (L==0) return; // sanity check, nothing to do

    // compute the parameters if they are not provided by caller
    TDMatrixParams p;
    if (params==NULL)
    {
        long e = 3;
        long dim = trans[0][0].NumRows();

#ifdef DEBUG //small parameters in DEBUG mode
        long k = L;
        p.init(dim+2, k, e);

#else // "real" parameters in non-DEBUG mode
        GGH15basicParams bp(COMP_GGH15PRMS, dim, L, sec, e);
        p.init(bp.n, bp.k, bp.e, bp.m);
#endif // DEBUG

        params = &p; // pointer points to local p

	cout << "m=" << p.m << ", kFactors=" << p.kFactors
	 << ", n=" << p.n << ", e=" << p.e
	 << ", sigmaX=" << p.sigmaX << endl;
    }
    if (bPipe) {
      pipedInit(dirName, *params, 2*L, threads);
    } else {
      SetNumThreads(threads);
      initAllNodes(dirName, *params, 2*L);
    }

    // do actual obfuscation
    obfuscateNFASavedNodes(dirName, trans, params, bPipe, threads);
}

// This is called after initAllNodes, so all the nodes are already
// stored in dirName
void obfuscateNFASavedNodes(const std::string& dirName,
                            const NTL::Mat< NTL::Mat<long> >& trans,
			    TDMatrixParams* params, bool pipes, long nThreads)
{
    FHE_TIMER_START;

    cout << "obfuscating\n" << std::flush;

    char cwdOrig[1024];
    if (!getcwd(cwdOrig, sizeof(cwdOrig)))
      throw std::logic_error("Cannot get current directory");

    long ret = chdir(dirName.c_str());  // move into the new directory
    if (ret != 0) {
      cout << "   original directory was "<<cwdOrig<<endl;
      throw std::logic_error("Cannot change directory");
    }

    // Encode each tranition matrix via two encoded randomized matrices

    Mat<GGH15ptxt> mainGGH15ptxt, dummyGGH15ptxt; // main & dummy branches
    CRTmatrix An;             // The A_n matrix (actually n-by-1 "matrix")

    SetNumThreads(3); // For prepare we need 2, for encode we may need 3

    // First randomize the transition matrices and read A_n
    prepare4encoding(trans,mainGGH15ptxt,dummyGGH15ptxt,An,params,nThreads);

    //Next encode the randomized matrices, one branch at a time

    // FIXME: The piped implemtation below is fragile, relying on the reader
    // to read the nodes in exactly the right order that the worker expect
    // them. A more robust implementation would have the worker ask for a
    // node and then the reader read that node, but it is a lot more work
    // to implement this more robust solution (with pre-fetching).

    if (pipes) {
      SynchronizedPipe<GGH15node*> inPipe;
      SynchronizedPipe<encPair> outPipe;
      // "fork" three threads, reader, worker, and writer
      EXEC_INDEX(3, index)
      switch (index) {

      case 0: // The "reader thread, no multi-threading here
	readNodesPipe(inPipe,mainGGH15ptxt,dummyGGH15ptxt,params);
	inPipe.end();
	break;

      case 1: // The "worker" thread, can be multi-threaded
	SetNumThreads((nThreads>2)? (nThreads-2) : 1);
	encodeBranch(dirName, mainGGH15ptxt, An, params, &inPipe, &outPipe);
	encodeBranch(dirName, dummyGGH15ptxt, An, params,&inPipe, &outPipe);
	outPipe.end();
	{GGH15node *tmp; inPipe.receive(tmp);} // clear end-of-pipe signal
	break;

      case 2: // The "writer thread
	writeEncodingPipe(outPipe);
	break;
      }
      EXEC_INDEX_END
    }
    else { // non-piped implementation
      SetNumThreads(nThreads);
      encodeBranch(dirName, mainGGH15ptxt, An, params);
      encodeBranch(dirName, dummyGGH15ptxt, An, params);
    }
    // Restore working directory
    if (!chdir(cwdOrig)) return; // ignore this value
}

//////
//evalNFA gets a bitstring that defines the path
//////
bool evalNFA(const std::string& dirName, const Vec<long>& symbolString,
             TDMatrixParams* params, long nThreads)
{
    FHE_TIMER_START;
    long nEdges = symbolString.length();
    assert(nEdges>0); // sanity check

    char cwd[1024];
    if (!getcwd(cwd, sizeof(cwd))) // store cwd before switching
      throw std::logic_error("Cannot get current directory");
    if (chdir(dirName.c_str()) != 0)
      throw std::logic_error("Cannot change directory " + dirName);

    // read the parameters from file, if not given
    TDMatrixParams p;
    if (params==NULL)
    {
        params = &p;
        FILE* handle = fopen("params.dat", "rb");
        params->readFromFile(handle);
        fclose(handle);
    }

    // The "main" path is 0,1,3,5,...,2*nSymbols-1,
    // the "dummy" path is 0,2,4,..., 2*nSymbols-2, 2*nSymbols-1.
    // First and last nodes are the same on both paths.

    // Along each path we read the matrices that are determined by the
    // symbols in symbolString. For example if symbolString is (0,2,1,...)
    // then on the main path we read 0_1_0, 1_3_2, 3_5_1,...
    // and on the dummy path we read 0_2_0, 2_4_2, 4_6_1,...

    // Then we multiply the matrices along each path (getting two matrices
    // relative to 0-to-(2*nSymbols-1)), subtract these matrices off of each
    // other, and test if the result is a zero-encoding.

    NTL::Vec<int> realIdx(INIT_SIZE, nEdges+1);
    NTL::Vec<int> dummyIdx(INIT_SIZE, nEdges+1);
    for (long i = nEdges-1; i>=0; --i) {
      realIdx[i+1] = 2*i+1;
      dummyIdx[i+1] = (i==nEdges-1)? (2*i +1) : (2*i +2);
    }
    realIdx[0] = dummyIdx[0] = 0;

    // Multiply all matrices, from right to left. Note that rightmost
    // matrices are m-by-1, middle matrices are m-by-m, and leftmost
    // matrices are 7-by-m (?), so right-to-left product will always
    // have a products of m-by-m X m-by-1.

    GGH15encoding mainPathEnc;
    GGH15encoding dummyPathEnc;

    // No. of threads to allocate each branch
    if (nThreads>2) nThreads /= 2;
    else nThreads = 1;

    SetNumThreads(3);
    EXEC_INDEX(3, index)
    switch (index) {
    case 0: break; // Cannot multi-thread theard 0
    case 1:
      SetNumThreads(nThreads);
      evalBranch(mainPathEnc, realIdx, symbolString, params);
      break;
    case 2:
      SetNumThreads(nThreads);
      evalBranch(dummyPathEnc, dummyIdx, symbolString, params);
      break;
    }
    EXEC_INDEX_END

    // subtract and check for zero encoding
    mainPathEnc -= dummyPathEnc;

    bool success = (mainPathEnc.fromNode()==0)
      && (mainPathEnc.toNode()==2*nEdges-1)
      && mainPathEnc.getData().isSmall();

    if (chdir(cwd) != 0) { // restore working directory
      cout << "evalNFA: attempted return to "<<cwd<<endl;
      throw std::logic_error("Cannot change directory");
    }
    return success;
}

//pipedInit forks two threads, one "writer" thread and the "producer" thread, which can be further multi-threaded
bool pipedInit(const std::string& dirName, TDMatrixParams& p, long n,
	       long nThreads)
{

 FHE_TIMER_START;

  bool bsuccess=false;
  SynchronizedPipe<nodePair> pipe;

  // "fork" two thread
  SetNumThreads(2);
  EXEC_INDEX(2, index)
    switch (index) {

    case 0: // The "writer thread, no multi-threading here
      writeNodesToFile(pipe);
      break;

      // NOTE: Starting with NTL v9.10, the current thread
      // always gets assigned index == 0. This can be convenient to know:
      // the current thread's thread pool (which is thread_local) is already
      // in use; however, the other threads' thread pools are not in use.
      // Thus, if we want, the functions Process1, Process2, Process3 (below)
      // could each independently call SetNumThreads to work with their own
      // thread pools.

    case 1:
      SetNumThreads((nThreads>1)? (nThreads-1): 1);
      bsuccess=initAllNodes(dirName, p, n, &pipe);
      pipe.end();
      // The "producer" thread, can be multi-threaded
      break;
    }
  EXEC_INDEX_END

    return bsuccess;
}

// p1 includes the transition matrix and a few extra random dimensions,
// p2 includes the same random dimensions as p1 but the identity or
// part of it instead of the transition matrix
void randomizeTransitions(GGH15ptxt& p1, GGH15ptxt& p2,
                          const NTL::Mat<long>& transition,
                          long i, long j, long nSteps, long dim)
{
    FHE_TIMER_START;
    // set the to,from indexes and the tags
    p1.setFrom((i==0)? (2*i) : (2*i -1));
    p1.setTo(2*i +1);

    p2.setFrom(2*i);
    p2.setTo((i==nSteps-1)? (2*i +1) : (2*i +2));

    std::string tag = ToString(j);
    p1.setTag(tag);
    p2.setTag(tag);

    // Set the data part of the plaintext
    long extraDims = dim - transition.NumRows();  // how many extra dimensions
    mat_l& p1Data = p1.getData();
    mat_l& p2Data = p2.getData();
    p1Data.SetDims(transition.NumRows()+extraDims,
                   transition.NumCols()+extraDims);
    p2Data.SetDims(transition.NumRows()+extraDims,
                   transition.NumCols()+extraDims);
    clear(p1Data);
    clear(p2Data);

    // Copy the transition matrix to p1
    for (long ii=0; ii<transition.NumRows(); ii++)
        for (long jj=0; jj<transition.NumCols(); jj++)
            p1Data[ii][jj] = (long) transition[ii][jj];

    // Set p2 as the identity or part of it
    long smallDim = min(transition.NumRows(), transition.NumCols());
    if (i < nSteps-1) // all but the last step
        for (long ii=0; ii<smallDim/2; ii++) p2Data[ii][ii] = 1;
    if (i > 0)      // all but the first step
        for (long ii=smallDim/2; ii<smallDim; ii++) p2Data[ii][ii] = 1;

    // Choose a small random matrix and store in the extra dimensions of p1,p2
    mat_l rand;
    setSmall(rand, extraDims, extraDims, /*sigma=*/256);
    for (long ii=0; ii<extraDims; ii++) for (long jj=0; jj<extraDims; jj++)
        {
            long row = ii + transition.NumRows();
            long col = jj + transition.NumCols();
            p1Data[row][col] = p2Data[row][col] = rand[ii][jj];
        }
}

/* Function creates a new sub-directory and moves into it. it then creates
 * a binary file "params.dat", opens it and writes the values of p into it.
 * At the end, it moves back to the initial directory.
 */
long saveParamstoNewDir(const std::string& dirName, TDMatrixParams& p)
{
    FHE_TIMER_START;
#if defined(_WIN32) // Windows mkdir takes only one parameter
    int ret = mkdir(dirName.c_str());
#else               // *nix mkdir takes two parameters
    int ret = mkdir(dirName.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
#endif

    char cwdOrig[1024];
    if (!getcwd(cwdOrig, sizeof(cwdOrig)))
      throw std::logic_error("Cannot get current directory");
    ret = chdir(dirName.c_str());  // move into the new directory
    if (ret != 0) {
      cout << "saveParamstoNewDir: attempted chdir to "<<dirName<<endl;
      throw std::logic_error("Cannot change directory");
    }
    FILE* handle = fopen("params.dat", "wb"); // binary file, open for writing
    long count = p.writeToFile(handle);        // write parameters to file
    fclose(handle);

    ret = chdir(cwdOrig);
    if (ret != 0) {
      cout << "saveParamstoNewDir: attempted return to "<<cwdOrig<<endl;
      throw std::logic_error("Cannot change directory");
    }
    return count;
}

//create a random transitions file - for debug purposes,
long makeRandomBP(std::string dirName, std::string name, long dim, long sig, long L)
{
    Mat< Mat<long> > trans(INIT_SIZE, L, sig);
    for (long i=0; i<L; i++) for (long iSig=0; iSig<sig; iSig++) {
	Mat<long>& M = trans[i][iSig];
	M.SetDims(dim,dim);
	if (NTL::RandomBnd(L)==0) clear(M);
	else
	  for (long row=0; row<dim; row++) for (long col=0; col<dim; col++) {
	      M[row][col] = NTL::RandomBnd(2);
	    }
      }

    // Write the transitions matrices to file

    std::string filename = dirName + "/" + name + "_dim" + ToString(dim)
                           + "_sig" + ToString(sig) + "_L" + ToString(L)
                           + ".txt";
    std::fstream fs;
    fs.open(filename.c_str(), std::ios::out); // E.g., "BPs/P_dim2_sig2_L3.txt"
    if (!fs.is_open()) {
        char cwd[1024];
        if (getcwd(cwd, sizeof(cwd)))
          throw std::logic_error("Cannot get current directory");
        std::cout << "Cannot open input file "<< filename
		  << ", working directory=" << cwd << endl;
        exit(0);
    }
    fs << trans << endl;
    fs.close();

    return 0;
}

// Read the A_n matrix from disk and randomize transition matrices
static void prepare4encoding(const NTL::Mat< NTL::Mat<long> >& trans,
			     Mat<GGH15ptxt>& mainGGH15ptxt,
			     Mat<GGH15ptxt>& dummyGGH15ptxt,
			     CRTmatrix& An, TDMatrixParams* params,
			     long nThreads)
{
    long L = trans.NumRows(); // # of steps
    long nLoops = L*trans.NumCols();
    FILE* handle;

    mainGGH15ptxt.SetDims(L, trans.NumCols()); //main branch
    dummyGGH15ptxt.SetDims(L,trans.NumCols()); //dummy branch

    // "fork" two threads, one for reading An, one for randomizing matrices
    EXEC_INDEX(2, index)
    switch (index) {

    case 0: //read An
      handle = fopen("nAn.dat", "rb");
      if (handle == 0) NTL::Error("Cannot read An");
      else {
	long nn; // nn not used for anything
        fread(&nn, sizeof(nn),1, handle);
	An.readFromFile(handle, params);
	fclose(handle);
      }
      break;

    case 1: // randomize transition matrices, multi-threaded
      SetNumThreads((nThreads>1)? (nThreads-1) : 1);
      EXEC_RANGE(nLoops, first, last);
      for (long iLoop = first; iLoop < last; iLoop++) {

        // represent each transition matrix by two randomized matrices,
        // one on the main path and the other on the dummy path

        long j = iLoop % trans.NumCols();   //i = step, j = trans.col
        long i = (iLoop - j) / trans.NumCols();

        GGH15ptxt& p1=mainGGH15ptxt[i][j];
        GGH15ptxt& p2=dummyGGH15ptxt[i][j];

	//we chose the from and to in the following manner:
        p1.setFrom((i==0)? (2*i) : (2*i -1));
        p1.setTo(2*i +1);
        p2.setFrom(2*i);
        p2.setTo((i==L-1)? (2*i +1) : (2*i +2));
        randomizeTransitions(p1, p2, trans[i][j], i, j, L, params->n);
      } //create all ptxt matrices
      EXEC_RANGE_END
    }
    EXEC_INDEX_END
}

static void encodeBranch(const std::string& dirName,
			 const Mat<GGH15ptxt>& branch,
			 CRTmatrix& An, TDMatrixParams* params,
			 SynchronizedPipe<GGH15node*>* inPipe,
			 SynchronizedPipe<encPair>* outPipe)
{
    assert(branch.NumRows()>0 && branch.NumCols()>0);

    GGH15node *toNode=NULL, *fromNode=NULL;
    TaggedCRTmatrix mat1;
    GGH15encoding* enc;

    long lastNode = branch[branch.NumRows()-1][0].getTo();
    for (long i=0; i<branch.NumRows(); i++) {
      long from = branch[i][0].getFrom();
      long to = branch[i][0].getTo();

      // Read from disk the next node that's needed for this step
      if (to >= lastNode) toNode =NULL; // no toNode for last-step encoding
      else if (inPipe != NULL)
        assert(inPipe->receive(toNode));// get node from pipe, failure forbidden
      else
        toNode = getNode(to, params);   // read it yourself

      // Encode all matrices wrt from -> to, one per alphabet symbol
      for (long j=0; j<branch.NumCols(); j++) {
	enc = new(GGH15encoding);
	encodeMatrix(dirName, *enc, branch[i][j].getData(), from, to,
                     fromNode, toNode, An, &mat1, params, lastNode+1);
	// When from==0, encodeMatrix does not use the pointer fromNode

	// Write the encoded matrices to disk
	std::string FileName = ToString(from)+"_"+ToString(to)+"_"
                               + branch[i][j].getTag()+".dat";
	FILE* handle = fopen((const char*)FileName.c_str(), "wb");
	if (handle==0) NTL::Error("Cannot write encoding to disk");

	if (outPipe!=NULL) { // Send matrix over pipe to be written
	  encPair ePair(handle,enc);
	  outPipe->send(ePair);
	} else {             // write it yourself
	  enc->writeToFile(handle);
	  fclose(handle);
	  delete enc;
	}
      }
      if (fromNode!=NULL) delete fromNode;
      fromNode = toNode;
    }
}

static void readNodesPipe(SynchronizedPipe<GGH15node*>& pipe,
			  const Mat<GGH15ptxt>& mainBranch,
			  const Mat<GGH15ptxt>& dummyBranch,
			  TDMatrixParams* params)
{
  GGH15node *node;
  // First read the nodes on the main branch in order
  long lastNode = mainBranch[mainBranch.NumRows()-1][0].getTo();
  for (long i=0; i<mainBranch.NumRows(); i++) {
    long to = mainBranch[i][0].getTo();
    if (to >= lastNode) break;
    node = getNode(to, params);
    pipe.send(node);
  }
  // Next read the nodes on the dummy branch in order
  lastNode = dummyBranch[mainBranch.NumRows()-1][0].getTo();
  for (long i=0; i<dummyBranch.NumRows(); i++) {
    long to = dummyBranch[i][0].getTo();
    if (to >= lastNode) break;
    node = getNode(to, params);
    pipe.send(node);
  }
}

static void writeEncodingPipe(SynchronizedPipe<encPair>& pipe)
{
  GGH15encoding* enc;
  FILE* handle;
  encPair ePair;

  while (true) {
    if (!pipe.receive(ePair)) break;
    handle = ePair.a;
    enc = ePair.b;
    enc->writeToFile(handle);
    delete(enc);
    fclose(handle);
  }
}

static GGH15node* getNode(long idx, TDMatrixParams* params)
{
  std::string fileName = "node"+ToString(idx)+ ".dat";
  FILE* handle = fopen(fileName.c_str(), "rb");
  if (handle==0) NTL::Error("Cannot open node file on disk");
  GGH15node* node = new GGH15node();
  node->readFromFile(handle, params);
  fclose(handle);
  return node;
}

static void evalBranch(GGH15encoding& mainPathEnc,
		       const NTL::Vec<int>& indexes,
		       const NTL::Vec<long>& symbolString,
		       TDMatrixParams* params)
{
  long nEdges = indexes.length()-1;
  for (long i = nEdges-1; i>=0; --i) {
    GGH15encoding cc;

    long from1 = indexes[i];
    long to1   = indexes[i+1];
    std::string fName1 = ToString(from1) + "_"
      + ToString(to1) + "_" + ToString(symbolString[i]) + ".dat";

    // read encodings from files and multiply into the path encodings

    FILE* handle = fopen(fName1.c_str(), "rb");
    if (handle == NULL) // error
      throw std::logic_error("Cannot open file " + fName1);

    if (i == nEdges-1) // read directly to mainPathEnc
      mainPathEnc.readFromFile(handle, *params);
    else {       // multiply into mainPathEnc
      cc.readFromFile(handle, *params);
      mainPathEnc.leftMultBy(cc);
    }
    fclose(handle);
  }
}

max_stars_repo_name: shaih/BPobfus

max_issues_repo_name: shaih/BPobfus

max_forks_repo_name: shaih/BPobfus


text:
#ifndef __AC_HPP__
#define __AC_HPP__

/***************************************************************
      Author: Joel Veness
        Date: 2011
        Info: A binary arithmetic decoder/encoder.

        Thanks to the Arithmetic Coding Library by
        Fred Wheeler (2000) for inspiration, and also to
        the accompanying source code provided with the article
        "Arithmetic Coding for Data Compression", by
        Witten et al.
*****************************************************************/

#include <fstream>
#include <iostream>

#include <boost/cstdint.hpp>

// fixed size types
typedef boost::uint32_t uint32_t;
typedef boost::uint64_t uint64_t;
typedef boost::int8_t int8_t;

// binary arithemtic encoder
class BinaryArithmeticEncoder {

    public:

        // opens a new encoder that outputs to filename
        BinaryArithmeticEncoder(const std::string &filename);

        // send a bit to the encoder and the probability of it being a 1
        void encode(int bit, double pr_one);

        // finalise the encoding process
        void close();

    private:

        // write the next bit, being careful to record previous middle subdivisions
        void bit_plus_follow(int bit);

        // writes a bit to the internal buffer
        void write(uint32_t bit);

        // flushes the internal buffer to file
        void flush();

        std::ofstream m_ofs;

        uint64_t m_low;
        uint64_t m_high;
        uint64_t m_fbits;

        char m_buffer;
        char m_upto;
        uint32_t m_size;
};

// binary arithmetic decoder
class BinaryArithmeticDecoder {

    public:

        // opens a new decoder that can read bits from a file
        BinaryArithmeticDecoder(const std::string &filename);

        // read a new bit
        int decode(double pr_one);

        // size of decompressed file
        uint32_t size() const { return m_size; }

        // finalise the decoding process
        void close();

    private:

        uint32_t readBit();

        std::ifstream m_ifs;

        uint64_t m_low;
        uint64_t m_high;
        uint64_t m_value;

        uint32_t m_size;

        int8_t m_bits_left;
        int8_t m_buffer;
};

#endif // __AC_HPP__

ext: hpp

max_stars_repo_name: mgbellemare/SkipCTS

max_issues_repo_name: GitHubBeinner/SkipCTS

max_forks_repo_name: GitHubBeinner/SkipCTS


text:
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <regex>
#include <fstream>
#include <boost/algorithm/string.hpp>

#include "../common.hpp"

using namespace std;

// search updates `found` to contain all the bags that can directly or indirectly contain the target.
// bags assumes a child->parent maping.
void search(set<string> * found, const map<string, map<string, int>> & bags, string target) {
    // Bag doesn't exist :/
    if (bags.find(target) == bags.end()) {
        return;
    }

    for (auto const& [parent, count] : bags.at(target)) {
        if (found->find(parent) != found->end()) {
            continue;
        }

        found->insert(parent);
        search(found, bags, parent);
    }
}

// search2 returns the count of bags within the target bag.
// bags assumes a parent->child mapping.
int search2(const map<string, map<string, int>> & bags, string target) {
    // Bag doesn't exist, so assume it contains nothing.
    if (bags.find(target) == bags.end()) {
        return 1;
    }

    int answer = 1;
    for (auto const& [child, count] : bags.at(target)) {
        answer += count * search2(bags, child);
    }

    return answer;
}

int main() {
    ifstream file ("2020/7.txt");
    if (!file.is_open()) {
        cout << "Failed to open file: " << strerror(errno) << endl;
        return -1;
    }

    int answer1 = 0;
    int answer2 = 0;

    map<string, map<string, int>> bags;
    map<string, map<string, int>> bags2;

    string line;
    while (getline(file, line, '\n')) {
        boost::trim(line);

        if (line == "") {
            continue;
        }

        smatch matches;
        regex e1 ("(.+) bags contain");
        assert(regex_search(line, matches, e1));

        string parent = matches[1];

        std::regex e2("(\\d+) (.+?) bag");
        auto bags_begin = std::sregex_iterator(line.begin(), line.end(), e2);
        auto bags_end = std::sregex_iterator();

        for (std::sregex_iterator i = bags_begin; i != bags_end; ++i) {
            smatch match = *i;
            int count = stoi(match[1]);
            string child = match[2];

            bags[child][parent] = count;
            bags2[parent][child] = count;
        }
    }

    set<string> found;
    search(&found, bags, "shiny gold");

    answer1 = found.size();
    cout << "Answer 7.1: " << answer1 << endl;

    answer2 = search2(bags2, "shiny gold") - 1;
    cout << "Answer 7.2: " << answer2 << endl;

    file.close();
}

ext: cpp

max_stars_repo_name: bramp/aoc

max_issues_repo_name: bramp/aoc

max_forks_repo_name: bramp/aoc


text:
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/CXX11/Tensor>

using Eigen::Tensor;
using Eigen::TensorMap;

static void test_assign()
{
  std::string data1[6];
  TensorMap<Tensor<std::string, 2>> mat1(data1, 2, 3);
  std::string data2[6];
  const TensorMap<Tensor<const std::string, 2>> mat2(data2, 2, 3);

  for (int i = 0; i < 6; ++i) {
    std::ostringstream s1;
    s1 << "abc" << i*3;
    data1[i] = s1.str();
    std::ostringstream s2;
    s2 << "def" << i*5;
    data2[i] = s2.str();
  }

  Tensor<std::string, 2> rslt1;
  rslt1 = mat1;
  Tensor<std::string, 2> rslt2;
  rslt2 = mat2;

  Tensor<std::string, 2> rslt3 = mat1;
  Tensor<std::string, 2> rslt4 = mat2;

  Tensor<std::string, 2> rslt5(mat1);
  Tensor<std::string, 2> rslt6(mat2);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      VERIFY_IS_EQUAL(rslt1(i,j), data1[i+2*j]);
      VERIFY_IS_EQUAL(rslt2(i,j), data2[i+2*j]);
      VERIFY_IS_EQUAL(rslt3(i,j), data1[i+2*j]);
      VERIFY_IS_EQUAL(rslt4(i,j), data2[i+2*j]);
      VERIFY_IS_EQUAL(rslt5(i,j), data1[i+2*j]);
      VERIFY_IS_EQUAL(rslt6(i,j), data2[i+2*j]);
    }
  }
}

static void test_concat()
{
  Tensor<std::string, 2> t1(2, 3);
  Tensor<std::string, 2> t2(2, 3);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      std::ostringstream s1;
      s1 << "abc" << i + j*2;
      t1(i, j) = s1.str();
      std::ostringstream s2;
      s2 << "def" << i*5 + j*32;
      t2(i, j) = s2.str();
    }
  }

  Tensor<std::string, 2> result = t1.concatenate(t2, 1);
  VERIFY_IS_EQUAL(result.dimension(0), 2);
  VERIFY_IS_EQUAL(result.dimension(1), 6);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      VERIFY_IS_EQUAL(result(i, j),   t1(i, j));
      VERIFY_IS_EQUAL(result(i, j+3), t2(i, j));
    }
  }
}

static void test_slices()
{
  Tensor<std::string, 2> data(2, 6);
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      std::ostringstream s1;
      s1 << "abc" << i + j*2;
      data(i, j) = s1.str();
    }
  }

  const Eigen::DSizes<ptrdiff_t, 2> half_size(2, 3);
  const Eigen::DSizes<ptrdiff_t, 2> first_half(0, 0);
  const Eigen::DSizes<ptrdiff_t, 2> second_half(0, 3);

  Tensor<std::string, 2> t1 = data.slice(first_half, half_size);
  Tensor<std::string, 2> t2 = data.slice(second_half, half_size);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      VERIFY_IS_EQUAL(data(i, j),   t1(i, j));
      VERIFY_IS_EQUAL(data(i, j+3), t2(i, j));
    }
  }
}

static void test_additions()
{
  Tensor<std::string, 1> data1(3);
  Tensor<std::string, 1> data2(3);
  for (int i = 0; i < 3; ++i) {
    data1(i) = "abc";
    std::ostringstream s1;
    s1 << i;
    data2(i) = s1.str();
  }

  Tensor<std::string, 1> sum = data1 + data2;
  for (int i = 0; i < 3; ++i) {
    std::ostringstream concat;
    concat << "abc" << i;
    std::string expected = concat.str();
    VERIFY_IS_EQUAL(sum(i), expected);
  }
}

static void test_initialization()
{
  Tensor<std::string, 2> a(2, 3);
  a.setConstant(std::string("foo"));
  for (int i = 0; i < 2*3; ++i) {
    VERIFY_IS_EQUAL(a(i), std::string("foo"));
  }
}

void test_cxx11_tensor_of_strings()
{
  // Beware: none of this is likely to ever work on a GPU.
  CALL_SUBTEST(test_assign());
  CALL_SUBTEST(test_concat());
  CALL_SUBTEST(test_slices());
  CALL_SUBTEST(test_additions());
  CALL_SUBTEST(test_initialization());
}


text:
/**
 * Copyright (c) 2015-2019 Przemysław Dobrowolski
 *
 * This file is part of the Configuration Space Library (libcs2), a library
 * for creating configuration spaces of various motion planning problems.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "renderview.h"
#include "renderviewarcballcamera.h"
#include "renderviewflycamera.h"
#include "renderviewautocamera.h"
#include "test/testpredg3f.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QTextStream>
#include <QFile>
#include <QImage>
#include <boost/scoped_array.hpp>
#include <cassert>
#include <cmath>

const QColor salemColor(9, 127, 75);
const QColor redBerryColor(142, 0, 0);
const QColor darkOrangeColor(255, 140, 0);

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    m_blockPredicateUpdate(false),
    m_currentChanged(false),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // setup
    if (true)
    {
        QGLFormat fmt;
        fmt.setSamples(4);
        fmt.setSampleBuffers(true);
        QGLFormat::setDefaultFormat(fmt);
    }

    m_rv = new RenderView();

    m_rv->setCaption("cspace");
    m_rv->enableViewModeOption(ViewMode::Culling);

    ui->widgetView->layout()->addWidget(m_rv);

    // update predicate predicate
    updatePredicateInformation();

    // window title
    updateWindowTitle();

    // force no-changes
    m_currentChanged = false;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::updatePredicateInformation()
{
    if (m_blockPredicateUpdate)
        return;

    // changed
    m_currentChanged = true;
    updateWindowTitle();

    // predicate g
    struct cs2_predg3f_s pred =
        {
            { ui->doubleSpinBoxKX->value(), ui->doubleSpinBoxKY->value(), ui->doubleSpinBoxKZ->value() },
            { ui->doubleSpinBoxLX->value(), ui->doubleSpinBoxLY->value(), ui->doubleSpinBoxLZ->value() },
            { ui->doubleSpinBoxAX->value(), ui->doubleSpinBoxAY->value(), ui->doubleSpinBoxAZ->value() },
            { ui->doubleSpinBoxBX->value(), ui->doubleSpinBoxBY->value(), ui->doubleSpinBoxBZ->value() },
            ui->doubleSpinBoxC->value()
        };

    // param g
    struct cs2_predgparam3f_s param;
    cs2_predg3f_param(&param, &pred);

    double a = param.a;
    double b = param.b;
    double c = param.c;

    double mi = std::min(a - b, b - a);
    double ma = std::max(a - b, b - a);

    // information -> parameters
    ui->labelKval->setText(formatVector(&pred.k));
    ui->labelLval->setText(formatVector(&pred.l));
    ui->labelAval->setText(formatVector(&pred.a));
    ui->labelBval->setText(formatVector(&pred.b));
    ui->labelCval->setText(QString::number(c, 'f', 2));

    // information -> base variables
    struct cs2_vec3f_s p, q, u, v;
    cs2_predg3f_pquv(&p, &q, &u, &v, &pred);

    ui->labelPval->setText(formatVector(&p));
    ui->labelQval->setText(formatVector(&q));
    ui->labelUval->setText(formatVector(&u));
    ui->labelVval->setText(formatVector(&v));
    ui->labelC2val->setText(QString::number(c, 'f', 2));

    // information -> type
    enum cs2_predgtype3f_e type = cs2_predg3f_type(&pred);

    ui->labelproperval->setText(type == cs2_predgtype3f_improper ? "no" : "yes");
    ui->labeltypeval->setText(cs2_predgtype3f_str(type));

    // information -> parametrization variables
    ui->labelaval->setText(QString::number(a, 'f', 4));
    ui->labelbval->setText(QString::number(b, 'f', 4));
    ui->labelcval->setText(QString::number(c, 'f', 4));
    ui->labelminval->setText(QString::number(mi, 'f', 4));
    ui->labelmaxval->setText(QString::number(ma, 'f', 4));

    ui->labelcaseval->setText(cs2_predgparamtype3f_str(param.t));
    ui->labeldimval->setText(QString::number(cs2_predgparamtype3f_dim(param.t)));
    ui->labelcompval->setText(QString::number(cs2_predgparamtype3f_domain_components(param.t)));
    ui->labelismanival->setText(cs2_predgparamtype3f_is_manifold(param.t) ? "yes" : "no");
    ui->labelhasholeval->setText(cs2_predgparamtype3f_has_domain_hole(param.t) ? "yes" : "no");
    ui->labelisconnval->setText(cs2_predgparamtype3f_is_connected(param.t) ? "yes" : "no");

    // information -> eigen decomposition
    ui->labeldetval->setText(QString::number(param.e[0] * param.e[1] * param.e[2] * param.e[3], 'f', 8));

    ui->labell1val->setText(QString::number(param.e[0], 'f', 4));
    ui->labell2val->setText(QString::number(param.e[1], 'f', 4));
    ui->labell3val->setText(QString::number(param.e[2], 'f', 4));
    ui->labell4val->setText(QString::number(param.e[3], 'f', 4));

    ui->labelw1val->setText(formatVector(&param.ev[0]));
    ui->labelw2val->setText(formatVector(&param.ev[1]));
    ui->labelw3val->setText(formatVector(&param.ev[2]));
    ui->labelw4val->setText(formatVector(&param.ev[3]));

    // visual
    m_rv->removeAllObjects();

    switch (cs2_predgparamtype3f_dim(param.t))
    {
        case 1: // 1-dimensional
            {
                LineListPtr lines(new LineList());

                meshing::meshCurveSimple(lines, &param, 0.01);

                m_rv->addLineList(lines, darkOrangeColor);
            }
            break;

        case 2: // 2-dimensional
            {
                TriangleListPtr trianglesFront(new TriangleList());
                TriangleListPtr trianglesBack(new TriangleList());

                if (ui->actionAutoMesh->isChecked())
                    meshing::meshSurfaceAdaptive(trianglesFront, trianglesBack, &param, 0.1, 0.5, 10);
                else
                    meshing::meshSurfaceSimple(trianglesFront, trianglesBack, &param, 0.01);

                m_rv->addTriangleList(trianglesFront, salemColor);
                m_rv->addTriangleList(trianglesBack, redBerryColor);
            }
            break;
    }
}

void MainWindow::setPredicate(double kx, double ky, double kz, double lx, double ly, double lz, double ax, double ay, double az, double bx, double by, double bz, double c)
{
    m_blockPredicateUpdate = true;

    ui->doubleSpinBoxKX->setValue(kx);
    ui->doubleSpinBoxKY->setValue(ky);
    ui->doubleSpinBoxKZ->setValue(kz);

    ui->doubleSpinBoxLX->setValue(lx);
    ui->doubleSpinBoxLY->setValue(ly);
    ui->doubleSpinBoxLZ->setValue(lz);

    ui->doubleSpinBoxAX->setValue(ax);
    ui->doubleSpinBoxAY->setValue(ay);
    ui->doubleSpinBoxAZ->setValue(az);

    ui->doubleSpinBoxBX->setValue(bx);
    ui->doubleSpinBoxBY->setValue(by);
    ui->doubleSpinBoxBZ->setValue(bz);

    ui->doubleSpinBoxC->setValue(c);

    m_blockPredicateUpdate = false;

    updatePredicateInformation();
}

void MainWindow::setPredicate(const cs2_predg3f_s *p)
{
    setPredicate(p->k.x, p->k.y, p->k.z,
                 p->l.x, p->l.y, p->l.z,
                 p->a.x, p->a.y, p->a.z,
                 p->b.x, p->b.y, p->b.z,
                 p->c);
}

QString MainWindow::formatVector(const struct cs2_vec3f_s *v)
{
    return "[" + QString::number(v->x, 'f', 2) + ", " + QString::number(v->y, 'f', 2) + ", " + QString::number(v->z, 'f', 2) + "]";
}

QString MainWindow::formatVector(const struct cs2_vec4f_s *v)
{
    return "[" + QString::number(v->x, 'f', 2) + ", " + QString::number(v->y, 'f', 2) + ", " + QString::number(v->z, 'f', 2) + ", " + QString::number(v->w, 'f', 2) + "]";
}

bool MainWindow::handleUnsavedChanges()
{
    switch (QMessageBox::question(this, tr("Unsaved changes"), tr("Save changes to file?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel))
    {
        case QMessageBox::Yes:
            if (!m_currentFile.isEmpty())
                return saveCurrentFile();
            else
                return saveNewFile();

        case QMessageBox::No:
            return true;

        case QMessageBox::Cancel:
            return false;

    default:
        assert(0);
    }
}

bool MainWindow::saveCurrentFile()
{
    // changes
    m_currentChanged = false;
    updateWindowTitle();

    // save
    QFile out(m_currentFile);

    if (out.open(QFile::WriteOnly))
    {
        //writer
        {
            QTextStream stream(&out);

            stream << ui->doubleSpinBoxKX->value() << " ";
            stream << ui->doubleSpinBoxKY->value() << " ";
            stream << ui->doubleSpinBoxKZ->value();
            stream << "\r\n";
            stream << ui->doubleSpinBoxLX->value() << " ";
            stream << ui->doubleSpinBoxLY->value() << " ";
            stream << ui->doubleSpinBoxLZ->value();
            stream << "\r\n";
            stream << ui->doubleSpinBoxAX->value() << " ";
            stream << ui->doubleSpinBoxAY->value() << " ";
            stream << ui->doubleSpinBoxAZ->value();
            stream << "\r\n";
            stream << ui->doubleSpinBoxBX->value() << " ";
            stream << ui->doubleSpinBoxBY->value() << " ";
            stream << ui->doubleSpinBoxBZ->value();
            stream << "\r\n";
            stream << ui->doubleSpinBoxC->value();
            stream << "\r\n";
        }

        out.close();
    }
    else
    {
        (void)QMessageBox::warning(this, tr("Save file"), tr("Failed to write: ") + m_currentFile, QMessageBox::Ok);
        return false;
    }

    return true;
}

bool MainWindow::saveNewFile()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), QString(), QString("*.vis"));

    if (fileName.isEmpty())
        return false;

    if (!fileName.endsWith(".vis"))
        fileName += ".vis";

    m_currentFile = fileName;
    return saveCurrentFile();
}

void MainWindow::updateWindowTitle()
{
    QString fileName;

    if (m_currentFile.isEmpty())
        fileName = "unnamed.vis";
    else
    {
        QFileInfo fileInfo(m_currentFile);
        fileName = fileInfo.fileName();
    }

    setWindowTitle(fileName + ": vis" + (m_currentChanged ? " *" : ""));
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (!m_currentChanged)
        return;

    if (!handleUnsavedChanges())
    {
        event->ignore();
        return;
    }
}

void MainWindow::on_actionArcballCamera_triggered()
{
    m_rv->setRenderViewCamera(new RenderViewArcBallCamera());

    ui->actionArcballCamera->setChecked(true);
    ui->actionFreeCamera->setChecked(false);
    ui->actionAutoCamera->setChecked(false);
}

void MainWindow::on_actionFreeCamera_triggered()
{
    m_rv->setRenderViewCamera(new RenderViewFlyCamera());

    ui->actionArcballCamera->setChecked(false);
    ui->actionFreeCamera->setChecked(true);
    ui->actionAutoCamera->setChecked(false);
}

void MainWindow::on_actionAutoCamera_triggered()
{
    m_rv->setRenderViewCamera(new RenderViewAutoCamera());

    ui->actionArcballCamera->setChecked(false);
    ui->actionFreeCamera->setChecked(false);
    ui->actionAutoCamera->setChecked(true);
}

void MainWindow::on_doubleSpinBoxKX_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxKY_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxKZ_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxLX_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxLY_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxLZ_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxAX_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxAY_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxAZ_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxBX_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxBY_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxBZ_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_doubleSpinBoxC_valueChanged(double)
{
    updatePredicateInformation();
}

void MainWindow::on_labelZeroK_linkActivated(const QString &link)
{
    Q_UNUSED(link)

    ui->doubleSpinBoxKX->setValue(0);
    ui->doubleSpinBoxKY->setValue(0);
    ui->doubleSpinBoxKZ->setValue(0);
}

void MainWindow::on_labelZeroL_linkActivated(const QString &link)
{
    Q_UNUSED(link)

    ui->doubleSpinBoxLX->setValue(0);
    ui->doubleSpinBoxLY->setValue(0);
    ui->doubleSpinBoxLZ->setValue(0);
}

void MainWindow::on_labelZeroA_linkActivated(const QString &link)
{
    Q_UNUSED(link)

    ui->doubleSpinBoxAX->setValue(0);
    ui->doubleSpinBoxAY->setValue(0);
    ui->doubleSpinBoxAZ->setValue(0);
}

void MainWindow::on_labelZeroB_linkActivated(const QString &link)
{
    Q_UNUSED(link)

    ui->doubleSpinBoxBX->setValue(0);
    ui->doubleSpinBoxBY->setValue(0);
    ui->doubleSpinBoxBZ->setValue(0);
}

void MainWindow::on_labelZeroC_linkActivated(const QString &link)
{
    Q_UNUSED(link)

    ui->doubleSpinBoxC->setValue(0);
}

void MainWindow::on_actionWireframe_triggered()
{
    m_rv->setViewModeOption(ViewMode::Wireframe, ui->actionWireframe->isChecked());
}

void MainWindow::on_actionQuit_triggered()
{
    if (!m_currentChanged)
    {
        emit close();
        return;
    }

    if (!handleUnsavedChanges())
        return;

    emit close();
}

void MainWindow::on_actionOpen_triggered()
{
    if (m_currentChanged && !handleUnsavedChanges())
        return;

    QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"), QString(), tr("*.vis"));

    if (fileName.isEmpty())
        return;

    QFile file(fileName);

    if (file.open(QFile::ReadOnly))
    {
        // reader
        {
            QTextStream stream(&file);

            int kx, ky, kz;
            stream >> kx >> ky >> kz;

            int lx, ly, lz;
            stream >> lx >> ly >> lz;

            int ax, ay, az;
            stream >> ax >> ay >> az;

            int bx, by, bz;
            stream >> bx >> by >> bz;

            int c;
            stream >> c;

            if (stream.status() != QTextStream::Ok)
            {
                (void)QMessageBox::warning(this, tr("Open file"), tr("Failed to parse: ") + m_currentFile, QMessageBox::Ok);
                return;
            }

            ui->doubleSpinBoxKX->setValue(kx);
            ui->doubleSpinBoxKY->setValue(ky);
            ui->doubleSpinBoxKZ->setValue(kz);

            ui->doubleSpinBoxLX->setValue(lx);
            ui->doubleSpinBoxLY->setValue(ly);
            ui->doubleSpinBoxLZ->setValue(lz);

            ui->doubleSpinBoxAX->setValue(ax);
            ui->doubleSpinBoxAY->setValue(ay);
            ui->doubleSpinBoxAZ->setValue(az);

            ui->doubleSpinBoxBX->setValue(bx);
            ui->doubleSpinBoxBY->setValue(by);
            ui->doubleSpinBoxBZ->setValue(bz);

            ui->doubleSpinBoxC->setValue(c);
        }

        file.close();
    }
    else
    {
        (void)QMessageBox::warning(this, tr("Open file"), tr("Failed to open: ") + m_currentFile, QMessageBox::Ok);
        return;
    }

    m_currentFile = fileName;
    m_currentChanged = false;
    updateWindowTitle();
}

void MainWindow::on_actionSave_triggered()
{
    if (m_currentChanged)
    {
        if (!m_currentFile.isEmpty())
            (void)saveCurrentFile();
        else
            (void)saveNewFile();
    }
}

void MainWindow::on_actionSaveAs_triggered()
{
    (void)saveNewFile();
}

void MainWindow::on_actionAutoMesh_triggered()
{
    updatePredicateInformation();
}

void MainWindow::on_actionTakeScreenshot_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save current frame buffer as"), QString(), QString("*.png"));

    if (fileName.isEmpty())
        return;

    if (!fileName.endsWith(".png"))
        fileName += ".png";

    QImage img = m_rv->grabFrameBuffer();

    if (!img.save(fileName, nullptr, 100))
    {
        (void)QMessageBox::warning(this, tr("Save current frame buffer file"), tr("Failed to save frame buffer"), QMessageBox::Ok);
        return;
    }
}

void MainWindow::on_actionModelOnlyView_triggered()
{
    m_rv->setViewModeOption(ViewMode::ModelOnly, ui->actionModelOnlyView->isChecked());
}

void MainWindow::on_actionOutlines_triggered()
{
    m_rv->setViewModeOption(ViewMode::Outlines, ui->actionOutlines->isChecked());
}

void MainWindow::on_actionNormals_triggered()
{
    m_rv->setViewModeOption(ViewMode::Normals, ui->actionNormals->isChecked());
}

void MainWindow::on_actionA_pair_of_points_triggered()
{
    setPredicate(&test_predg3f_a_pair_of_points);
}

void MainWindow::on_actionA_pair_of_separate_ellipsoids_triggered()
{
    setPredicate(&test_predg3f_a_pair_of_separate_ellipsoids);
}

void MainWindow::on_actionA_pair_of_y_touching_ellipsoids_triggered()
{
    setPredicate(&test_predg3f_a_pair_of_y_touching_ellipsoids);
}

void MainWindow::on_actionA_pair_of_yz_crossed_ellipsoids_triggered()
{
    setPredicate(&test_predg3f_a_pair_of_yz_crossed_ellipsoids);
}

void MainWindow::on_actionA_pair_of_z_touching_ellipsoids_triggered()
{
    setPredicate(&test_predg3f_a_pair_of_z_touching_ellipsoids);
}

void MainWindow::on_actionA_y_barrel_triggered()
{
    setPredicate(&test_predg3f_a_y_barrel);
}

void MainWindow::on_actionA_z_barrel_triggered()
{
    setPredicate(&test_predg3f_a_z_barrel);
}

void MainWindow::on_actionA_notched_y_barrel_triggered()
{
    setPredicate(&test_predg3f_a_notched_y_barrel);
}

void MainWindow::on_actionA_notched_z_barrel_triggered()
{
    setPredicate(&test_predg3f_a_notched_z_barrel);
}

void MainWindow::on_actionA_pair_of_separate_yz_caps_triggered()
{
    setPredicate(&test_predg3f_a_pair_of_separate_yz_caps);
}

void MainWindow::on_actionA_xy_zw_torus_triggered()
{
    setPredicate(&test_predg3f_a_xy_zw_torus);
}

void MainWindow::on_actionA_xy_circle_triggered()
{
    setPredicate(&test_predg3f_a_xy_circle);
}

void MainWindow::on_actionA_zw_circle_triggered()
{
    setPredicate(&test_predg3f_a_zw_circle);
}

void MainWindow::on_actionA_xz_yw_torus_triggered()
{
    setPredicate(&test_predg3f_a_xz_yw_torus);
}

void MainWindow::on_actionA_xz_circle_triggered()
{
    setPredicate(&test_predg3f_a_xz_circle);
}

void MainWindow::on_actionA_yw_circle_triggered()
{
    setPredicate(&test_predg3f_a_yw_circle);
}


text:
#ifndef ISOLATOR_GC_HPP
#define ISOLATOR_GC_HPP

#include <vector>
#include <boost/thread.hpp>

#include "transcripts.hpp"
#include "loess/loess.h"

class GCCorrection
{
    public:
        GCCorrection(TranscriptSet& ts, const double* transcript_gc);
        ~GCCorrection();

        void correct(double* expr);
        void adjustments(const double* expr, double* weights);

    private:
        TranscriptSet& ts;

        const double* transcript_gc;

        // number of entrie (tgroups) in xs, ys
        size_t n;

        // work vectors for computing gene expression and weighted gc content
        std::vector<double> gene_expr, gene_gc;

        // input: weighted gc content
        std::vector<double> xs;

        // response: log tgroup expression
        std::vector<double> ys;

        // transcript gc
        std::vector<double> tgc;

        // loess predictions
        std::vector<double> fit, se_fit;

        loess_struct lo;
        pred_struct pre;

        // the netlib loess code is not thread safe so we need to
        // use a global lock.
        static boost::mutex mut;
};

#endif

max_stars_repo_name: dcjones/isolator

max_issues_repo_name: dcjones/isolator

max_forks_repo_name: dcjones/isolator


text:
/*
 * Copyright 2015 Applied Research Center for Computer Networks
 *
 * 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 "STP.hh"

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>

#include "Topology.hh"
#include "Controller.hh"
#include "SwitchConnection.hh"
#include "Maple.hh"
REGISTER_APPLICATION(STP, {"controller", "switch-manager", "link-discovery", "topology", ""})

enum {
    FLOOD_GROUP = 0xf100d
};

void SwitchSTP::resetBroadcast()
{
    for (auto port : ports) {
        if (port.second->to_switch)
            unsetBroadcast(port.second->port_no);
    }
}

STPPorts SwitchSTP::getEnabledPorts()
{
    STPPorts result;

    for (auto port : ports) {
        if (port.second->broadcast)
            result.push_back(port.second->port_no);
    }
    return result;
}

void SwitchSTP::updateGroup()
{
    of13::GroupMod gm;
    gm.commmand(of13::OFPGC_MODIFY);
    gm.group_type(of13::OFPGT_ALL);
    gm.group_id(FLOOD_GROUP);
    STPPorts ports = getEnabledPorts();
    for (auto port : ports) {
        of13::Bucket b;
        b.watch_port(of13::OFPP_ANY);
        b.watch_group(of13::OFPG_ANY);
        //b.weight(0);
        b.add_action(new of13::OutputAction(port, 0));
        gm.add_bucket(b);
    }
    DVLOG(20) << "Update group in switch" << sw->id();
    sw->connection()->send(gm);
}

void SwitchSTP::clearGroup()
{
    if (sw){
        of13::GroupMod gm;
        gm.commmand(of13::OFPGC_DELETE);
        gm.group_type(of13::OFPGT_ALL);
        gm.group_id(FLOOD_GROUP);
        DVLOG(20) << "Clear group in switch " <<  sw->id();
        sw->connection()->send(gm);
    }
}

void SwitchSTP::installGroup()
{
    of13::GroupMod gm;
    gm.commmand(of13::OFPGC_ADD);
    gm.group_type(of13::OFPGT_ALL);
    gm.group_id(FLOOD_GROUP);
    STPPorts ports = getEnabledPorts();
    for (auto port : ports) {
        of13::Bucket b;
        b.watch_port(of13::OFPP_ANY);
        b.watch_group(of13::OFPG_ANY);
        //b.weight(0);
        b.add_action(new of13::OutputAction(port, 0));
        gm.add_bucket(b);
    }
    DVLOG(20) << "Install group in switch" << sw->id();
    sw->connection()->send(gm);
}

void SwitchSTP::setSwitchPort(uint32_t port_no, uint64_t dpid)
{
    ports.at(port_no)->to_switch = true;
    ports.at(port_no)->nextSwitch = parent->switch_list[dpid];
}

void STP::init(Loader* loader, const Config& config)
{
    QObject* ld = ILinkDiscovery::get(loader);
    auto subconfig = config_cd(config, "stp");
    poll_timeout = config_get(subconfig, "poll-timeout", 3);
    connect(ld, SIGNAL(linkDiscovered(switch_and_port, switch_and_port)),
                     this, SLOT(onLinkDiscovered(switch_and_port, switch_and_port)));
    connect(ld, SIGNAL(linkBroken(switch_and_port, switch_and_port)),
                     this, SLOT(onLinkBroken(switch_and_port, switch_and_port)));

    SwitchManager* sw = SwitchManager::get(loader);
    connect(sw, &SwitchManager::switchDiscovered, this, &STP::onSwitchDiscovered);
    connect(sw, &SwitchManager::switchDown, this, &STP::onSwitchDown);
    connect(sw, &SwitchManager::switchUp, this, &STP::onSwitchUp);
    topo = Topology::get(loader);

    computed = false;
    timer = new QTimer;
    connect(timer, SIGNAL(timeout()), this, SLOT(computeSpanningTree()));
    timer->start(poll_timeout * 1000);
}

STPPorts STP::getSTP(uint64_t dpid)
{
    if (switch_list.count(dpid) == 0 or not computed) {
        return {};
    }

    SwitchSTP* sw = switch_list[dpid];
    return sw->getEnabledPorts();
}

void STP::onLinkDiscovered(switch_and_port from, switch_and_port to)
{
    if (switch_list.count(from.dpid) == 0)
        return;

    if (switch_list.count(to.dpid) == 0)
        return;

    SwitchSTP* sw = switch_list[from.dpid];
    if (!sw->existsPort(from.port)) {
        Port* port = new Port(from.port);
        sw->ports[from.port] = port;
    }

    // port is disabled by default
    sw->unsetBroadcast(from.port);
    sw->updateGroup();

    sw->setSwitchPort(from.port, to.dpid);

    sw = switch_list[to.dpid];
    if (!sw->existsPort(to.port)) {
        Port* port = new Port(to.port);
        sw->ports[to.port] = port;
    }

    // port is disabled by default
    sw->unsetBroadcast(to.port);
    sw->updateGroup();

    sw->setSwitchPort(to.port, from.dpid);

    // recompute pathes for all switches
    computed = false;
}

void STP::onLinkBroken(switch_and_port from, switch_and_port to)
{
    // recompute pathes for all switches
    computed = false;
}

void STP::onSwitchDiscovered(Switch* dp)
{
    SwitchSTP* sw;
    sw = new SwitchSTP(dp, this);

    switch_list[dp->id()] = sw;

    connect(dp, &Switch::portUp, this, &STP::onPortUp);
}

void STP::onSwitchDown(Switch* dp)
{
    if (switch_list.count(dp->id()) > 0) {
        SwitchSTP* sw = switch_list[dp->id()];
        switch_list.erase(dp->id());
        delete sw;
    }
}

void STP::onSwitchUp(Switch* dp)
{
    if (switch_list.count(dp->id()) == 0) {
        SwitchSTP* sw = new SwitchSTP(dp, this);
        switch_list[dp->id()] = sw;
        connect(dp, &Switch::portUp, this, &STP::onPortUp);
    }
}

void STP::onPortUp(Switch *dp, of13::Port port)
{
    if (switch_list.count(dp->id()) > 0) {
        SwitchSTP* sw = switch_list[dp->id()];
        if ( !sw->existsPort(port.port_no()) && port.port_no() < of13::OFPP_MAX ) {
            Port* p = new Port(port.port_no());
            sw->ports[port.port_no()] = p;
        }
        sw->updateGroup();
    }
}

void STP::computeSpanningTree()
{
    static std::mutex compute_mutex;
    using namespace boost;
    using namespace topology;

    typedef graph_traits<TopologyGraph>::edge_descriptor edge_descriptor ;

    // clear spanning tree before new computing

    if (not computed){
        VLOG(20) << "Compute spanning tree";
        compute_mutex.lock();

        // all switch-switch ports are not broadcast
        for (auto sw : switch_list){
            sw.second->resetBroadcast();
        }
        spanning_tree.clear();

        auto boost_kruskal = [this](const topology::TopologyGraph& g){
            std::vector<edge_descriptor> result;
            kruskal_minimum_spanning_tree(g, std::back_inserter(result),
                    boost::weight_map( boost::get(&link_property::weight, g )) );
            for (auto& i : result){
                link_property l = g[i];
                spanning_tree[l.source.dpid].push_back(l.source.port);
                spanning_tree[l.target.dpid].push_back(l.target.port);
            }

        };
        topo->apply(boost_kruskal);

        // set ports broadcast in spanning tree
        for (auto& i : spanning_tree){
            SwitchSTP *sw = switch_list[i.first];
            for (auto& p : i.second){
                if (sw->existsPort(p)){
                    sw->setBroadcast(p);
                    VLOG(10) << i.first << ":" << p << " added in spanning tree";
                }
            }
            // update bucket groups
            sw->updateGroup();
        }

        computed = true;

        compute_mutex.unlock();
    }
}

ext: cc

max_stars_repo_name: Alexey-Ershov/runos

max_issues_repo_name: Alexey-Ershov/runos

max_forks_repo_name: Alexey-Ershov/runos


text:
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
//
// Above code modified by John Reynolds, Cornelia Consulting LLC, 08/2019
// This implementation hides details and presents simple calling api

#include "wsapi.hpp"

#include "root_certificates.hpp"

#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <boost/asio/strand.hpp>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <sstream>
#include <memory>
#include <string>
#include <vector>
#include <fstream>
#include <streambuf>

namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
namespace ssl = boost::asio::ssl;       // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>

// Report a failure
void fail(beast::error_code ec, char const* what) {
  std::cerr << what << ": " << ec.message() << "\n";
}

// Sends a WebSocket message and prints the response
class session : public std::enable_shared_from_this<session>
{
  tcp::resolver resolver_;
  websocket::stream<beast::ssl_stream<beast::tcp_stream>> ws_;
  beast::flat_buffer buffer_;
  std::string host_;
  std::vector<std::string> subs_;
  wsapi_cb *cb_;
  size_t   sub_send_count_;
  size_t   error_cnt;

public:
  // Resolver and socket require an io_context
  explicit session(net::io_context& ioc, ssl::context& ctx)
    : resolver_(net::make_strand(ioc))
    , ws_(net::make_strand(ioc), ctx) {
  }

  // Start the asynchronous operation
  void run(char const* host, char const* port, const std::vector<std::string> &subs, wsapi_cb *cb) {
    // Save these for later
    host_ = host;
    subs_ = subs;
    cb_ = cb;
    sub_send_count_ = 0;
    error_cnt = 0;

    // Look up the domain name
    resolver_.async_resolve(host, port, beast::bind_front_handler(&session::on_resolve, shared_from_this()));
  }

  void on_resolve(beast::error_code ec, tcp::resolver::results_type results) {
    if(ec)
      return fail(ec, "resolve");

    // Set a timeout on the operation
    beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));

    // Make the connection on the IP address we get from a lookup
    beast::get_lowest_layer(ws_).async_connect(results,beast::bind_front_handler(&session::on_connect, shared_from_this()));
  }

  void on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) {
    if(ec)
      return fail(ec, "connect");

    // Set a timeout on the operation
    beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));

    // this line is needed for coinbase, some exchanges dont require this
    if(! SSL_set_tlsext_host_name(ws_.next_layer().native_handle(), host_.c_str())) {
      std::cerr << "SSL_set_tlsext_host_name: error " << std::endl;
      return;
    }
    // Perform the SSL handshake
    ws_.next_layer().async_handshake(ssl::stream_base::client,beast::bind_front_handler(&session::on_ssl_handshake,shared_from_this()));
  }

  void on_ssl_handshake(beast::error_code ec) {
    if(ec)
      return fail(ec, "ssl_handshake");

    // Turn off the timeout on the tcp_stream, because
    // the websocket stream has its own timeout system.
    beast::get_lowest_layer(ws_).expires_never();

    // Set suggested timeout settings for the websocket
    ws_.set_option(websocket::stream_base::timeout::suggested(beast::role_type::client));

    // Set a decorator to change the User-Agent of the handshake
    ws_.set_option(
		   websocket::stream_base::decorator(
						     [](websocket::request_type& req)
						     {
						       req.set(http::field::user_agent,
							       std::string(BOOST_BEAST_VERSION_STRING) +
							       " websocket-client-async-ssl");
						     }));

    // Perform the websocket handshake
    ws_.async_handshake(host_, "/", beast::bind_front_handler(&session::on_handshake, shared_from_this()));
  }

  void on_handshake(beast::error_code ec) {
    if(ec)
      return fail(ec, "handshake");
    do_write();
  }

  void do_write() {
    if (sub_send_count_ < subs_.size())
      ws_.async_write(net::buffer(subs_[sub_send_count_++]),beast::bind_front_handler(&session::on_write,shared_from_this()));
  }

  void on_write(beast::error_code ec, std::size_t bytes_transferred) {
    boost::ignore_unused(bytes_transferred);
    if(ec)
      return fail(ec, "write");
    if (sub_send_count_ < subs_.size())
      do_write();
    else
      do_read();
  }

  void do_read() {
    ws_.async_read(buffer_, beast::bind_front_handler(&session::on_read, shared_from_this()));
  }

  void on_read(beast::error_code ec, std::size_t bytes_transferred) {
    if(ec) {
      if (++error_cnt > 5) {
	do_close();

      } else {
	fail(ec, "on_read error, ignoring");
	do_read();
      }
    } else {
      std::string msg = beast::buffers_to_string(buffer_.data());
      cb_->recv(msg);
      buffer_.consume(bytes_transferred);
      do_read();
    }
  }

  void do_close() {
    ws_.async_close(websocket::close_code::normal,beast::bind_front_handler(&session::on_close,shared_from_this()));
  }

  void
  on_close(beast::error_code ec) {
    if(ec)
      return fail(ec, "close");
  }
};

wsapi::wsapi(){
}

wsapi::wsapi(const char *host, const char *port, const char *sub, wsapi_cb *cb, const char *certfile)
  :host_(host), port_(port), certfile_(certfile), subs_(1,sub), cb_(cb) {
}

wsapi::wsapi(const char *host, const char *port, const std::vector<std::string> &subs, wsapi_cb *cb, const char *certfile)
  :host_(host), port_(port), certfile_(certfile), subs_(subs), cb_(cb) {
}

void wsapi::set_cert_file(const std::string &certfile){
  certfile_=certfile;
}

void wsapi::set_host(const std::string &host) {
  host_=host;
}

void wsapi::set_port(const std::string &port){
  port_=port;
}

void wsapi::set_subs(const std::vector<std::string> &subs) {
  subs_=subs;
}

void wsapi::set_cb(wsapi_cb *cb) {
  cb_=cb;
}

void wsapi::start() {

  net::io_context ioc;

  // The SSL context is required, and holds certificates
  ssl::context ctx{ssl::context::tlsv12_client};

  // This holds the ssl certificate used for verification
  if (certfile_.length() > 0) {
    // common on linux is this one "/usr/lib/ssl/certs/653b494a.0"
    std::ifstream t(certfile_.c_str());
    std::string cert((std::istreambuf_iterator<char>(t)),
		     std::istreambuf_iterator<char>());
    boost::system::error_code ec;
    ctx.add_certificate_authority(boost::asio::buffer(cert.data(), cert.size()), ec);
    if(ec)
      throw boost::system::system_error{ec};
  } else {
    // this one is a default and is not guaranteed to be sucessful
    // see these comments here on the default root certificate
    // https://github.com/boostorg/beast/issues/1702
    load_root_certificates(ctx);
  }

  // Launch the asynchronous operation
  std::make_shared<session>(ioc, ctx)->run(host_.c_str(), port_.c_str(), subs_, cb_);

  // Run the I/O service. The call will return when
  // the socket is closed.
  ioc.run();
}

max_stars_repo_name: jrrpanix/cexchange

max_issues_repo_name: jrrpanix/cexchange

max_forks_repo_name: jrrpanix/cexchange


text:
#include <websocketpp/config/asio_no_tls.hpp>

#include <websocketpp/server.hpp>

#include <iostream>

/*#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>*/
#include <websocketpp/common/thread.hpp>

typedef websocketpp::server<websocketpp::config::asio> server;

using websocketpp::connection_hdl;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

using websocketpp::lib::thread;
using websocketpp::lib::mutex;
using websocketpp::lib::unique_lock;
using websocketpp::lib::condition_variable;

/* on_open insert connection_hdl into channel
 * on_close remove connection_hdl from channel
 * on_message queue send to all channels
 */

enum action_type {
    SUBSCRIBE,
    UNSUBSCRIBE,
    MESSAGE
};

struct action {
    action(action_type t, connection_hdl h) : type(t), hdl(h) {}
    action(action_type t, connection_hdl h, server::message_ptr m)
      : type(t), hdl(h), msg(m) {}

    action_type type;
    websocketpp::connection_hdl hdl;
    server::message_ptr msg;
};

class broadcast_server {
public:
    broadcast_server() {
        // Initialize Asio Transport
        m_server.init_asio();

        // Register handler callbacks
        m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
        m_server.set_close_handler(bind(&broadcast_server::on_close,this,::_1));
        m_server.set_message_handler(bind(&broadcast_server::on_message,this,::_1,::_2));
    }

    void run(uint16_t port) {
        // listen on specified port
        m_server.listen(port);

        // Start the server accept loop
	    m_server.start_accept();

	    // Start the ASIO io_service run loop
        try {
            m_server.run();
        } catch (const std::exception & e) {
            std::cout << e.what() << std::endl;
        } catch (websocketpp::lib::error_code e) {
            std::cout << e.message() << std::endl;
        } catch (...) {
            std::cout << "other exception" << std::endl;
        }
    }

    void on_open(connection_hdl hdl) {
        unique_lock<mutex> lock(m_action_lock);
        //std::cout << "on_open" << std::endl;
        m_actions.push(action(SUBSCRIBE,hdl));
        lock.unlock();
        m_action_cond.notify_one();
    }

    void on_close(connection_hdl hdl) {
        unique_lock<mutex> lock(m_action_lock);
        //std::cout << "on_close" << std::endl;
        m_actions.push(action(UNSUBSCRIBE,hdl));
        lock.unlock();
        m_action_cond.notify_one();
    }

    void on_message(connection_hdl hdl, server::message_ptr msg) {
        // queue message up for sending by processing thread
        unique_lock<mutex> lock(m_action_lock);
        //std::cout << "on_message" << std::endl;
        m_actions.push(action(MESSAGE,hdl,msg));
        lock.unlock();
        m_action_cond.notify_one();
    }

    void process_messages() {
        while(1) {
            unique_lock<mutex> lock(m_action_lock);

            while(m_actions.empty()) {
                m_action_cond.wait(lock);
            }

            action a = m_actions.front();
            m_actions.pop();

            lock.unlock();

            if (a.type == SUBSCRIBE) {
                unique_lock<mutex> con_lock(m_connection_lock);
                m_connections.insert(a.hdl);
            } else if (a.type == UNSUBSCRIBE) {
                unique_lock<mutex> con_lock(m_connection_lock);
                m_connections.erase(a.hdl);
            } else if (a.type == MESSAGE) {
                unique_lock<mutex> con_lock(m_connection_lock);

                con_list::iterator it;
                for (it = m_connections.begin(); it != m_connections.end(); ++it) {
                    m_server.send(*it,a.msg);
                }
            } else {
                // undefined.
            }
        }
    }
private:
    typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;

    server m_server;
    con_list m_connections;
    std::queue<action> m_actions;

    mutex m_action_lock;
    mutex m_connection_lock;
    condition_variable m_action_cond;
};

int main() {
	try {
	broadcast_server server_instance;

	// Start a thread to run the processing loop
	thread t(bind(&broadcast_server::process_messages,&server_instance));

	// Run the asio loop with the main thread
	server_instance.run(9002);

	t.join();

	} catch (std::exception & e) {
	    std::cout << e.what() << std::endl;
	}
}

max_stars_repo_name: mentionllc/traintracks-cpp-sdk

max_issues_repo_name: mentionllc/traintracks-cpp-sdk

max_forks_repo_name: mentionllc/traintracks-cpp-sdk


text:
/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/* irodsFs.h - Header for for irodsFs.c */

#ifndef IRODS_FS_HPP_
#define IRODS_FS_HPP_

#undef USE_BOOST

#ifdef USE_BOOST
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#endif
// =-=-=-=-=-=-=-

#define FUSE_USE_VERSION 26

#include <fuse.h>
#include "rodsClient.hpp"
#include "parseCommandLine.hpp"
#include "rodsPath.hpp"

#define FILE_BLOCK_SZ	512
#define DIR_SZ    4096
#define DEF_FILE_MODE	0660
#define DEF_FILE_CREATE_MODE	0750
#define DEF_DIR_MODE	0770

#define IFUSE_CONN_TIMEOUT	120	/* 2 min connection timeout */
#define CONN_MANAGER_SLEEP_TIME 60
#define CONN_REQ_SLEEP_TIME 30

typedef struct IFuseConn {
    rcComm_t *conn;
#ifdef USE_BOOST
    boost::mutex* mutex;
#else
    pthread_mutex_t lock;
#endif
    time_t actTime;	/* the last time the connection is active */
    int inuseCnt;
    int pendingCnt;
    int status;
    /* struct IFuseConn *next; */
} iFuseConn_t;

#ifdef  __cplusplus
extern "C" {
#endif

#ifdef  __cplusplus
}
#endif

#endif	/* IRODS_FS_HPP_ */

max_stars_repo_name: nesi/irods

max_issues_repo_name: nesi/irods

max_forks_repo_name: nesi/irods


text:
/*
Copyright 2017-2018 Glen Joseph Fernandes
(glenjofe@gmail.com)

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

#ifndef BOOST_TT_DETAIL_DETECTOR_HPP_INCLUDED
#define BOOST_TT_DETAIL_DETECTOR_HPP_INCLUDED

#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/make_void.hpp>

namespace boost {
namespace detail {

template<class T>
using detector_t = typename boost::make_void<T>::type;

template<class Default, class, template<class...> class, class...>
struct detector {
    using value_t = boost::false_type;
    using type = Default;
};

template<class Default, template<class...> class Op, class... Args>
struct detector<Default, detector_t<Op<Args...> >, Op, Args...> {
    using value_t = boost::true_type;
    using type = Op<Args...>;
};

} /* detail */
} /* boost */

#endif

max_stars_repo_name: kindlychung/mediasoup-sfu-cpp

max_issues_repo_name: kindlychung/mediasoup-sfu-cpp

max_forks_repo_name: kindlychung/mediasoup-sfu-cpp


text:
#include "io_fixture.hpp"
#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_CASE(unsigned_short, io_fixture)
{
    unsigned short x = static_cast<unsigned short>(rand());
    check_roundtrip(x);
}

max_stars_repo_name: rwols/yaml-archive

max_issues_repo_name: rwols/yaml-archive

max_forks_repo_name: rwols/yaml-archive


text:
// Copyright 2015-2019 Hans Dembinski
// Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_HISTOGRAM_UNLIMTED_STORAGE_HPP
#define BOOST_HISTOGRAM_UNLIMTED_STORAGE_HPP

#include <algorithm>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/histogram/detail/iterator_adaptor.hpp>
#include <boost/histogram/detail/large_int.hpp>
#include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/detail/safe_comparison.hpp>
#include <boost/histogram/detail/static_if.hpp>
#include <boost/histogram/fwd.hpp>
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/utility.hpp>
#include <cmath>
#include <functional>
#include <iterator>
#include <memory>
#include <type_traits>

namespace boost {
namespace histogram {
namespace detail {

template <class T, class = std::enable_if_t<(std::is_arithmetic<T>::value ||
                                             is_large_int<T>::value)>>
struct requires_arithmetic {};

template <class L, class T>
using next_type = mp11::mp_at_c<L, (mp11::mp_find<L, T>::value + 1)>;

template<class Allocator>
class construct_guard {
public:
  using pointer = typename std::allocator_traits<Allocator>::pointer;

  construct_guard(Allocator& a, pointer p, std::size_t n) noexcept
    : a_(a), p_(p), n_(n) {}

  ~construct_guard() {
    if (p_) {
      a_.deallocate(p_, n_);
    }
  }

  void release() {
    p_ = pointer();
  }

  construct_guard(const construct_guard&) = delete;
  construct_guard& operator=(const construct_guard&) = delete;

private:
  Allocator& a_;
  pointer p_;
  std::size_t n_;
};

template <class Allocator>
void* buffer_create(Allocator& a, std::size_t n) {
  auto ptr = a.allocate(n); // may throw
  static_assert(std::is_trivially_copyable<decltype(ptr)>::value,
                "ptr must be trivially copyable");
  construct_guard<Allocator> guard(a, ptr, n);
  boost::alloc_construct_n(a, ptr, n);
  guard.release();
  return static_cast<void*>(ptr);
}

template <class Allocator, class Iterator>
auto buffer_create(Allocator& a, std::size_t n, Iterator iter) {
  BOOST_ASSERT(n > 0u);
  auto ptr = a.allocate(n); // may throw
  static_assert(std::is_trivially_copyable<decltype(ptr)>::value,
                "ptr must be trivially copyable");
  construct_guard<Allocator> guard(a, ptr, n);
  boost::alloc_construct_n(a, ptr, n, iter);
  guard.release();
  return ptr;
}

template <class Allocator>
void buffer_destroy(Allocator& a, typename std::allocator_traits<Allocator>::pointer p,
                    std::size_t n) {
  BOOST_ASSERT(p);
  BOOST_ASSERT(n > 0u);
  boost::alloc_destroy_n(a, p, n);
  a.deallocate(p, n);
}

} // namespace detail

/**
  Memory-efficient storage for integral counters which cannot overflow.

  This storage provides a no-overflow-guarantee if it is filled with integral weights
  only. This storage implementation keeps a contiguous array of elemental counters, one
  for each cell. If an operation is requested, which would overflow a counter, the whole
  array is replaced with another of a wider integral type, then the operation is executed.
  The storage uses integers of 8, 16, 32, 64 bits, and then switches to a multiprecision
  integral type, similar to those in
  [Boost.Multiprecision](https://www.boost.org/doc/libs/develop/libs/multiprecision/doc/html/index.html).

  A scaling operation or adding a floating point number turns the elements into doubles,
  which voids the no-overflow-guarantee.
*/
template <class Allocator>
class unlimited_storage {
  static_assert(
      std::is_same<typename std::allocator_traits<Allocator>::pointer,
                   typename std::allocator_traits<Allocator>::value_type*>::value,
      "unlimited_storage requires allocator with trivial pointer type");

public:
  static constexpr bool has_threading_support = false;

  using allocator_type = Allocator;
  using value_type = double;
  using large_int = detail::large_int<
      typename std::allocator_traits<allocator_type>::template rebind_alloc<uint64_t>>;

  struct buffer_type {
    // cannot be moved outside of scope of unlimited_storage, large_int is dependent type
    using types = mp11::mp_list<uint8_t, uint16_t, uint32_t, uint64_t, large_int, double>;

    template <class T>
    static constexpr unsigned type_index() noexcept {
      return static_cast<unsigned>(mp11::mp_find<types, T>::value);
    }

    template <class F, class... Ts>
    decltype(auto) visit(F&& f, Ts&&... ts) const {
      // this is intentionally not a switch, the if-chain is faster in benchmarks
      if (type == type_index<uint8_t>())
        return f(static_cast<uint8_t*>(ptr), std::forward<Ts>(ts)...);
      if (type == type_index<uint16_t>())
        return f(static_cast<uint16_t*>(ptr), std::forward<Ts>(ts)...);
      if (type == type_index<uint32_t>())
        return f(static_cast<uint32_t*>(ptr), std::forward<Ts>(ts)...);
      if (type == type_index<uint64_t>())
        return f(static_cast<uint64_t*>(ptr), std::forward<Ts>(ts)...);
      if (type == type_index<large_int>())
        return f(static_cast<large_int*>(ptr), std::forward<Ts>(ts)...);
      return f(static_cast<double*>(ptr), std::forward<Ts>(ts)...);
    }

    buffer_type(const allocator_type& a = {}) : alloc(a) {}

    buffer_type(buffer_type&& o) noexcept
        : alloc(std::move(o.alloc)), size(o.size), type(o.type), ptr(o.ptr) {
      o.size = 0;
      o.type = 0;
      o.ptr = nullptr;
    }

    buffer_type& operator=(buffer_type&& o) noexcept {
      if (this != &o) {
        using std::swap;
        swap(alloc, o.alloc);
        swap(size, o.size);
        swap(type, o.type);
        swap(ptr, o.ptr);
      }
      return *this;
    }

    buffer_type(const buffer_type& x) : alloc(x.alloc) {
      x.visit([this, n = x.size](const auto* xp) {
        using T = detail::remove_cvref_t<decltype(*xp)>;
        this->template make<T>(n, xp);
      });
    }

    buffer_type& operator=(const buffer_type& o) {
      *this = buffer_type(o);
      return *this;
    }

    ~buffer_type() noexcept { destroy(); }

    void destroy() noexcept {
      BOOST_ASSERT((ptr == nullptr) == (size == 0));
      if (ptr == nullptr) return;
      visit([this](auto* p) {
        using T = detail::remove_cvref_t<decltype(*p)>;
        using alloc_type =
            typename std::allocator_traits<allocator_type>::template rebind_alloc<T>;
        alloc_type a(alloc); // rebind allocator
        detail::buffer_destroy(a, p, this->size);
      });
      size = 0;
      type = 0;
      ptr = nullptr;
    }

    template <class T>
    void make(std::size_t n) {
      // note: order of commands is to not leave buffer in invalid state upon throw
      destroy();
      if (n > 0) {
        // rebind allocator
        using alloc_type =
            typename std::allocator_traits<allocator_type>::template rebind_alloc<T>;
        alloc_type a(alloc);
        ptr = detail::buffer_create(a, n); // may throw
      }
      size = n;
      type = type_index<T>();
    }

    template <class T, class U>
    void make(std::size_t n, U iter) {
      // note: iter may be current ptr, so create new buffer before deleting old buffer
      void* new_ptr = nullptr;
      const auto new_type = type_index<T>();
      if (n > 0) {
        // rebind allocator
        using alloc_type =
            typename std::allocator_traits<allocator_type>::template rebind_alloc<T>;
        alloc_type a(alloc);
        new_ptr = detail::buffer_create(a, n, iter); // may throw
      }
      destroy();
      size = n;
      type = new_type;
      ptr = new_ptr;
    }

    allocator_type alloc;
    std::size_t size = 0;
    unsigned type = 0;
    mutable void* ptr = nullptr;
  };

  class reference; // forward declare to make friend of const_reference

  /// implementation detail
  class const_reference {
  public:
    const_reference(buffer_type& b, std::size_t i) : bref_(b), idx_(i) {
      BOOST_ASSERT(idx_ < bref_.size);
    }

    const_reference(const const_reference&) = default;

    // references do not rebind
    const_reference& operator=(const const_reference&) = delete;
    const_reference& operator=(const_reference&&) = delete;

    operator double() const {
      return bref_.visit(
          [this](const auto* p) { return static_cast<double>(p[this->idx_]); });
    }

    // minimal operators for partial ordering
    bool operator<(const const_reference& rhs) const { return op<detail::less>(rhs); }
    bool operator>(const const_reference& rhs) const { return op<detail::greater>(rhs); }
    bool operator==(const const_reference& rhs) const { return op<detail::equal>(rhs); }

    // adapted copy from boost/operators.hpp for partial ordering
    friend bool operator<=(const const_reference& x, const const_reference& y) {
      return !(y < x);
    }
    friend bool operator>=(const const_reference& x, const const_reference& y) {
      return !(y > x);
    }
    friend bool operator!=(const const_reference& y, const const_reference& x) {
      return !(x == y);
    }

    template <class U, class = detail::requires_arithmetic<U>>
    bool operator<(const U& rhs) const {
      return op<detail::less>(rhs);
    }

    template <class U, class = detail::requires_arithmetic<U>>
    bool operator>(const U& rhs) const {
      return op<detail::greater>(rhs);
    }

    template <class U, class = detail::requires_arithmetic<U>>
    bool operator==(const U& rhs) const {
      return op<detail::equal>(rhs);
    }

    // adapted copy from boost/operators.hpp
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator<=(const const_reference& x, const U& y) {
      if (detail::is_unsigned_integral<U>::value) return !(x > y);
      return (x < y) || (x == y);
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator>=(const const_reference& x, const U& y) {
      if (detail::is_unsigned_integral<U>::value) return !(x < y);
      return (x > y) || (x == y);
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator>(const U& x, const const_reference& y) {
      return y < x;
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator<(const U& x, const const_reference& y) {
      return y > x;
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator<=(const U& x, const const_reference& y) {
      if (detail::is_unsigned_integral<U>::value) return !(y < x);
      return (y > x) || (y == x);
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator>=(const U& x, const const_reference& y) {
      if (detail::is_unsigned_integral<U>::value) return !(y > x);
      return (y < x) || (y == x);
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator==(const U& y, const const_reference& x) {
      return x == y;
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator!=(const U& y, const const_reference& x) {
      return !(x == y);
    }
    template <class U, class = detail::requires_arithmetic<U>>
    friend bool operator!=(const const_reference& y, const U& x) {
      return !(y == x);
    }

  private:
    template <class Binary>
    bool op(const const_reference& x) const {
      return x.bref_.visit(
          [this, ix = x.idx_](const auto* xp) { return this->op<Binary>(xp[ix]); });
    }

    template <class Binary, class U>
    bool op(const U& x) const {
      return bref_.visit([i = idx_, &x](const auto* p) { return Binary()(p[i], x); });
    }

  protected:
    buffer_type& bref_;
    std::size_t idx_;
    friend class reference;
  };

  /// implementation detail
  class reference : public const_reference {
  public:
    reference(buffer_type& b, std::size_t i) : const_reference(b, i) {}

    // references do copy-construct
    reference(const reference& x) = default;

    // references do not rebind, assign through
    reference& operator=(const reference& x) {
      return operator=(static_cast<const_reference>(x));
    }

    reference& operator=(const const_reference& x) {
      x.bref_.visit([this, ix = x.idx_](const auto* xp) {
        auto xi = xp[ix]; // convert reference to value
        this->operator=(xi);
      });
      return *this;
    }

    template <class U, class = detail::requires_arithmetic<U>>
    reference& operator=(const U& x) {
      this->bref_.visit([this, &x](auto* p) {
        p[this->idx_] = 0;
        adder()(p, this->bref_, this->idx_, x);
      });
      return *this;
    }

    reference& operator=(const large_int& x) {
      this->bref_.visit([this, &x](auto* p) {
        p[this->idx_] = 0;
        adder()(p, this->bref_, this->idx_, x);
      });
      return *this;
    }

    reference& operator+=(const const_reference& x) {
      x.bref_.visit([this, ix = x.idx_](const auto* xp) { this->operator+=(xp[ix]); });
      return *this;
    }

    template <class U, class = detail::requires_arithmetic<U>>
    reference& operator+=(const U& x) {
      this->bref_.visit(adder(), this->bref_, this->idx_, x);
      return *this;
    }

    reference& operator+=(const large_int& x) {
      this->bref_.visit(adder(), this->bref_, this->idx_, x);
      return *this;
    }

    reference& operator-=(const double x) { return operator+=(-x); }

    reference& operator*=(const double x) {
      this->bref_.visit(multiplier(), this->bref_, this->idx_, x);
      return *this;
    }

    reference& operator/=(const double x) { return operator*=(1.0 / x); }

    reference& operator++() {
      this->bref_.visit(incrementor(), this->bref_, this->idx_);
      return *this;
    }
  };

private:
  template <class Value, class Reference>
  class iterator_impl : public detail::iterator_adaptor<iterator_impl<Value, Reference>,
                                                        std::size_t, Reference, Value> {
  public:
    iterator_impl() = default;
    template <class V, class R>
    iterator_impl(const iterator_impl<V, R>& it)
        : iterator_impl::iterator_adaptor_(it.base()), buffer_(it.buffer_) {}
    iterator_impl(buffer_type* b, std::size_t i) noexcept
        : iterator_impl::iterator_adaptor_(i), buffer_(b) {}

    Reference operator*() const noexcept { return {*buffer_, this->base()}; }

    template <class V, class R>
    friend class iterator_impl;

  private:
    mutable buffer_type* buffer_ = nullptr;
  };

public:
  using const_iterator = iterator_impl<const value_type, const_reference>;
  using iterator = iterator_impl<value_type, reference>;

  explicit unlimited_storage(const allocator_type& a = {}) : buffer_(a) {}
  unlimited_storage(const unlimited_storage&) = default;
  unlimited_storage& operator=(const unlimited_storage&) = default;
  unlimited_storage(unlimited_storage&&) = default;
  unlimited_storage& operator=(unlimited_storage&&) = default;

  // TODO
  // template <class Allocator>
  // unlimited_storage(const unlimited_storage<Allocator>& s)

  template <class Iterable, class = detail::requires_iterable<Iterable>>
  explicit unlimited_storage(const Iterable& s) {
    using std::begin;
    using std::end;
    auto s_begin = begin(s);
    auto s_end = end(s);
    using V = typename std::iterator_traits<decltype(begin(s))>::value_type;
    constexpr auto ti = buffer_type::template type_index<V>();
    constexpr auto nt = mp11::mp_size<typename buffer_type::types>::value;
    const std::size_t size = static_cast<std::size_t>(std::distance(s_begin, s_end));
    detail::static_if_c<(ti < nt)>(
        [this, &size, &s_begin](auto) { buffer_.template make<V>(size, s_begin); },
        [this, &size, &s_begin](auto) { buffer_.template make<double>(size, s_begin); },
        0);
  }

  template <class Iterable, class = detail::requires_iterable<Iterable>>
  unlimited_storage& operator=(const Iterable& s) {
    *this = unlimited_storage(s);
    return *this;
  }

  allocator_type get_allocator() const { return buffer_.alloc; }

  void reset(std::size_t n) { buffer_.template make<uint8_t>(n); }

  std::size_t size() const noexcept { return buffer_.size; }

  reference operator[](std::size_t i) noexcept { return {buffer_, i}; }
  const_reference operator[](std::size_t i) const noexcept { return {buffer_, i}; }

  bool operator==(const unlimited_storage& x) const noexcept {
    if (size() != x.size()) return false;
    return buffer_.visit([&x](const auto* p) {
      return x.buffer_.visit([p, n = x.size()](const auto* xp) {
        return std::equal(p, p + n, xp, detail::equal{});
      });
    });
  }

  template <class Iterable>
  bool operator==(const Iterable& iterable) const {
    if (size() != iterable.size()) return false;
    return buffer_.visit([&iterable](const auto* p) {
      return std::equal(p, p + iterable.size(), std::begin(iterable), detail::equal{});
    });
  }

  unlimited_storage& operator*=(const double x) {
    buffer_.visit(multiplier(), buffer_, x);
    return *this;
  }

  iterator begin() noexcept { return {&buffer_, 0}; }
  iterator end() noexcept { return {&buffer_, size()}; }
  const_iterator begin() const noexcept { return {&buffer_, 0}; }
  const_iterator end() const noexcept { return {&buffer_, size()}; }

  /// @private used by unit tests, not part of generic storage interface
  template <class T>
  unlimited_storage(std::size_t s, const T* p, const allocator_type& a = {})
      : buffer_(std::move(a)) {
    buffer_.template make<T>(s, p);
  }

private:
  struct incrementor {
    template <class T>
    void operator()(T* tp, buffer_type& b, std::size_t i) {
      BOOST_ASSERT(tp && i < b.size);
      if (!detail::safe_increment(tp[i])) {
        using U = detail::next_type<typename buffer_type::types, T>;
        b.template make<U>(b.size, tp);
        ++static_cast<U*>(b.ptr)[i];
      }
    }

    void operator()(large_int* tp, buffer_type&, std::size_t i) { ++tp[i]; }

    void operator()(double* tp, buffer_type&, std::size_t i) { ++tp[i]; }
  };

  struct adder {
    template <class U>
    void operator()(double* tp, buffer_type&, std::size_t i, const U& x) {
      tp[i] += static_cast<double>(x);
    }

    void operator()(large_int* tp, buffer_type&, std::size_t i, const large_int& x) {
      tp[i] += x; // potentially adding large_int to itself is safe
    }

    template <class T, class U>
    void operator()(T* tp, buffer_type& b, std::size_t i, const U& x) {
      is_x_integral(std::is_integral<U>{}, tp, b, i, x);
    }

    template <class T, class U>
    void is_x_integral(std::false_type, T* tp, buffer_type& b, std::size_t i,
                       const U& x) {
      // x could be reference to buffer we manipulate, make copy before changing buffer
      const auto v = static_cast<double>(x);
      b.template make<double>(b.size, tp);
      operator()(static_cast<double*>(b.ptr), b, i, v);
    }

    template <class T>
    void is_x_integral(std::false_type, T* tp, buffer_type& b, std::size_t i,
                       const large_int& x) {
      // x could be reference to buffer we manipulate, make copy before changing buffer
      const auto v = static_cast<large_int>(x);
      b.template make<large_int>(b.size, tp);
      operator()(static_cast<large_int*>(b.ptr), b, i, v);
    }

    template <class T, class U>
    void is_x_integral(std::true_type, T* tp, buffer_type& b, std::size_t i, const U& x) {
      is_x_unsigned(std::is_unsigned<U>{}, tp, b, i, x);
    }

    template <class T, class U>
    void is_x_unsigned(std::false_type, T* tp, buffer_type& b, std::size_t i,
                       const U& x) {
      if (x >= 0)
        is_x_unsigned(std::true_type{}, tp, b, i, detail::make_unsigned(x));
      else
        is_x_integral(std::false_type{}, tp, b, i, static_cast<double>(x));
    }

    template <class T, class U>
    void is_x_unsigned(std::true_type, T* tp, buffer_type& b, std::size_t i, const U& x) {
      if (detail::safe_radd(tp[i], x)) return;
      // x could be reference to buffer we manipulate, need to convert to value
      const auto y = x;
      using TN = detail::next_type<typename buffer_type::types, T>;
      b.template make<TN>(b.size, tp);
      is_x_unsigned(std::true_type{}, static_cast<TN*>(b.ptr), b, i, y);
    }

    template <class U>
    void is_x_unsigned(std::true_type, large_int* tp, buffer_type&, std::size_t i,
                       const U& x) {
      tp[i] += x;
    }
  };

  struct multiplier {
    template <class T>
    void operator()(T* tp, buffer_type& b, const double x) {
      // potential lossy conversion that cannot be avoided
      b.template make<double>(b.size, tp);
      operator()(static_cast<double*>(b.ptr), b, x);
    }

    void operator()(double* tp, buffer_type& b, const double x) {
      for (auto end = tp + b.size; tp != end; ++tp) *tp *= x;
    }

    template <class T>
    void operator()(T* tp, buffer_type& b, std::size_t i, const double x) {
      b.template make<double>(b.size, tp);
      operator()(static_cast<double*>(b.ptr), b, i, x);
    }

    void operator()(double* tp, buffer_type&, std::size_t i, const double x) {
      tp[i] *= static_cast<double>(x);
    }
  };

  mutable buffer_type buffer_;
  friend struct unsafe_access;
};

} // namespace histogram
} // namespace boost

#endif


text:
#ifndef __wrapper_MSSMNoFV_onshell_susy_parameters_decl_gm2calc_1_3_0_hpp__
#define __wrapper_MSSMNoFV_onshell_susy_parameters_decl_gm2calc_1_3_0_hpp__

#include <cstddef>
#include "forward_decls_wrapper_classes.hpp"
#include "gambit/Backends/wrapperbase.hpp"
#include "abstract_MSSMNoFV_onshell_susy_parameters.hpp"
#include <Eigen/Core>
#include <ostream>

#include "identification.hpp"

namespace CAT_3(BACKENDNAME,_,SAFE_VERSION)
{

   namespace gm2calc
   {

      class MSSMNoFV_onshell_susy_parameters : public WrapperBase
      {
            // Member variables:
         public:
            // -- Static factory pointers:
            static gm2calc::Abstract_MSSMNoFV_onshell_susy_parameters* (*__factory0)();
            static gm2calc::Abstract_MSSMNoFV_onshell_susy_parameters* (*__factory1)(double, const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>&, const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>&, const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>&, double, double, double, double, double, double);

            // -- Other member variables:

            // Member functions:
         public:
            void print(::std::basic_ostream<char, std::char_traits<char> >& arg_1) const;

            void clear();

            void set_scale(double s);

            double get_scale() const;

            void set_Yd(const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& Yd_);

            void set_Yd(int i, int k, double value);

            void set_Ye(const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& Ye_);

            void set_Ye(int i, int k, double value);

            void set_Yu(const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& Yu_);

            void set_Yu(int i, int k, double value);

            void set_Mu(double Mu_);

            void set_g1(double g1_);

            void set_g2(double g2_);

            void set_g3(double g3_);

            void set_vd(double vd_);

            void set_vu(double vu_);

            const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& get_Yd() const;

            double get_Yd(int i, int k) const;

            const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& get_Ye() const;

            double get_Ye(int i, int k) const;

            const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& get_Yu() const;

            double get_Yu(int i, int k) const;

            double get_Mu() const;

            double get_g1() const;

            double get_g2() const;

            double get_g3() const;

            double get_vd() const;

            double get_vu() const;

            // Wrappers for original constructors:
         public:
            MSSMNoFV_onshell_susy_parameters();
            MSSMNoFV_onshell_susy_parameters(double scale_, const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& Yd_, const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& Ye_, const ::Eigen::Matrix<double, 3, 3, 0, 3, 3>& Yu_, double Mu_, double g1_, double g2_, double g3_, double vd_, double vu_);

            // Special pointer-based constructor:
            MSSMNoFV_onshell_susy_parameters(gm2calc::Abstract_MSSMNoFV_onshell_susy_parameters* in);

            // Copy constructor:
            MSSMNoFV_onshell_susy_parameters(const MSSMNoFV_onshell_susy_parameters& in);

            // Assignment operator:
            MSSMNoFV_onshell_susy_parameters& operator=(const MSSMNoFV_onshell_susy_parameters& in);

            // Destructor:
            ~MSSMNoFV_onshell_susy_parameters();

            // Returns correctly casted pointer to Abstract class:
            gm2calc::Abstract_MSSMNoFV_onshell_susy_parameters* get_BEptr() const;

      };
   }

}

#include "gambit/Backends/backend_undefs.hpp"

#endif /* __wrapper_MSSMNoFV_onshell_susy_parameters_decl_gm2calc_1_3_0_hpp__ */