text:
#include "entities/Node.hpp"
#include "index/BitmapIndex.hpp"

#include <boost/test/unit_test.hpp>
#include "test_utils/DependencyProvider.hpp"
#include "test_utils/ElementUtils.hpp"

using namespace utymap;
using namespace utymap::entities;
using namespace utymap::index;
using namespace utymap::tests;

namespace {
  /// Defines the simplest in memory string index implementation.
  class TestBitmapIndex : public BitmapIndex {
   public:
    TestBitmapIndex(const StringTable &stringTable,
                    ElementVisitor &visitor) :
        BitmapIndex(stringTable),
        addedElements(),
        visitor_(visitor),
        registry_() {}

    void notify(const utymap::QuadKey& quadKey,
                const std::uint32_t order,
                ElementVisitor &visitor) override {
      addedElements.at(order)->accept(visitor_);
    }

    Bitmap& getBitmap(const utymap::QuadKey& quadKey) {
      auto bitmap = registry_.find(quadKey);
      if (bitmap==registry_.end()) {
        bitmap = registry_.emplace(quadKey, Bitmap()).first;
      }
      return bitmap->second;
    }

    bool hasData(const utymap::QuadKey& quadKey) const override {
      return registry_.find(quadKey) != registry_.end();
    }

    void erase(const utymap::QuadKey &quadKey) override {}

    std::vector<std::shared_ptr<Element>> addedElements;
   private:
    ElementVisitor &visitor_;
    std::map<QuadKey, BitmapIndex::Bitmap, QuadKey::Comparator> registry_;
  };

  struct Index_BitmapIndexFixture : ElementVisitor {
    Index_BitmapIndexFixture() :
      dependencyProvider(),
      index(*dependencyProvider.getStringTable(), *this),
      bbox(BoundingBox(GeoCoordinate(-90, -180), GeoCoordinate(90, 180))),
      lodRange(1, 1),
      visitedElements() {
    }

    /// Adds node with given tags in index for given quadkey
    void addToIndex(std::initializer_list<std::pair<const char *, const char *>> tags,
                       const QuadKey quadKey = QuadKey(1, 0, 0)) {
      auto node = ElementUtils::createElement<Node>(*dependencyProvider.getStringTable(), 0, tags);
      index.add(node,
                utymap::QuadKey(1, 0, 0),
                static_cast<std::uint32_t>(index.addedElements.size()));
      index.addedElements.push_back(std::make_shared<Node>(node));
    }

    std::string getString(std::uint32_t id) {
      return *dependencyProvider.getStringTable()->getString(id);
    }

    void addThreeElements() {
      addToIndex({ { "addr:country", "Deutschland" } });
      addToIndex({ { "addr:street", "Eichendorffstr." } });
      addToIndex({ { "addr:city", "Berlin" } });
    }

    /// Adds visited node in special collection.
    void visitNode(const Node &node) override {
      visitedElements.push_back(std::make_shared<Node>(node));
    }

    // Ignore the rest as we always use nodes
    void visitWay(const Way &) override { }
    void visitArea(const Area &) override { }
    void visitRelation(const Relation &) override { }

    DependencyProvider dependencyProvider;
    TestBitmapIndex index;
    BoundingBox bbox;
    LodRange lodRange;

    std::vector<std::shared_ptr<Element>> visitedElements;
  };
}

BOOST_FIXTURE_TEST_SUITE(Index_BitmapIndex, Index_BitmapIndexFixture)

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenEmptyQuery_ThenNoResults) {
  BitmapIndex::Query query = { "", "", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 0);
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithOneAND_ThenOneResult) {
  BitmapIndex::Query query = { "", "street", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 1);
  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:street");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithTwoAND_ThenOneResult) {
  BitmapIndex::Query query = { "", "addr Eichendorffstr", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 1);
  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:street");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithOneAND_ThenThreeResults) {
  BitmapIndex::Query query = { "", "addr", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 3);
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithNot_ThenNoResults) {
  BitmapIndex::Query query = { "country", "", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 0);
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithNotAnd_ThenOneResult) {
  BitmapIndex::Query query = { "street", "addr", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:country");
  BOOST_CHECK_EQUAL(getString(this->visitedElements[1]->tags[0].key), "addr:city");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithNotAnd_ThenNoResults) {
  BitmapIndex::Query query = { "Deutschland", "country", "", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 0);
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithOr_ThenHasOneResult) {
  BitmapIndex::Query query = { "", "", "country", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 1);
  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:country");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithTwoOr_ThenHasTwoResults) {
  BitmapIndex::Query query = { "", "", "country Berlin", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 2);
  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:country");
  BOOST_CHECK_EQUAL(getString(this->visitedElements[1]->tags[0].key), "addr:city");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithTwoOrPlusNot_ThenHasOneResult) {
  BitmapIndex::Query query = { "Berlin" , "", "Deutschland city", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 1);
  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:country");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithThreeOrPlusNotPlusAnd_ThenHasOneResult) {
  BitmapIndex::Query query = { "Berlin", "street", "Deutschland city Eichendorffstr", bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 1);
  BOOST_CHECK_EQUAL(getString(this->visitedElements[0]->tags[0].key), "addr:street");
}

BOOST_AUTO_TEST_CASE(GivenThreeElements_WhenQueryWithConflictingRules_ThenHasNoResult) {
  BitmapIndex::Query query = { "Deutschland Eichendorffstr",
                               "street addr",
                               "Deutschland Berlin Eichendorffstr",
                               bbox, lodRange };
  addThreeElements();

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 0);
}

BOOST_AUTO_TEST_CASE(GivenElement_WhenQueryWithPartiallyValidAndRule_ThenHasNoResult) {
  BitmapIndex::Query query = { "", "Kremlin Senate", "", bbox, lodRange };
  addToIndex({ { "name:en", "Kremlin Clock" } });

  index.search(query, *this);

  BOOST_CHECK_EQUAL(this->visitedElements.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: hexrain/utymap

max_issues_repo_name: hexrain/utymap

max_forks_repo_name: hexrain/utymap


text:
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <fstream>
#include <vector>
#include <cmath>

//#include <system.h>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

/* Keep the webcam from locking up when you interrupt a frame capture */
volatile int quit_signal=0;
#ifdef __unix__
#include <signal.h>
extern "C" void quit_signal_handler(int signum) {
 if (quit_signal!=0) exit(0); // just exit already
 quit_signal=1;
 printf("Will quit at next camera frame (repeat to kill now)\n");
}
#endif

int capture_video_spacebar(VideoCapture cap){
	unsigned int count = 0;
	namedWindow("Screen", CV_WINDOW_NORMAL);
	char setting = 'a';

	for(;;){  // Loop through, getting new images from the camera.
		//cout << "Setting " << setting + 'a' << endl;
		Mat frame;
		cap >> frame; // get a new frame from camera
		if (quit_signal) exit(0); // exit cleanly on interrupt

		imshow("Screen", frame);  // Show the image on the screen

		char key = waitKey(30);
		if (key == ' '){
			//cout << "setting is " << key + 0<< endl;
			cout << "space bar\n";
			ostringstream name;
			name << "calibrate_webcam/img" << count++ << ".jpg";
			string filename = name.str();
			imwrite(filename, frame);
			waitKey(1000);
		}else if(key == 'x'){
			return count;
		}
	}
}

void calibrate(int numImages, int numCornersHorizontal, int numCornersVertical, const char* intrinsic_name, const char* distortion_name){
	ofstream intrinsicFile;
	intrinsicFile.open(intrinsic_name);
	ofstream distortionParams;
	distortionParams.open(distortion_name);

// Task 2
	int numSquares = numCornersHorizontal * numCornersVertical;
	Size boardSize = Size(numCornersHorizontal, numCornersVertical);

	vector<vector<Point3f> > object_points;
	vector<vector<Point2f> > image_points;
	Mat image;

	vector<Point3f> obj;
	for(int j=0;j<numSquares;j++){
		obj.push_back(Point3f( j/numCornersHorizontal , j%numCornersHorizontal , 0.0f));
	}

	for (int i = 0; i < numImages; i++){
		vector<Point2f> pointBuf;
		ostringstream name;
		name << "calibrate_webcam/img" << i << ".jpg";
		string filename = name.str();
		image = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);

	// Find chessboard inner corners, 10 corners per row/7 per column
		bool found = findChessboardCorners(image, boardSize, pointBuf, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);

		if(found){
		// Find subpixels with the criteria
			TermCriteria criteria = TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.01 );
			cornerSubPix(image, pointBuf, Size(10,10), Size(-1, -1), criteria);
			drawChessboardCorners(image, cvSize(10,7), pointBuf, found);

			cvtColor(image, image, CV_GRAY2BGR);
			image_points.push_back(pointBuf);
			object_points.push_back(obj);
		// Draw the corners on a colored image
	/*	// Write the image
			//imwrite("Task_1.jpg", image[i]);

			//imshow("Screen", image[i]);
			//waitKey(100);*/
			std::cout << i + 1 << " processed " << pointBuf[0] << "\n";
		}
	}

	Mat intrinsic = Mat(3,3, CV_32FC1);
	Mat distCoeffs;
	Size imageSize = image.size();
	vector<Mat> rvecs, tvecs;
	intrinsic.ptr<double>(0)[0] = 1;
	intrinsic.ptr<double>(1)[1] = 1;

	calibrateCamera(object_points, image_points, imageSize, intrinsic, distCoeffs, rvecs, tvecs);
	std::cout << "Matrix is " << intrinsic << std::endl << distCoeffs << std::endl;

	for(int i = 0; i < 3; i++){
		for(int j =0; j < 3; j++){
			intrinsicFile << intrinsic.at<double>(i, j) << " ";
		}
	}

	for(int k = 0; k < 5; k++)
		distortionParams << distCoeffs.at<double>(k) << " ";

//	intrinsicFile << intrinsic;
//	distortionParams << distCoeffs;

	intrinsicFile.close();
	distortionParams.close();
	return;
}

int main(int argc, char** argv){
	VideoCapture cap(0); // open the default camera
	if(!cap.isOpened()){ // check if we succeeded
		return -1;
	}
	#ifdef __unix__
	   signal(SIGINT,quit_signal_handler); // listen for ctrl-C
	#endif

	int count = capture_video_spacebar(cap);

	int cornersHoriz = 9;
	int cornersVert = 7;
	calibrate(count, cornersHoriz, cornersVert, "intrinsic_webcam.txt", "distortion_webcam.txt");

// the camera will be deinitialized automatically in VideoCapture destructor

return 0;
}

ext: cpp


text:
/****************************************************************************
**
** Copyright (C) 2018 TU Wien, ACIN, Vision 4 Robotics (V4R) group
** Contact: v4r.acin.tuwien.ac.at
**
** This file is part of V4R
**
** V4R is distributed under dual licenses - GPLv3 or closed source.
**
** GNU General Public License Usage
** V4R is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** V4R is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** Please review the following information to ensure the GNU General Public
** License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
**
** Commercial License Usage
** If GPL is not suitable for your project, you must purchase a commercial
** license to use V4R. Licensees holding valid commercial V4R licenses may
** use this file in accordance with the commercial license agreement
** provided with the Software or, alternatively, in accordance with the
** terms contained in a written agreement between you and TU Wien, ACIN, V4R.
** For licensing terms and conditions please contact
** office<at>acin.tuwien.ac.at.
**
**
** The copyright holder additionally grants the author(s) of the file the right
** to use, copy, modify, merge, publish, distribute, sublicense, and/or
** sell copies of their contributions without any restrictions.
**
****************************************************************************/

/**
 * @file apply_auto_calibration.cpp
 * @author Georg Halmetschlager-Funek (gh@acin.tuwien.ac.at)
 * @date 2018
 * @brief
 *
 */

#include <memory.h>
#include <sys/stat.h>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/core/version.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#if CV_MAJOR_VERSION < 3
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/highgui/highgui.hpp>
#else
#include <opencv2/imgcodecs/imgcodecs.hpp>
#endif
#include <pcl/common/time.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <v4r/calibration/apply_calibration.h>
#include <v4r/common/img_loader.h>

namespace po = boost::program_options;
namespace ac = v4r::auto_calibration;

bool parseArgs(int argc, char** argv, std::string& param_file, std::string& folder, std::string& result, int& num_cams,
               bool& generate_cloud, bool& generate_depth, bool& generate_pseudo_depth, bool& tum_data);
void generatePseudoDepth(std::string result, int im_height, int im_width, std::shared_ptr<ac::apply_calibration> calib);

int main(int argc, char** argv) {
  std::string param_file, folder, result;
  bool generate_cloud, generate_depth, generate_pseudo_depth, tum_data;
  int num_cams = 0;
  int max_cams = 0;

  // get input arguments

  if (!parseArgs(argc, argv, param_file, folder, result, max_cams, generate_cloud, generate_depth,
                 generate_pseudo_depth, tum_data)) {
    return 0;
  }

  // Load RGB Images
  v4r::ImgContainer rgb_img_container;
  rgb_img_container.setPathToImages(folder + "/rgb/", "*.png");
  const std::vector<cv::Mat>& rgb_imgs = rgb_img_container.getImages();

  // Load Depth Images
  v4r::ImgContainer depth_img_container;
  depth_img_container.setPathToImages(folder + "/depth/", "*.png");
  const std::vector<cv::String>& filenames_depth = depth_img_container.getFileNames();
  const std::vector<cv::Mat>& depth_imgs = depth_img_container.getImages();

  // generate mutable depth images (will be converted to float an meter)
  std::vector<cv::Mat> mutable_depth(depth_imgs);
  num_cams = depth_imgs.size();

  if (num_cams > max_cams && max_cams > 0)
    num_cams = max_cams;

  int im_width = depth_imgs[0].cols;
  int im_height = depth_imgs[0].rows;

  int im_width_rgb = rgb_imgs[0].cols;
  int im_height_rgb = rgb_imgs[0].rows;

  //
  ac::apply_calibration calib(param_file);

  // Create Result Directory if it does not exist

  struct stat st;

  if (stat((result).c_str(), &st) == -1) {
    mkdir((result).c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
    std::cout << std::endl << "Creating directory for results: " << result << std::endl;
  } else {
    std::cout << std::endl << "Evaluation directory exists already: " << result << std::endl;
  }

  // If the user asked for pseud depth images (most likely to view the offset compensation for given distances):
  if (generate_pseudo_depth) {
    generatePseudoDepth(result, im_height, im_width, std::make_shared<ac::apply_calibration>(calib));
  }

  // For n (every) image, do
  for (int i = 0; i < num_cams; i++) {
    std::string filename = boost::filesystem::path(filenames_depth[i]).filename().string();
    std::string filename_noext = boost::filesystem::path(filenames_depth[i]).stem().string();

    // Convert depth to mm
    if (tum_data) {
      mutable_depth[i] = mutable_depth[i] * (0.001 / 5.);
    } else {
      mutable_depth[i] = mutable_depth[i] * 0.001;
    }

    // generate the point cloud
    if (generate_cloud) {
      pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>(im_width, im_height));
      {
        pcl::ScopeTime t1("Generating PointCloud");
        calib.GeneratePointCloud(&depth_imgs[i], &rgb_imgs[i], *cloud);
      }
      // save cloud
      pcl::io::savePCDFileBinaryCompressed(result + "/" + filename_noext + ".pcd", *cloud);
    }

    // generate the corrected and projected depth map (project depth map to rgb image)
    if (generate_depth) {
      cv::Mat projected_depth(im_height_rgb, im_width_rgb, CV_16U, cv::Scalar(0));
      {
        pcl::ScopeTime t1("Generating DepthMap");
        calib.GenerateDepthMap(&depth_imgs[i], projected_depth);
      }

      std::string base_filename = result + "/" + filename;
      // save image
      cv::imwrite(base_filename, projected_depth);
    }
  }
}

bool parseArgs(int argc, char** argv, std::string& param_file, std::string& folder, std::string& result, int& num_cams,
               bool& generate_cloud, bool& generate_depth, bool& generate_pseudo_depth, bool& tum_data) {
  po::options_description arguments(
      "Applies the results of a structure based auto calibration to a depth/rgb image/set. ");
  arguments.add_options()("help,h", "");
  arguments.add_options()("parameter_file,p", po::value<std::string>(&param_file)->default_value("./"),
                          "Path to parameter file");
  arguments.add_options()("img_folder,i ", po::value<std::string>(&folder)->default_value("./"),
                          "Path to image folders; structure: (/path/rgb/n.png /path/depth/n.png)");
  arguments.add_options()("result_folder,r", po::value<std::string>(&result)->default_value("./"),
                          "Path to result folder");
  arguments.add_options()("num_cams,n ", po::value<int>(&num_cams)->default_value(0), "Max Number of images");
  arguments.add_options()("cloud,c ", po::value<bool>(&generate_cloud)->default_value(false), "Generate cloud");
  arguments.add_options()("depth,d ", po::value<bool>(&generate_depth)->default_value(true), "Generate depth map");
  arguments.add_options()("pseudoDepth,g", po::value<bool>(&generate_pseudo_depth)->default_value(false),
                          "Generate Pseudo Depth maps for 0.5-5.5m");
  arguments.add_options()("TUMData,t", po::value<bool>(&tum_data)->default_value(false), "TUM Data (1m=5000)");

  po::options_description config("Other options");
  std::string config_file;

  config.add_options()("configfile,s", po::value<std::string>(&config_file), "Configuration file");

  po::options_description all("");
  all.add(arguments).add(config);
  po::options_description visible("");
  visible.add(arguments).add(config);
  po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).options(all).run(), vm);
  po::notify(vm);

  if (vm.count("configfile")) {
    std::ifstream ifs(config_file);
    if (ifs) {
      po::store(po::parse_config_file(ifs, all, true), vm);
      ifs.close();
    }

    else {
      std::cout << "Configuration file " << config_file << " cannot be opened!" << std::endl;
      return false;
    }
  }

  po::notify(vm);

  std::string usage = "General usage: program [-options] []";

  if (vm.count("help")) {
    std::cout << usage << std::endl;
    std::cout << visible;
    return false;
  }

  return true;
}

void generatePseudoDepth(std::string result, int im_height, int im_width,
                         std::shared_ptr<ac::apply_calibration> calib) {
  // generate result subdirectory
  std::string result_lattice;
  result_lattice = result + "/lattice/";
  struct stat st;

  if (stat((result_lattice).c_str(), &st) == -1) {
    mkdir((result_lattice).c_str(), S_IRUSR | S_IWUSR | S_IXUSR);
    std::cout << std::endl << "Creating directory for lattice: " << result << std::endl;
  } else {
    std::cout << std::endl << "Directory for lattice exists already: " << result << std::endl;
  }

  // generate 8 artificcal depth image with delta=0.5 starting from 0.5
  cv::Mat pseudo_depth(im_height, im_width, CV_32FC1, cv::Scalar(.5));
  std::vector<cv::Mat> depths;
  std::string filename = "pseudo_depth";
  for (int i = 0; i < 8; ++i) {
    pseudo_depth += 0.5;
    cv::Mat projected_depth(im_height, im_width, CV_16U, cv::Scalar(0));
    cv::Mat conv_depth;
    // Generate the depth map without projecting it to the rgb image = compensate depth error.
    calib->GenerateDepthMapNoProjection(&pseudo_depth, projected_depth);

    projected_depth.convertTo(conv_depth, CV_32FC1, 0.001);  ///(max-min));
    conv_depth -= pseudo_depth;
    depths.push_back(conv_depth);
  }

  // Colorize Image
  // First, find min and max over all images.
  double min = 0;
  double max = 0;
  cv::minMaxIdx(depths[0], &min, &max);
  for (size_t i = 1; i < depths.size(); ++i) {
    double temp_min, temp_max;
    cv::minMaxIdx(depths[i], &temp_min, &temp_max);

    if (temp_max > max) {
      max = temp_max;
    }
    if (temp_min < min) {
      min = temp_min;
    }
  }

  // alpha to convert image from float (m) to 0...255.
  double alpha;
  if (max == min) {
    alpha = 0;  // if min==max set image to 0.
  } else {
    alpha = 255.0 / (max - min);
  }

  for (size_t i = 0; i < depths.size(); ++i) {
    // Color
    cv::Mat conv;
    cv::Mat colored;

    // min, max of image for filename
    double min_img = 0;
    double max_img = 0;

    cv::minMaxIdx(depths[i], &min_img, &max_img);

    // Convert image and apply Colormap
    depths[i].convertTo(conv, CV_8UC3, alpha, -min * alpha);  ///(max-min));
    cv::applyColorMap(conv, colored, cv::COLORMAP_JET);

    // Save image
    cv::imwrite(result_lattice + "/" + filename + "_" + std::to_string(float(i) / 2. + 0.5) + "m_min_" +
                    std::to_string(min_img) + "_max_" + std::to_string(max_img) + ".png",
                colored);
  }
}


text:
#include <boost/numeric/odeint.hpp>

typedef std::vector< double > state_type;

const double gam = 0.15;

void harmonic_oscillator( const state_type &x , state_type &dxdt , const double /* t */ )
{
    dxdt[0] = x[1];
    dxdt[1] = -x[0] - gam*x[1];
}

int main()
{
  state_type x(2);
  x[0] = 1.0; // start at x=1.0, p=0.0
  x[1] = 0.0;

  using namespace boost::numeric::odeint;
  size_t steps = integrate( harmonic_oscillator, x, 0.0, 10.0, 0.1 );
  if(steps == 0)
    return 1;

  return 0;
}

ext: cc


text:
//
// Created by victor on 11/22/17.
//
#include "GiphySearchRequestHandler.h"
#include "Validations.h"
#include <glog/logging.h>
#include <proxygen/httpserver/ResponseBuilder.h>
#include <proxygen/lib/utils/URL.h>
#include <proxygen/lib/http/session/HTTPUpstreamSession.h>
#include <folly/io/async/EventBaseManager.h>
#include <boost/algorithm/string.hpp>
#include <folly/json.h>
#include <folly/SocketAddress.h>
#include <folly/futures/Promise.h>
#include <folly/executors/GlobalExecutor.h>

using std::string;
using proxygen::HTTPMethod;
using proxygen::HTTPMessage;
using proxygen::HTTPHeaders;
using proxygen::HTTPHeaderCode;
using proxygen::ResponseBuilder;
using folly::HHWheelTimer;

namespace {

class invalid_giphy_path : public std::domain_error {
 public:
  invalid_giphy_path() : domain_error("path for giphy endpoint is invalid") {}
};
}

namespace restdbxx {
void GiphySearchRequestHandler::onRequest(std::unique_ptr<HTTPMessage> headers) noexcept {
  using std::string;
  _request = std::move(headers);
  std::string urlStr = "unknown url";

  folly::SocketAddress addr; //(_giphyRequest->getDstAddress());
  try {
    urlStr = buildGiphyRequest();
    proxygen::URL url(urlStr);
    addr.setFromHostPort(url.getHost(), url.getPort());
  } catch (const invalid_giphy_path &e) {

    ResponseBuilder(downstream_)
        .status(404, "not found")
        .body(folly::to<string>("invalid path: ",
                                urlStr))
        .sendWithEOM();
    return;
  } catch (...) {
    ResponseBuilder(downstream_)
        .status(503, "Bad Gateway")
        .body(folly::to<string>("Could not parse server from URL: ",
                                urlStr))
        .sendWithEOM();
    return;
  }

//  downstream_->pauseIngress();
  VLOG(google::GLOG_INFO) << "Trying to connect to " << addr;
  auto evb = folly::EventBaseManager::get()->getEventBase();

  // A more sophisticated proxy would have a connection pool here
  const folly::AsyncSocket::OptionMap opts{
      {{SOL_SOCKET, SO_REUSEADDR}, 1}};
  downstream_->pauseIngress();
  _connector.connect(evb, addr,
                     std::chrono::milliseconds(1000),
                     opts);
}
string GiphySearchRequestHandler::buildGiphyRequest() {
  const static std::map<string, string> paths_map = {
      {"/search", "http://api.giphy.com/v1/gifs/search"},
      {"/trending", "http://api.giphy.com/v1/gifs/trending"},
      {"/random", "http://api.giphy.com/v1/gifs/random"}
  };

  string urlStr =
      "http://api.giphy.com/v1/gifs/search";
  std::string path = _request->getPath();
  boost::erase_first(path, _mount_path);
  auto found = paths_map.find(path);
  if (found != paths_map.end()) {
    urlStr = found->second;
  } else {
    throw invalid_giphy_path();
  }
  std::string q = _request->getDecodedQueryParam("q");
  int limit = _request->hasQueryParam("limit") ? _request->getIntQueryParam("limit", 100) : 100;
  const std::map<string, string> param_map = _request->getQueryParams();
  if (param_map.find("format") != param_map.end()) {
    std::string format = param_map.at("format");
    boost::to_upper(format);
    if (format == "HTML") {
      output_format = HTML;
    }
  }
  _giphyRequest = new HTTPMessage();
  _giphyRequest->setMethod(HTTPMethod::GET);
  _giphyRequest->setURL(urlStr);
  _giphyRequest->setQueryParam("api_key", _api_key);
  _giphyRequest->setQueryParam("limit", std::__cxx11::to_string(limit));
  _giphyRequest->setQueryParam("offset", "0");
  _giphyRequest->setQueryParam("rating", "R");
  _giphyRequest->setQueryParam("lang", "en");
  _giphyRequest->setQueryParam("q", q);
  return urlStr;
}
void GiphySearchRequestHandler::onBody(std::unique_ptr<folly::IOBuf> body) noexcept {
//  if (txn)
}
void GiphySearchRequestHandler::onUpgrade(proxygen::UpgradeProtocol prot) noexcept {

}
void GiphySearchRequestHandler::onEOM() noexcept {

}
void GiphySearchRequestHandler::requestComplete()noexcept {

}
void GiphySearchRequestHandler::onError(proxygen::ProxygenError err)noexcept {

}
void GiphySearchRequestHandler::connectSuccess(proxygen::HTTPUpstreamSession *session) noexcept {
  VLOG(google::INFO) << "Established " << *session;
  _session = std::make_unique<SessionWrapper>(session);
  _txn = session->newTransaction(&_serverHandler);
  LOG(INFO) << "Sending client request: " << _giphyRequest->getURL()
            << " to server";
  _giphyRequest->getHeaders().add(HTTPHeaderCode::HTTP_HEADER_ALLOW, "*");

  _giphyRequest->getHeaders().add(HTTPHeaderCode::HTTP_HEADER_ORIGIN, "localhost");
  _giphyRequest->getHeaders().add(HTTPHeaderCode::HTTP_HEADER_HOST, "api.giphy.com");
  _giphyRequest->dumpMessage(google::INFO);
  _txn->sendHeadersWithEOM(*_giphyRequest);
  downstream_->resumeIngress();
}
void GiphySearchRequestHandler::connectError(const folly::AsyncSocketException &ex) noexcept {
  VLOG(google::GLOG_INFO) << "connect error -- " << ex.what();
}
void GiphySearchRequestHandler::detachServerTransaction() noexcept {
  VLOG(google::GLOG_INFO) << "detached txn";

}
void GiphySearchRequestHandler::onServerHeadersComplete(std::unique_ptr<HTTPMessage> msg) noexcept {
//  CHECK(!clientTerminated_);
  VLOG(google::INFO) << "Forwarding " << msg->getStatusCode() << " response to client";
  if (output_format == JSON) downstream_->sendHeaders(*msg);
}
void GiphySearchRequestHandler::onServerBody(std::unique_ptr<folly::IOBuf> chain) noexcept {
//  CHECK(!clientTerminated_);
  LOG(INFO) << "Forwarding " <<
            ((chain) ? chain->computeChainDataLength() : 0) << " body bytes to client";
  if (output_format == JSON) {
    downstream_->sendBody(std::move(chain));
    return;
  }
  if (_giphyBody) {
    _giphyBody->prependChain(std::move(chain));
  } else {
    _giphyBody = std::move(chain);
  }
}

void GiphySearchRequestHandler::onServerEOM() noexcept {
  LOG(INFO) << "end of giphy response";
  if (output_format == HTML) {
    folly::Promise<folly::dynamic> promise;
    auto f = promise.getFuture();
    folly::EventBaseManager::get()->getEventBase()
        ->runInLoop([p = std::move(promise), this]() mutable {
          p.setTry(parseGiphyBody());
        });

    f.then([this](folly::dynamic &giphy_obj) {
      LOG(INFO) << folly::toPrettyJson(giphy_obj);
      std::stringstream ss;
      ss << ""
         << "<title>" << "Giphy query"
         << "</title>"
         << ""
         << ""
         << "";
      if (giphy_obj.find("data") != giphy_obj.items().end()) {
        folly::dynamic &data = giphy_obj.at("data");
        if (data.isArray()) {
          ss << "
";
          for (auto &item: data) {
            ss << "
"
               << "<img src=\""
               << item.at("images").at("downsized").at("url")
               << "\" >"
               << "
";
          }
          ss << "
";
        }
      }
      ss << "";
      return ss.str();
    }).then([this](string &html) {

      ResponseBuilder(downstream_)
          .status(200, "OK")
          .body(std::move(html))
          .sendWithEOM();
    });
    //auto giphy_obj = folly::parseJson(_giphy_json_str);

  }
}
void GiphySearchRequestHandler::onServerError(const proxygen::HTTPException &error) noexcept {
  VLOG(google::GLOG_INFO) << "server error";

  ResponseBuilder(downstream_)
      .status(500, "internal error")
      .body(error.describe())
      .sendWithEOM();
}
void GiphySearchRequestHandler::onServerEgressPaused() noexcept {

}
void GiphySearchRequestHandler::onServerEgressResumed() noexcept {

}
folly::Try<folly::dynamic> GiphySearchRequestHandler::parseGiphyBody() {
  auto f = [b = _giphyBody->cloneCoalesced()]() {
    if (!b) {
      throw std::runtime_error("empty giphy body");
    }
    std::string piece(reinterpret_cast<const char *>(b->data()), b->length());
    return folly::parseJson(piece);
  };
  return folly::makeTryWith(f);
}
void GiphySearchRequestHandler::ServerTxnHandler::setTransaction(proxygen::HTTPTransaction *txn) noexcept {

}
void GiphySearchRequestHandler::ServerTxnHandler::detachTransaction() noexcept {
  parent.detachServerTransaction();
}
void GiphySearchRequestHandler::ServerTxnHandler::onHeadersComplete(std::unique_ptr<proxygen::HTTPMessage> msg) noexcept {
  parent.onServerHeadersComplete(std::move(msg));
}
void GiphySearchRequestHandler::ServerTxnHandler::onBody(std::unique_ptr<folly::IOBuf> chain) noexcept {
  parent.onServerBody(std::move(chain));
}
void GiphySearchRequestHandler::ServerTxnHandler::onTrailers(std::unique_ptr<proxygen::HTTPHeaders> trailers) noexcept {
//  parent.onser
}
void GiphySearchRequestHandler::ServerTxnHandler::onEOM() noexcept {
  parent.onServerEOM();
}
void GiphySearchRequestHandler::ServerTxnHandler::onUpgrade(proxygen::UpgradeProtocol protocol) noexcept {

}
void GiphySearchRequestHandler::ServerTxnHandler::onError(const proxygen::HTTPException &error) noexcept {
  parent.onServerError(error);
}
void GiphySearchRequestHandler::ServerTxnHandler::onEgressPaused() noexcept {
  parent.onServerEgressPaused();
}
void GiphySearchRequestHandler::ServerTxnHandler::onEgressResumed() noexcept {
  parent.onServerEgressPaused();
}
void GiphySearchRequestHandlerFactory::onServerStart(folly::EventBase *evb) noexcept {
  timer_->timer = HHWheelTimer::newTimer(
      evb,
      std::chrono::milliseconds(HHWheelTimer::DEFAULT_TICK_INTERVAL),
      folly::AsyncTimeout::InternalEnum::NORMAL,
      std::chrono::seconds(1));
}
void GiphySearchRequestHandlerFactory::onServerStop() noexcept {
  timer_->timer.reset();
}
proxygen::RequestHandler *GiphySearchRequestHandlerFactory::onRequest(proxygen::RequestHandler *handler,
                                                                      HTTPMessage *message) noexcept {
  std::string path = message->getPath();
  Validations::sanitize_path(path);
  if (boost::algorithm::starts_with(path, mount_path)) {
    return new GiphySearchRequestHandler(mount_path, giphy_api_key, timer_->timer.get());
  }
  return handler;
}
GiphySearchRequestHandlerFactory::GiphySearchRequestHandlerFactory(const string &mount_path) : mount_path(mount_path) {}
GiphySearchRequestHandlerFactory::GiphySearchRequestHandlerFactory(const string &mount_path,
                                                                   const string &giphy_api_key)
    : mount_path(mount_path), giphy_api_key(giphy_api_key) {}
}

max_stars_repo_name: baskeboler/restdbxx

max_issues_repo_name: baskeboler/restdbxx

max_forks_repo_name: baskeboler/restdbxx


text:
// ----------------------------------------------------------------------------
// parsing.hpp :  implementation of the parsing member functions
//                      ( parse, parse_printf_directive)
// ----------------------------------------------------------------------------

//  Copyright Samuel Krempp 2003. Use, modification, and distribution are
//  subject to the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

// see http://www.boost.org/libs/format for library home page

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

#ifndef BOOST_FORMAT_PARSING_HPP
#define BOOST_FORMAT_PARSING_HPP

#include <boost/format/format_class.hpp>
#include <boost/format/exceptions.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>

namespace boost {
namespace io {
namespace detail {

#if defined(BOOST_NO_STD_LOCALE)
    // streams will be used for narrow / widen. but these methods are not const
    template<class T>
    T& const_or_not(const T& x) {
        return const_cast<T&> (x);
    }
#else
    template<class T>
    const T& const_or_not(const T& x) {
        return x;
    }
#endif

    template<class Ch, class Facet> inline
    char wrap_narrow(const Facet& fac, Ch c, char deflt) {
        return const_or_not(fac).narrow(c, deflt);
    }

    template<class Ch, class Facet> inline
    bool wrap_isdigit(const Facet& fac, Ch c) {
#if ! defined( BOOST_NO_LOCALE_ISDIGIT )
        return fac.is(std::ctype<Ch>::digit, c);
# else
        ignore_unused(fac);
        using namespace std;
        return isdigit(c) != 0;
#endif
    }

    template<class Iter, class Facet>
    Iter wrap_scan_notdigit(const Facet & fac, Iter beg, Iter end) {
        using namespace std;
        for( ; beg!=end && wrap_isdigit(fac, *beg); ++beg) ;
        return beg;
    }

    // Input : [start, last) iterators range and a
    //          a Facet to use its widen/narrow member function
    // Effects : read sequence and convert digits into integral n, of type Res
    // Returns : n
    template<class Res, class Iter, class Facet>
    Iter str2int (const Iter & start, const Iter & last, Res & res,
                 const Facet& fac)
    {
        using namespace std;
        Iter it;
        res=0;
        for(it=start; it != last && wrap_isdigit(fac, *it); ++it ) {
            char cur_ch = wrap_narrow(fac, *it, 0); // cant fail.
            res *= 10;
            res += cur_ch - '0'; // 22.2.1.1.2.13 of the C++ standard
        }
        return it;
    }

    // auxiliary func called by parse_printf_directive
    // for centralising error handling
    // it either throws if user sets the corresponding flag, or does nothing.
    inline void maybe_throw_exception(unsigned char exceptions,
                                      std::size_t pos, std::size_t size)
    {
        if(exceptions & io::bad_format_string_bit)
            boost::throw_exception(io::bad_format_string(pos, size) );
    }

    // Input: the position of a printf-directive in the format-string
    //    a basic_ios& merely to use its widen/narrow member function
    //    a bitset'exceptions' telling whether to throw exceptions on errors.
    // Returns:
    //  true if parse succeeded (ignore some errors if exceptions disabled)
    //  false if it failed so bad that the directive should be printed verbatim
    // Effects:
    //  start is incremented so that *start is the first char after
    //     this directive
    //  *fpar is set with the parameters read in the directive
    template<class Ch, class Tr, class Alloc, class Iter, class Facet>
    bool parse_printf_directive(Iter & start, const Iter& last,
                                detail::format_item<Ch, Tr, Alloc> * fpar,
                                const Facet& fac,
                                std::size_t offset, unsigned char exceptions)
    {
        typedef typename basic_format<Ch, Tr, Alloc>::format_item_t format_item_t;

        fpar->argN_ = format_item_t::argN_no_posit;  // if no positional-directive
        bool precision_set = false;
        bool in_brackets=false;
        Iter start0 = start;
        std::size_t fstring_size = last-start0+offset;
        char mssiz = 0;

        if(start>= last) { // empty directive : this is a trailing %
                maybe_throw_exception(exceptions, start-start0 + offset, fstring_size);
                return false;
        }

        if(*start== const_or_not(fac).widen( '|')) {
            in_brackets=true;
            if( ++start >= last ) {
                maybe_throw_exception(exceptions, start-start0 + offset, fstring_size);
                return false;
            }
        }

        // the flag '0' would be picked as a digit for argument order, but here it's a flag :
        if(*start== const_or_not(fac).widen( '0'))
            goto parse_flags;

        // handle argument order (%2$d)  or possibly width specification: %2d
        if(wrap_isdigit(fac, *start)) {
            int n;
            start = str2int(start, last, n, fac);
            if( start >= last ) {
                maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
                return false;
            }

            // %N% case : this is already the end of the directive
            if( *start ==  const_or_not(fac).widen( '%') ) {
                fpar->argN_ = n-1;
                ++start;
                if( in_brackets)
                    maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
                return true;
            }

            if ( *start== const_or_not(fac).widen( '$') ) {
                fpar->argN_ = n-1;
                ++start;
            }
            else {
                // non-positional directive
                fpar->fmtstate_.width_ = n;
                fpar->argN_  = format_item_t::argN_no_posit;
                goto parse_precision;
            }
        }

      parse_flags:
        // handle flags
        while (start != last) { // as long as char is one of + - = _ # 0 or ' '
            switch ( wrap_narrow(fac, *start, 0)) {
                case '\'':
                    break; // no effect yet. (painful to implement)
                case '-':
                    fpar->fmtstate_.flags_ |= std::ios_base::left;
                    break;
                case '=':
                    fpar->pad_scheme_ |= format_item_t::centered;
                    break;
                case '_':
                    fpar->fmtstate_.flags_ |= std::ios_base::internal;
                    break;
                case ' ':
                    fpar->pad_scheme_ |= format_item_t::spacepad;
                    break;
                case '+':
                    fpar->fmtstate_.flags_ |= std::ios_base::showpos;
                    break;
                case '0':
                    fpar->pad_scheme_ |= format_item_t::zeropad;
                    // need to know alignment before really setting flags,
                    // so just add 'zeropad' flag for now, it will be processed later.
                    break;
                case '#':
                    fpar->fmtstate_.flags_ |= std::ios_base::showpoint | std::ios_base::showbase;
                    break;
                default:
                    goto parse_width;
            }
            ++start;
        } // loop on flag.

        if( start>=last) {
            maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
            return true;
        }

      // first skip 'asterisk fields' : * or num (length)
      parse_width:
        if(*start == const_or_not(fac).widen( '*') )
            ++start;
        else if(start!=last && wrap_isdigit(fac, *start))
            start = str2int(start, last, fpar->fmtstate_.width_, fac);

      parse_precision:
        if( start>= last) {
            maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
            return true;
        }
        // handle precision spec
        if (*start== const_or_not(fac).widen( '.')) {
            ++start;
            if(start != last && *start == const_or_not(fac).widen( '*') )
                ++start;
            else if(start != last && wrap_isdigit(fac, *start)) {
                start = str2int(start, last, fpar->fmtstate_.precision_, fac);
                precision_set = true;
            }
            else
                fpar->fmtstate_.precision_ =0;
        }

      // argument type modifiers
        while (start != last) {
            switch (wrap_narrow(fac, *start, 0)) {
                case 'h':
                case 'l':
                case 'j':
                case 'z':
                case 'L':
                    // boost::format ignores argument type modifiers as it relies on
                    // the type of the argument fed into it by operator %
                    break;

                // Note that the ptrdiff_t argument type 't' from C++11 is not honored
                // because it was already in use as the tabulation specifier in boost::format
                // case 't':

                // Microsoft extensions:
                // https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx

                case 'w':
                    break;
                case 'I':
                    mssiz = 'I';
                    break;
                case '3':
                    if (mssiz != 'I') {
                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
                        return true;
                    }
                    mssiz = '3';
                    break;
                case '2':
                    if (mssiz != '3') {
                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
                        return true;
                    }
                    mssiz = 0x00;
                    break;
                case '6':
                    if (mssiz != 'I') {
                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
                        return true;
                    }
                    mssiz = '6';
                    break;
                case '4':
                    if (mssiz != '6') {
                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
                        return true;
                    }
                    mssiz = 0x00;
                    break;
                default:
                    if (mssiz && mssiz == 'I') {
                        mssiz = 0;
                    }
                    goto parse_conversion_specification;
            }
            ++start;
        } // loop on argument type modifiers to pick up 'hh', 'll', and the more complex microsoft ones

      parse_conversion_specification:
        if (start >= last || mssiz) {
            maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
            return true;
        }

        if( in_brackets && *start== const_or_not(fac).widen( '|') ) {
            ++start;
            return true;
        }

        // The default flags are "dec" and "skipws"
        // so if changing the base, need to unset basefield first

        switch (wrap_narrow(fac, *start, 0))
        {
            // Boolean
            case 'b':
                fpar->fmtstate_.flags_ |= std::ios_base::boolalpha;
                break;

            // Decimal
            case 'u':
            case 'd':
            case 'i':
                // Defaults are sufficient
                break;

            // Hex
            case 'X':
                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
                BOOST_FALLTHROUGH;
            case 'x':
            case 'p': // pointer => set hex.
                fpar->fmtstate_.flags_ &= ~std::ios_base::basefield;
                fpar->fmtstate_.flags_ |= std::ios_base::hex;
                break;

            // Octal
            case 'o':
                fpar->fmtstate_.flags_ &= ~std::ios_base::basefield;
                fpar->fmtstate_.flags_ |= std::ios_base::oct;
                break;

            // Floating
            case 'A':
                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
                BOOST_FALLTHROUGH;
            case 'a':
                fpar->fmtstate_.flags_ &= ~std::ios_base::basefield;
                fpar->fmtstate_.flags_ |= std::ios_base::fixed;
                fpar->fmtstate_.flags_ |= std::ios_base::scientific;
                break;
            case 'E':
                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
                BOOST_FALLTHROUGH;
            case 'e':
                fpar->fmtstate_.flags_ |= std::ios_base::scientific;
                break;
            case 'F':
                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
                BOOST_FALLTHROUGH;
            case 'f':
                fpar->fmtstate_.flags_ |= std::ios_base::fixed;
                break;
            case 'G':
                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
                BOOST_FALLTHROUGH;
            case 'g':
                // default flags are correct here
                break;

            // Tabulation (a boost::format extension)
            case 'T':
                ++start;
                if( start >= last) {
                    maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
                    return false;
                } else {
                    fpar->fmtstate_.fill_ = *start;
                }
                fpar->pad_scheme_ |= format_item_t::tabulation;
                fpar->argN_ = format_item_t::argN_tabulation;
                break;
            case 't':
                fpar->fmtstate_.fill_ = const_or_not(fac).widen( ' ');
                fpar->pad_scheme_ |= format_item_t::tabulation;
                fpar->argN_ = format_item_t::argN_tabulation;
                break;

            // Character
            case 'C':
            case 'c':
                fpar->truncate_ = 1;
                break;

            // String
            case 'S':
            case 's':
                if(precision_set) // handle truncation manually, with own parameter.
                    fpar->truncate_ = fpar->fmtstate_.precision_;
                fpar->fmtstate_.precision_ = 6; // default stream precision.
                break;

            // %n is insecure and ignored by boost::format
            case 'n' :
                fpar->argN_ = format_item_t::argN_ignored;
                break;

            default:
                maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
        }
        ++start;

        if( in_brackets ) {
            if( start != last && *start== const_or_not(fac).widen( '|') ) {
                ++start;
                return true;
            }
            else  maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
        }
        return true;
    }
    // -end parse_printf_directive()

    template<class String, class Facet>
    int upper_bound_from_fstring(const String& buf,
                                 const typename String::value_type arg_mark,
                                 const Facet& fac,
                                 unsigned char exceptions)
    {
        // quick-parsing of the format-string to count arguments mark (arg_mark, '%')
        // returns : upper bound on the number of format items in the format strings
        using namespace boost::io;
        typename String::size_type i1=0;
        int num_items=0;
        while( (i1=buf.find(arg_mark,i1)) != String::npos ) {
            if( i1+1 >= buf.size() ) {
                if(exceptions & bad_format_string_bit)
                    boost::throw_exception(bad_format_string(i1, buf.size() )); // must not end in ".. %"
                else {
                  ++num_items;
                  break;
                }
            }
            if(buf[i1+1] == buf[i1] ) {// escaped "%%"
                i1+=2; continue;
            }

            ++i1;
            // in case of %N% directives, dont count it double (wastes allocations..) :
            i1 = detail::wrap_scan_notdigit(fac, buf.begin()+i1, buf.end()) - buf.begin();
            if( i1 < buf.size() && buf[i1] == arg_mark )
                ++i1;
            ++num_items;
        }
        return num_items;
    }
    template<class String> inline
    void append_string(String& dst, const String& src,
                       const typename String::size_type beg,
                       const typename String::size_type end) {
        dst.append(src.begin()+beg, src.begin()+end);
    }

} // detail namespace
} // io namespace

// -----------------------------------------------
//  format :: parse(..)

    template<class Ch, class Tr, class Alloc>
    basic_format<Ch, Tr, Alloc>& basic_format<Ch, Tr, Alloc>::
    parse (const string_type& buf) {
        // parse the format-string
        using namespace std;
#if !defined(BOOST_NO_STD_LOCALE)
        const std::ctype<Ch> & fac = BOOST_USE_FACET( std::ctype<Ch>, getloc());
#else
        io::basic_oaltstringstream<Ch, Tr, Alloc> fac;
        //has widen and narrow even on compilers without locale
#endif

        const Ch arg_mark = io::detail::const_or_not(fac).widen( '%');
        bool ordered_args=true;
        int max_argN=-1;

        // A: find upper_bound on num_items and allocates arrays
        int num_items = io::detail::upper_bound_from_fstring(buf, arg_mark, fac, exceptions());
        make_or_reuse_data(num_items);

        // B: Now the real parsing of the format string :
        num_items=0;
        typename string_type::size_type i0=0, i1=0;
        typename string_type::const_iterator it;
        bool special_things=false;
        int cur_item=0;
        while( (i1=buf.find(arg_mark,i1)) != string_type::npos ) {
            string_type & piece = (cur_item==0) ? prefix_ : items_[cur_item-1].appendix_;
            if( buf[i1+1] == buf[i1] ) { // escaped mark, '%%'
                io::detail::append_string(piece, buf, i0, i1+1);
                i1+=2; i0=i1;
                continue;
            }
            BOOST_ASSERT(  static_cast<unsigned int>(cur_item) < items_.size() || cur_item==0);

            if(i1!=i0) {
                io::detail::append_string(piece, buf, i0, i1);
                i0=i1;
            }
            ++i1;
            it = buf.begin()+i1;
            bool parse_ok = io::detail::parse_printf_directive(
                it, buf.end(), &items_[cur_item], fac, i1, exceptions());
            i1 = it - buf.begin();
            if( ! parse_ok ) // the directive will be printed verbatim
                continue;
            i0=i1;
            items_[cur_item].compute_states(); // process complex options, like zeropad, into params

            int argN=items_[cur_item].argN_;
            if(argN == format_item_t::argN_ignored)
                continue;
            if(argN ==format_item_t::argN_no_posit)
                ordered_args=false;
            else if(argN == format_item_t::argN_tabulation) special_things=true;
            else if(argN > max_argN) max_argN = argN;
            ++num_items;
            ++cur_item;
        } // loop on %'s
        BOOST_ASSERT(cur_item == num_items);

        // store the final piece of string
        {
            string_type & piece = (cur_item==0) ? prefix_ : items_[cur_item-1].appendix_;
            io::detail::append_string(piece, buf, i0, buf.size());
        }

        if( !ordered_args) {
            if(max_argN >= 0 ) {  // dont mix positional with non-positionnal directives
                if(exceptions() & io::bad_format_string_bit)
                    boost::throw_exception(
                        io::bad_format_string(static_cast<std::size_t>(max_argN), 0));
                // else do nothing. => positionnal arguments are processed as non-positionnal
            }
            // set things like it would have been with positional directives :
            int non_ordered_items = 0;
            for(int i=0; i< num_items; ++i)
                if(items_[i].argN_ == format_item_t::argN_no_posit) {
                    items_[i].argN_ = non_ordered_items;
                    ++non_ordered_items;
                }
            max_argN = non_ordered_items-1;
        }

        // C: set some member data :
        items_.resize(num_items, format_item_t(io::detail::const_or_not(fac).widen( ' ')) );

        if(special_things) style_ |= special_needs;
        num_args_ = max_argN + 1;
        if(ordered_args) style_ |=  ordered;
        else style_ &= ~ordered;
        return *this;
    }

} // namespace boost

#endif //  BOOST_FORMAT_PARSING_HPP

ext: hpp


text:
//==============================================================================
//         Copyright 2003 - 2011 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//         Copyright 2012 - 2014 MetaScale SAS
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_IEEE_FUNCTIONS_SCALAR_EXPONENTBITS_HPP_INCLUDED
#define BOOST_SIMD_IEEE_FUNCTIONS_SCALAR_EXPONENTBITS_HPP_INCLUDED

#include <boost/simd/ieee/functions/exponentbits.hpp>
#include <boost/dispatch/meta/as_integer.hpp>
#include <boost/simd/include/functions/scalar/bitwise_and.hpp>
#include <boost/simd/include/constants/maxexponent.hpp>
#include <boost/simd/include/constants/nbmantissabits.hpp>
#include <boost/dispatch/attributes.hpp>

namespace boost { namespace simd { namespace ext
{
  BOOST_DISPATCH_IMPLEMENT          ( exponentbits_, tag::cpu_
                                    , (A0)
                                    , (scalar_< floating_<A0> >)
                                    )
  {
    typedef typename dispatch::meta::as_integer<A0>::type result_type;
    BOOST_FORCEINLINE BOOST_SIMD_FUNCTOR_CALL(1)
    {
      return b_and((2*Maxexponent<A0>()+1)<<Nbmantissabits<A0>(), a0);
    }
  };
} } }

#endif


text:
// Copyright 2019 Xanadu Quantum Technologies Inc.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
 * @file
 * Contains functions for approximating the hafnian of a matrix
 * in a classically efficient manner, for certains classes of matrices.
 */

#pragma once
#include <stdafx.h>
#include <numeric>
#include <random>
#include <cmath>

#ifdef LAPACKE
#define EIGEN_SUPERLU_SUPPORT
#define EIGEN_USE_BLAS
#define EIGEN_USE_LAPACKE

#define LAPACK_COMPLEX_CUSTOM
#define lapack_complex_float std::complex<float>
#define lapack_complex_double std::complex<double>
#endif

#include <Eigen/Eigenvalues>

namespace libwalrus {

/**
* Returns the approximation to the hafnian of a matrix with non-negative entries.
*
* The approximation follows an stochastic algorithm according to which the hafnian
* can be approximated as the sum of determinants of matrices.
* The accuracy of the approximation increases with increasing number of iterations.
*
* @param mat vector representing the flattened matrix
* @param nsamples positive integer representing the number of samples to perform
* @return the approximate hafnian
*/
template <typename T>
inline long double hafnian_nonneg(std::vector<T> &mat, int &nsamples) {
    int n = std::sqrt(static_cast<double>(mat.size()));

    long double mean = 0;
    long double stdev = 1;

    namespace eg = Eigen;
    eg::Matrix<T, eg::Dynamic, eg::Dynamic> A = eg::Map<eg::Matrix<T, eg::Dynamic, eg::Dynamic>, eg::Unaligned>(mat.data(), n, n);

#ifdef _OPENMP
    int nthreads = omp_get_max_threads();
    omp_set_num_threads(nthreads);
#else
    int nthreads = 1;
#endif

    std::vector<int> threadbound_low(nthreads);
    std::vector<int> threadbound_hi(nthreads);

    std::default_random_engine generator;
    std::normal_distribution<double> distribution(mean, stdev);

    std::vector<long double> determinants(nsamples);

    #pragma omp parallel for shared(determinants)
    for (int k = 0; k < nsamples; k++) {
        std::vector<T> matrand(n * n, 0);
        std::vector<T> g(n * n, 0);
        std::vector<T> gt(n * n, 0);
        eg::Matrix<T, eg::Dynamic, eg::Dynamic> W;
        W.resize(n, n);

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                long double randnum = distribution(generator);
                matrand[i * n + j] = static_cast<T>(randnum);
                g[i * n + j] = 0.0;
                gt[i * n + j] = 0.0;
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                g[i * n + j] = matrand[i * n + j];
                gt[j * n + i] = matrand[i * n + j];
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int id = i * n + j;
                W(i, j) = (g[id] - gt[id]) * std::sqrt(std::abs(A(i, j)));
            }
        }

        long double det = std::real(W.determinant());

        determinants[k] = det;
    }

    long double final = 0.0;

    for (int i = 0; i < nsamples; i++) {
        final += determinants[i];
    }

    final = final / (static_cast<long double>(nsamples));

    return final;

}

/**
* Returns the approximation to the hafnian of a matrix with non-negative entries.
*
* The approximation follows an stochastic algorithm according to which the hafnian
* can be approximated as the sum of determinants of matrices.
* The accuracy of the approximation increases with increasing number of iterations.
*
* This is a wrapper around the templated function `libwalrus::hafnian_nonneg` for Python
* integration. It accepts and returns double numeric types, and
* returns sensible values for empty and non-even matrices.
*
* In addition, this wrapper function automatically casts all matrices
* to type `long double`, allowing for greater precision than supported
* by Python and NumPy.
*
* @param mat vector representing the flattened matrix
* @param nsamples positive integer representing the number of samples to perform
* @return the approximate hafnian
*/
double hafnian_approx(std::vector<double> &mat, int &nsamples) {
    std::vector<long double> matq(mat.begin(), mat.end());
    int n = std::sqrt(static_cast<double>(mat.size()));
    long double haf;

    if (n == 0)
        haf = 1.0;
    else if (n % 2 != 0)
        haf = 0.0;
    else
        haf = hafnian_nonneg(matq, nsamples);

    return static_cast<double>(haf);
}

}

max_stars_repo_name: NunoEdgarGFlowHub/thewalrus

max_issues_repo_name: NunoEdgarGFlowHub/thewalrus

max_forks_repo_name: NunoEdgarGFlowHub/thewalrus


text:
#define BOOST_TEST_DYN_LINK
#include <canard/net/ofp/v13/common/oxm_match_field.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>

#include <stdexcept>
#include <boost/optional/optional.hpp>
#include <boost/optional/optional_io.hpp>

namespace of = canard::net::ofp;
namespace v13 = of::v13;
namespace match = v13::oxm_match_fields;

namespace proto = v13::protocol;

namespace bdata = boost::unit_test::data;

BOOST_AUTO_TEST_SUITE(oxm_match_test)
BOOST_AUTO_TEST_SUITE(ipv6_flabel_test)

    BOOST_DATA_TEST_CASE(
              no_mask_create_success_test
            , bdata::make(std::vector<std::uint32_t>{0x00000000, 0x000fffff})
            , value)
    {
        auto const sut = match::ipv6_flabel::create(value);

        BOOST_TEST(sut.oxm_length() == sizeof(std::uint32_t));
        BOOST_TEST(sut.oxm_value() == value);
        BOOST_TEST(!sut.oxm_hasmask());
        BOOST_TEST(sut.oxm_mask() == boost::none);
        BOOST_TEST(sut.length()
                == sizeof(std::uint32_t) + sizeof(std::uint32_t));
        BOOST_TEST(!sut.is_wildcard());
        BOOST_TEST(sut.is_exact());
    }

    BOOST_DATA_TEST_CASE(
              has_mask_create_success_test
            , bdata::make(std::vector<std::uint32_t>{0x00000000, 0x000fffff})
            ^ bdata::make(std::vector<std::uint32_t>{0x00000001, 0x000fffff})
            , value, mask)
    {
        auto const sut = match::ipv6_flabel::create(value, mask);

        BOOST_TEST(sut.oxm_length() == 2 * sizeof(std::uint32_t));
        BOOST_TEST(sut.oxm_value() == value);
        BOOST_TEST_REQUIRE(sut.oxm_hasmask());
        BOOST_TEST(*sut.oxm_mask() == mask);
        BOOST_TEST(sut.length()
                == sizeof(std::uint32_t) + 2 * sizeof(std::uint32_t));
        BOOST_TEST(!sut.is_wildcard());
        BOOST_TEST(!sut.is_exact());
    }

    BOOST_DATA_TEST_CASE(
              no_mask_create_failure_test
            , bdata::make(std::vector<std::uint32_t>{0x00100000, 0xffffffff})
            , value)
    {
        BOOST_CHECK_THROW(
                match::ipv6_flabel::create(value), std::runtime_error);
    }

    BOOST_AUTO_TEST_CASE(has_mask_create_failure_test)
    {
        BOOST_CHECK_THROW(
                match::ipv6_flabel::create(0x01, 0x00), std::runtime_error);
    }

BOOST_AUTO_TEST_SUITE_END() // ipv6_flabel_test
BOOST_AUTO_TEST_SUITE_END() // oxm_match_test


text:
//
// Copyright (c) 2020 Kasper Laudrup (laudrup at stacktrace dot dk)
//
// 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_WINTLS_STREAM_HPP
#define BOOST_WINTLS_STREAM_HPP

#include <boost/wintls/error.hpp>
#include <boost/wintls/handshake_type.hpp>

#include <boost/wintls/detail/async_handshake.hpp>
#include <boost/wintls/detail/async_read.hpp>
#include <boost/wintls/detail/async_shutdown.hpp>
#include <boost/wintls/detail/async_write.hpp>
#include <boost/wintls/detail/sspi_stream.hpp>

#include <boost/asio/compose.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/system/error_code.hpp>

#include <memory>

namespace boost {
namespace wintls {

/** Provides stream-oriented functionality using Windows SSPI/Schannel.
 *
 * The stream class template provides asynchronous and blocking
 * stream-oriented functionality using Windows SSPI/Schannel.
 *
 * @tparam NextLayer The type representing the next layer, to which
 * data will be read and written during operations. For synchronous
 * operations, the type must support the SyncStream concept.
 * For asynchronous operations, the type must support the
 * AsyncStream concept.
 */
template<class NextLayer>
class stream {
public:
  /// The type of the next layer.
  using next_layer_type = typename std::remove_reference<NextLayer>::type;

  /// The type of the executor associated with the object.
  using executor_type = typename std::remove_reference<next_layer_type>::type::executor_type;

  /** Construct a stream.
   *
   * This constructor creates a stream and initialises the underlying
   * stream object.
   *
   *  @param arg The argument to be passed to initialise the
   *  underlying stream.
   *  @param ctx The wintls @ref context to be used for the stream.
   */
  template <class Arg>
  stream(Arg&& arg, context& ctx)
    : next_layer_(std::forward<Arg>(arg))
    , sspi_stream_(std::make_unique<detail::sspi_stream>(ctx)) {
  }

  stream(stream&& other) = default;
  stream& operator=(stream&& other) = delete;

  /** Get the executor associated with the object.
   *
   * This function may be used to obtain the executor object that the
   * stream uses to dispatch handlers for asynchronous operations.
   *
   * @return A copy of the executor that stream will use to dispatch
   * handlers.
   */
  executor_type get_executor() {
    return next_layer().get_executor();
  }

  /** Get a reference to the next layer.
   *
   * This function returns a reference to the next layer in a stack of
   * stream layers.
   *
   * @return A reference to the next layer in the stack of stream
   * layers.  Ownership is not transferred to the caller.
   */
  const next_layer_type& next_layer() const {
    return next_layer_;
  }

  /** Get a reference to the next layer.
   *
   * This function returns a reference to the next layer in a stack of
   * stream layers.
   *
   * @return A reference to the next layer in the stack of stream
   * layers.  Ownership is not transferred to the caller.
   */
  next_layer_type& next_layer() {
    return next_layer_;
  }

  /** Set SNI hostname
   *
   * Sets the SNI hostname the client will use for requesting and
   * validating the server certificate.
   *
   * Only used when handshake is performed as @ref
   * handshake_type::client
   *
   * @param hostname The hostname to use in certificate validation
   */
  void set_server_hostname(const std::string& hostname) {
    sspi_stream_->handshake.set_server_hostname(hostname);
  }

  /** Perform TLS handshaking.
   *
   * This function is used to perform TLS handshaking on the
   * stream. The function call will block until handshaking is
   * complete or an error occurs.
   *
   * @param type The @ref handshake_type to be performed, i.e. client
   * or server.
   * @param ec Set to indicate what error occurred, if any.
   */
  void handshake(handshake_type type, boost::system::error_code& ec) {
    sspi_stream_->handshake(type);

    detail::sspi_handshake::state state;
    while((state = sspi_stream_->handshake()) != detail::sspi_handshake::state::done) {
      switch (state) {
        case detail::sspi_handshake::state::data_needed: {
          std::size_t size_read = next_layer_.read_some(sspi_stream_->handshake.in_buffer(), ec);
          if (ec) {
            return;
          }
          sspi_stream_->handshake.size_read(size_read);
          continue;
        }
        case detail::sspi_handshake::state::data_available: {
          std::size_t size_written = net::write(next_layer_, sspi_stream_->handshake.out_buffer(), ec);
          if (ec) {
            return;
          }
          sspi_stream_->handshake.size_written(size_written);
          continue;
        }
        case detail::sspi_handshake::state::error:
          ec = sspi_stream_->handshake.last_error();
          return;
        case detail::sspi_handshake::state::done:
          BOOST_UNREACHABLE_RETURN(0);
      }
    }
  }

  /** Perform TLS handshaking.
   *
   * This function is used to perform TLS handshaking on the
   * stream. The function call will block until handshaking is
   * complete or an error occurs.
   *
   * @param type The @ref handshake_type to be performed, i.e. client
   * or server.
   *
   * @throws boost::system::system_error Thrown on failure.
   */
  void handshake(handshake_type type) {
    boost::system::error_code ec{};
    handshake(type, ec);
    if (ec) {
      detail::throw_error(ec);
    }
  }

  /** Start an asynchronous TLS handshake.
   *
   * This function is used to asynchronously perform an TLS
   * handshake on the stream. This function call always returns
   * immediately.
   *
   * @param type The @ref handshake_type to be performed, i.e. client
   * or server.
   * @param handler The handler to be called when the operation
   * completes. The implementation takes ownership of the handler by
   * performing a decay-copy. The handler must be invocable with this
   * signature:
   * @code
   * void handler(
   *     boost::system::error_code // Result of operation.
   * );
   * @endcode
   *
   * @note Regardless of whether the asynchronous operation completes
   * immediately or not, the handler will not be invoked from within
   * this function. Invocation of the handler will be performed in a
   * manner equivalent to using `net::post`.
   */
  template <class CompletionToken>
  auto async_handshake(handshake_type type, CompletionToken&& handler) {
    return boost::asio::async_compose<CompletionToken, void(boost::system::error_code)>(
        detail::async_handshake<next_layer_type>{next_layer_, sspi_stream_->handshake, type}, handler);
  }

  /** Read some data from the stream.
   *
   * This function is used to read data from the stream. The function
   * call will block until one or more bytes of data has been read
   * successfully, or until an error occurs.
   *
   * @param ec Set to indicate what error occurred, if any.
   * @param buffers The buffers into which the data will be read.
   *
   * @returns The number of bytes read.
   *
   * @note The `read_some` operation may not read all of the requested
   * number of bytes. Consider using the `net::read` function if you
   * need to ensure that the requested amount of data is read before
   * the blocking operation completes.
   */
  template <class MutableBufferSequence>
  size_t read_some(const MutableBufferSequence& buffers, boost::system::error_code& ec) {
    detail::sspi_decrypt::state state;
    while((state = sspi_stream_->decrypt(buffers)) == detail::sspi_decrypt::state::data_needed) {
      std::size_t size_read = next_layer_.read_some(sspi_stream_->decrypt.input_buffer, ec);
      if (ec) {
        return 0;
      }
      sspi_stream_->decrypt.size_read(size_read);
      continue;
    }

    if (state == detail::sspi_decrypt::state::error) {
      ec = sspi_stream_->decrypt.last_error();
      return 0;
    }

    return sspi_stream_->decrypt.size_decrypted;
  }

  /** Read some data from the stream.
   *
   * This function is used to read data from the stream. The function
   * call will block until one or more bytes of data has been read
   * successfully, or until an error occurs.
   *
   * @param buffers The buffers into which the data will be read.
   *
   * @returns The number of bytes read.
   *
   * @throws boost::system::system_error Thrown on failure.
   *
   * @note The `read_some` operation may not read all of the requested
   * number of bytes. Consider using the `net::read` function if you
   * need to ensure that the requested amount of data is read before
   * the blocking operation completes.
   */
  template <class MutableBufferSequence>
  size_t read_some(const MutableBufferSequence& buffers) {
    boost::system::error_code ec{};
    auto read = read_some(buffers, ec);
    if (ec) {
      detail::throw_error(ec);
    }
    return read;
  }

  /** Start an asynchronous read.
   *
   * This function is used to asynchronously read one or more bytes of
   * data from the stream. The function call always returns
   * immediately.
   *
   * @param buffers The buffers into which the data will be
   * read. Although the buffers object may be copied as necessary,
   * ownership of the underlying buffers is retained by the caller,
   * which must guarantee that they remain valid until the handler is
   * called.
   * @param handler The handler to be called when the read operation
   * completes.  Copies will be made of the handler as required. The
   * equivalent function signature of the handler must be:
   * @code
   * void handler(
   *     const boost::system::error_code& error, // Result of operation.
   *     std::size_t bytes_transferred           // Number of bytes read.
   * ); @endcode
   *
   * @note The `async_read_some` operation may not read all of the
   * requested number of bytes. Consider using the `net::async_read`
   * function if you need to ensure that the requested amount of data
   * is read before the asynchronous operation completes.
   */
  template <class MutableBufferSequence, class CompletionToken>
  auto async_read_some(const MutableBufferSequence& buffers, CompletionToken&& handler) {
    return boost::asio::async_compose<CompletionToken, void(boost::system::error_code, std::size_t)>(
        detail::async_read<next_layer_type, MutableBufferSequence>{next_layer_, buffers, sspi_stream_->decrypt}, handler);
  }

  /** Write some data to the stream.
   *
   * This function is used to write data on the stream. The function
   * call will block until one or more bytes of data has been written
   * successfully, or until an error occurs.
   *
   * @param buffers The data to be written.
   * @param ec Set to indicate what error occurred, if any.
   *
   * @returns The number of bytes written.
   *
   * @note The `write_some` operation may not transmit all of the data
   * to the peer. Consider using the `net::write` function if you need
   * to ensure that all data is written before the blocking operation
   * completes.
   */
  template <class ConstBufferSequence>
  std::size_t write_some(const ConstBufferSequence& buffers, boost::system::error_code& ec) {
    std::size_t bytes_consumed = sspi_stream_->encrypt(buffers, ec);
    if (ec) {
      return 0;
    }

    net::write(next_layer_, sspi_stream_->encrypt.buffers, ec);
    if (ec) {
      return 0;
    }

    return bytes_consumed;
  }

  /** Write some data to the stream.
   *
   * This function is used to write data on the stream. The function
   * call will block until one or more bytes of data has been written
   * successfully, or until an error occurs.
   *
   * @param buffers The data to be written.
   *
   * @returns The number of bytes written.
   *
   * @throws boost::system::system_error Thrown on failure.
   *
   * @note The `write_some` operation may not transmit all of the data
   * to the peer. Consider using the `net::write` function if you need
   * to ensure that all data is written before the blocking operation
   * completes.
   */
  template <class ConstBufferSequence>
  std::size_t write_some(const ConstBufferSequence& buffers) {
    boost::system::error_code ec{};
    auto wrote = write_some(buffers, ec);
    if (ec) {
      detail::throw_error(ec);
    }
    return wrote;
  }

  /** Start an asynchronous write.
   *
   * This function is used to asynchronously write one or more bytes
   * of data to the stream. The function call always returns
   * immediately.
   *
   * @param buffers The data to be written to the stream. Although the
   * buffers object may be copied as necessary, ownership of the
   * underlying buffers is retained by the caller, which must
   * guarantee that they remain valid until the handler is called.
   * @param handler The handler to be called when the write operation
   * completes.  Copies will be made of the handler as required. The
   * equivalent function signature of the handler must be:
   * @code
   * void handler(
   *     const boost::system::error_code& error, // Result of operation.
   *     std::size_t bytes_transferred           // Number of bytes written.
   * );
   * @endcode
   *
   * @note The `async_write_some` operation may not transmit all of
   * the data to the peer. Consider using the `net::async_write`
   * function if you need to ensure that all data is written before
   * the asynchronous operation completes.
   */
  template <class ConstBufferSequence, class CompletionToken>
  auto async_write_some(const ConstBufferSequence& buffers, CompletionToken&& handler) {
    return boost::asio::async_compose<CompletionToken, void(boost::system::error_code, std::size_t)>(
        detail::async_write<next_layer_type, ConstBufferSequence>{next_layer_, buffers, sspi_stream_->encrypt}, handler);
  }

  /** Shut down TLS on the stream.
   *
   * This function is used to shut down TLS on the stream. The
   * function call will block until TLS has been shut down or an
   * error occurs.
   *
   * @param ec Set to indicate what error occurred, if any.
   */
  void shutdown(boost::system::error_code& ec) {
    ec = sspi_stream_->shutdown();
    if (ec) {
      return;
    }
    std::size_t size_written = net::write(next_layer_, sspi_stream_->shutdown.buffer(), ec);
    if (!ec) {
      sspi_stream_->shutdown.size_written(size_written);
    }
  }

  /** Shut down TLS on the stream.
   *
   * This function is used to shut down TLS on the stream. The
   * function call will block until TLS has been shut down or an error
   * occurs.
   *
   * @throws boost::system::system_error Thrown on failure.
   */
  void shutdown() {
    boost::system::error_code ec{};
    shutdown(ec);
    if (ec) {
      detail::throw_error(ec);
    }
  }

  /** Asynchronously shut down TLS on the stream.
   *
   * This function is used to asynchronously shut down TLS on the
   * stream. This function call always returns immediately.
   *
   * @param handler The handler to be called when the handshake
   * operation completes. Copies will be made of the handler as
   * required. The equivalent function signature of the handler must
   * be:
   * @code void handler(
   *     const boost::system::error_code& error // Result of operation.
   *);
   * @endcode
   */
  template <class CompletionToken>
  auto async_shutdown(CompletionToken&& handler) {
    return boost::asio::async_compose<CompletionToken, void(boost::system::error_code)>(
        detail::async_shutdown<next_layer_type>{next_layer_, sspi_stream_->shutdown}, handler);
  }

private:
  NextLayer next_layer_;
  std::unique_ptr<detail::sspi_stream> sspi_stream_;
};

} // namespace wintls
} // namespace boost

#endif // BOOST_WINTLS_STREAM_HPP


text:
#pragma once
/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/

#ifndef _QI_EXECUTION_CONTEXT_HPP_
#define _QI_EXECUTION_CONTEXT_HPP_

#include <type_traits>
#include <boost/function.hpp>
#include <qi/api.hpp>
#include <qi/clock.hpp>
#include <ka/typetraits.hpp>

namespace qi
{

template <typename T>
class Future;

namespace detail
{

  // This class is kind of a hack to deprecate the old versions of async/post etc without deprecating the correct use of
  // the new ones. This class is just a strong alias to boost::function
  template <typename T>
  struct Function : boost::function<T>
  {
    template<class Arg>
    Function(Arg&& arg,
        typename std::enable_if<!std::is_same<typename std::decay<Arg>::type, Function>::value>::type* = nullptr)
      : boost::function<T>(std::forward<Arg>(arg))
    {}

    Function(const Function&) = default;
  };

}

enum class CancelOption     ///< If cancel have been requested for the associated scheduled task...
{ AllowSkipExecution        ///< ... allow the execution context to not execute the task.
, AlwaysSkipExecution       ///< ... the execution context must not execute the task.
, NeverSkipExecution        ///< ... the executino context must still execute the task.
};

/// Represent execution behaviour options attached to a task that must be interpreted by an ExecutionContext.
struct ExecutionOptions
{
  /** Specifies the behaviour when the task is scheduled but not executed
      and it have been marked as cancel-requested.
  */
  CancelOption onCancelRequested;
};

BOOST_CONSTEXPR
inline ExecutionOptions defaultExecutionOptions() BOOST_NOEXCEPT
{
  return { CancelOption::AllowSkipExecution };
}

class QI_API ExecutionContext
{
public:
  virtual ~ExecutionContext() {}

  // DEPRECATED STUFF
  /// call a callback asynchronously to be executed on tp
  /// @deprecated since 2.5
  QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
  virtual qi::Future<void> async(const boost::function<void()>& callback, qi::SteadyClockTimePoint tp) = 0;
  /// call a callback asynchronously to be executed in delay
  /// @deprecated since 2.5
  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
  virtual qi::Future<void> async(const boost::function<void()>& callback, qi::Duration delay) = 0;

  /// call a callback asynchronously to be executed in delay
  /// @deprecated since 2.5
  template <typename R>
  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
  typename boost::disable_if<std::is_same<R, void>, qi::Future<R> >::type
  async(const boost::function<R()>& callback, qi::Duration delay);
  /// call a callback asynchronously to be executed on tp
  /// @deprecated since 2.5
  template <typename R>
  QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
  typename boost::disable_if<std::is_same<R, void>, qi::Future<R> >::type
  async(const boost::function<R()>& callback, qi::SteadyClockTimePoint tp);

  /// @deprecated since 2.5
  template <typename R>
  QI_API_DEPRECATED_MSG(Use 'async' without explicit return type template arguement instead)
  qi::Future<R> async(const detail::Function<R()>& callback)
  {
    return asyncDelay(callback, qi::Duration(0));
  }
  // END OF DEPRECATED STUFF

  /// post a callback to be executed as soon as possible
  template <typename F>
  void post(F&& callback, ExecutionOptions options = defaultExecutionOptions());

  /// call a callback asynchronously to be executed on tp
  template <typename F, typename R = ka::Decay<decltype(std::declval<F>()())>>
  qi::Future<R> asyncAt(F&& callback, qi::SteadyClockTimePoint tp, ExecutionOptions options = defaultExecutionOptions());
  /// call a callback asynchronously to be executed in delay
  template <typename F, typename R = ka::Decay<decltype(std::declval<F>()())>>
  qi::Future<R> asyncDelay(F&& callback, qi::Duration delay, ExecutionOptions options = defaultExecutionOptions());

  template <typename F>
  auto async(F&& callback, ExecutionOptions options = defaultExecutionOptions())
    -> decltype(asyncDelay(std::forward<F>(callback), qi::Duration(0), options))
  {
    return asyncDelay(std::forward<F>(callback), qi::Duration(0), options);
  }

  /// return true if the current thread is in this context
  virtual bool isInThisContext() const = 0;

protected:
  virtual void postImpl(boost::function<void()> callback, ExecutionOptions options) = 0;
  virtual qi::Future<void> asyncAtImpl(boost::function<void()> cb, qi::SteadyClockTimePoint tp, ExecutionOptions options) = 0;
  virtual qi::Future<void> asyncDelayImpl(boost::function<void()> cb, qi::Duration delay, ExecutionOptions options) = 0;
};

}

#include <qi/detail/future_fwd.hpp>

namespace qi
{

namespace detail
{

template <typename T>
class DelayedPromise: public Promise<T>
{
public:
  void setup(boost::function<void (qi::Promise<T>)> cancelCallback, FutureCallbackType async = FutureCallbackType_Async)
  {
    Promise<T>::setup(cancelCallback, async);
  }
};

template <typename R>
void setValue(qi::Promise<R>& p, const boost::function<R()>& f)
{
  p.setValue(f());
}

template <>
inline void setValue<void>(qi::Promise<void>& p, const boost::function<void()>& f)
{
  f();
  p.setValue(0);
}

template <typename R>
void callAndSet(qi::Promise<R> p, boost::function<R()> f)
{
  try
  {
    setValue<R>(p, f);
  }
  catch (const std::exception& e)
  {
    p.setError(e.what());
  }
  catch(...)
  {
    p.setError("unknown exception");
  }
}
template <typename R>
void forwardError(qi::Future<void> f, qi::Promise<R> p)
{
  switch (f.wait())
  {
    case FutureState_Canceled:          p.setCanceled(); break;
    case FutureState_FinishedWithError: p.setError(f.error()); break;
    case FutureState_None: // Nothing to do for these states.
    case FutureState_Running:
    case FutureState_FinishedWithValue: break;
  }
}

}

template <typename R>
typename boost::disable_if<std::is_same<R, void>,
                            qi::Future<R> >::type
    ExecutionContext::async(const boost::function<R()>& callback,
                            qi::Duration delay)
{
  detail::DelayedPromise<R> promise;
  qi::Future<void> f = async(boost::function<void()>(boost::bind(
                                 detail::callAndSet<R>, promise, callback)),
                             delay);
  promise.setup(
      boost::bind(&detail::futureCancelAdapter<void>,
                  boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
  f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
  return promise.future();
}

template <typename R>
typename boost::disable_if<std::is_same<R, void>,
                            qi::Future<R> >::type
    ExecutionContext::async(const boost::function<R()>& callback,
                            qi::SteadyClockTimePoint tp)
{
  detail::DelayedPromise<R> promise;
  qi::Future<void> f = async(boost::function<void()>(boost::bind(
                                 detail::callAndSet<R>, promise, callback)),
                             tp);
  promise.setup(
      boost::bind(&detail::futureCancelAdapter<void>,
                  boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
  f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
  return promise.future();
}

template <typename F>
void ExecutionContext::post(F&& callback, ExecutionOptions options)
{
  postImpl(std::forward<F>(callback), options);
}

template <typename ReturnType, typename Callback>
struct ToPost
{
  detail::DelayedPromise<ReturnType> promise;
  Callback callback;

  ToPost(Callback cb) :
    callback(std::move(cb))
  {}

  void operator()()
  {
    detail::callAndSet<ReturnType>(std::move(promise), std::move(callback));
  }
};

template <typename F, typename R>
Future<R> ExecutionContext::asyncAt(F&& callback, qi::SteadyClockTimePoint tp, ExecutionOptions options)
{
  ToPost<R, typename std::decay<F>::type> topost(std::forward<F>(callback));
  auto promise = topost.promise;
  qi::Future<void> f = asyncAtImpl(std::move(topost), tp, options);
  promise.setup(boost::bind(&detail::futureCancelAdapter<void>,
                            boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
  f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
  return promise.future();
}

template <typename F, typename R>
Future<R> ExecutionContext::asyncDelay(F&& callback, qi::Duration delay, ExecutionOptions options)
{
  ToPost<R, typename std::decay<F>::type> topost(std::forward<F>(callback));
  auto promise = topost.promise;
  qi::Future<void> f = asyncDelayImpl(std::move(topost), delay, options);
  promise.setup(boost::bind(&detail::futureCancelAdapter<void>,
                            boost::weak_ptr<detail::FutureBaseTyped<void> >(f.impl())));
  f.connect(boost::bind(&detail::forwardError<R>, _1, promise), FutureCallbackType_Sync);
  return promise.future();
}
}

#endif

max_stars_repo_name: arntanguy/libqi

max_issues_repo_name: arntanguy/libqi

max_forks_repo_name: arntanguy/libqi


text:
//    Copyright 2015 Rainer Gemulla
//
//    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.

/** \file
 *
 * Shows how to spawn a set of tasks.
 */

#include <iostream>
#include <map>
#include <queue>
#include <set>

#include <boost/mpi/communicator.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>

#include <util/io.h>

#include <mpi2/mpi2.h>

using namespace std;
using namespace mpi2;
using namespace rg;

log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("main"));

// simple task
struct Task1 {
	static inline string id() { return "task1"; }
	static inline void run(Channel ch, TaskInfo info) {
		LOG4CXX_INFO(logger, "Task " << (info.groupId()+1)<< "/"<< info.groupSize() << ": " << ch);
		ch.send(); // ack
	}
};

int main(int argc, char* argv[]) {
	boost::mpi::communicator& world = mpi2init(argc, argv);

	// register a simple task
	TaskManager& tm = TaskManager::getInstance();
	registerTask<Task1>();

	// fire up task managers
	// this blocks on all but the root node
	mpi2start();
	boost::this_thread::sleep(boost::posix_time::milliseconds(100)); // just to ensure output in right order

	// play around with the tasks
	// the root node initiates communication
	if (world.rank() == 0) {
		Channel ch(UNINITIALIZED);
		std::vector<Channel> channels;

		LOG4CXX_INFO(logger, "");
		LOG4CXX_INFO(logger, "Spawning one task on rank 0");
		ch = tm.spawn<Task1>(0);
		ch.recv();
		LOG4CXX_INFO(logger, "Source channel: " << ch);

		if (world.size() > 1) {
			LOG4CXX_INFO(logger, "");
			LOG4CXX_INFO(logger, "Spawning three tasks on rank 1");
			tm.spawn<Task1>(1, 3, channels);
			recvAll(channels);
			LOG4CXX_INFO(logger, rg::paste("Source channels: ", channels));
		}

		LOG4CXX_INFO(logger, "");
		LOG4CXX_INFO(logger, "Spawning one task on each rank");
		tm.spawnAll<Task1>(channels);
		recvAll(channels);
		LOG4CXX_INFO(logger, rg::paste("Source channels: ", channels));

		LOG4CXX_INFO(logger, "");
		LOG4CXX_INFO(logger, "Spawning three tasks on each rank");
		tm.spawnAll<Task1>(3, channels);
		recvAll(channels);
		LOG4CXX_INFO(logger, rg::paste("Source channels: ", channels));
	}

	// shut down
	LOG4CXX_INFO(logger, "");
	mpi2stop();
	mpi2finalize();

	return 0;
}


text:
/*
 * Copyright (c) 2017-2018, The Alloy Developers.
 * Portions Copyright (c) 2012-2017, The CryptoNote Developers, The Bytecoin Developers.
 *
 * This file is part of Alloy.
 *
 * This file is subject to the terms and conditions defined in the
 * file 'LICENSE', which is part of this source code package.
 */

#include "gtest/gtest.h"

#include "crypto/crypto.h"

#include "CryptoNoteCore/BlockchainStorage.h"
#include "CryptoNoteCore/MemoryBlockchainStorage.h"
#include "CryptoNoteCore/SwappedBlockchainStorage.h"

#include <boost/filesystem/operations.hpp>
#include <boost/range/combine.hpp>

using namespace CryptoNote;

class BlockchainStorageTests : public ::testing::Test {
public:
  BlockchainStorageTests() {
  }

  void SetUp() override {
    m_dir = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path("test_data_dir_%%%%%%%%%%%%");
    boost::system::error_code ignoredErrorCode;
    boost::filesystem::create_directory(m_dir, ignoredErrorCode);
  }

  void TearDown() override {
    boost::system::error_code ignoredErrorCode;
    boost::filesystem::remove_all(m_dir, ignoredErrorCode);
  }

  std::vector<RawBlock> generateRandomBlocks(size_t blocksNumber, size_t txsPerBlock) {
    const size_t BLOCK_SIZE = 10;
    const size_t TX_SIZE = 5;
    std::vector<RawBlock> blocks;
    for (size_t i = 0; i < blocksNumber; ++i) {
      RawBlock block;
      for (size_t j = 0; j < BLOCK_SIZE; ++j) {
        block.block.push_back(rand());
      }

      for (size_t j = 0; j < txsPerBlock; ++j) {
        BinaryArray rawTx;
        for (size_t k = 0; k < TX_SIZE; ++k) {
          rawTx.push_back(rand());
        }

        block.transactions.push_back(rawTx);
      }

      blocks.push_back(block);
    }

    return blocks;
  }

protected:
  boost::filesystem::path m_dir;
};

TEST_F(BlockchainStorageTests, MemoryBlockchainStoragePush) {
  MemoryBlockchainStorage storage(1);
  RawBlock block = generateRandomBlocks(1, 0).front();
  storage.pushBlock(std::move(block));
  ASSERT_EQ(1, storage.getBlockCount());
}

namespace CryptoNote {
bool operator == (const CryptoNote::RawBlock& l, const CryptoNote::RawBlock& r) {
  using boost::get;
  if (l.block.size() != r.block.size() || l.transactions.size() != r.transactions.size()) {
    return false;
  }

  if (!std::equal(std::begin(l.block), std::end(l.block), std::begin(r.block))) {
    return false;
  }

  for (const auto& pair : boost::combine(l.transactions, r.transactions)) {
    if (!std::equal(get<0>(pair).begin(), get<0>(pair).end(), get<1>(pair).begin())) {
      return false;
    }
  }

  return true;
}
}

TEST_F(BlockchainStorageTests, MemoryBlockchainStorageGetBlock) {
  MemoryBlockchainStorage storage(2);
  std::vector<RawBlock> blocks = generateRandomBlocks(2, 0);
  std::vector<RawBlock> blocksCopy = blocks;
  storage.pushBlock(std::move(blocksCopy.front()));
  storage.pushBlock(std::move(blocksCopy.back()));
  ASSERT_EQ(2, storage.getBlockCount());
  ASSERT_EQ(blocks.front(), storage.getBlockByIndex(0));
  ASSERT_EQ(blocks.back(), storage.getBlockByIndex(1));
}

TEST_F(BlockchainStorageTests, MemoryBlockchainStorageSplit) {
  const uint32_t BLOCKS_COUNT = 10;
  const uint32_t SPLIT_INDEX = 4;
  MemoryBlockchainStorage storage(BLOCKS_COUNT);
  std::vector<RawBlock> blocks = generateRandomBlocks(BLOCKS_COUNT, 0);
  std::vector<RawBlock> blocksCopy = blocks;
  for (RawBlock& block : blocksCopy) {
    storage.pushBlock(std::move(block));
  }

  ASSERT_EQ(BLOCKS_COUNT, storage.getBlockCount());

  std::unique_ptr<BlockchainStorage::IBlockchainStorageInternal> newStorage = storage.splitStorage(SPLIT_INDEX);
  ASSERT_EQ(SPLIT_INDEX, storage.getBlockCount());
  ASSERT_EQ(BLOCKS_COUNT - SPLIT_INDEX, newStorage->getBlockCount());

  for (uint32_t i = 0; i < SPLIT_INDEX; ++i) {
    ASSERT_EQ(blocks[i], storage.getBlockByIndex(i));
  }

  for (uint32_t i = 0; i < BLOCKS_COUNT - SPLIT_INDEX; ++i) {
    ASSERT_EQ(blocks[SPLIT_INDEX + i], newStorage->getBlockByIndex(i));
  }
}

TEST_F(BlockchainStorageTests, SwappedBlockchainStoragePush) {
  SwappedBlockchainStorage storage(m_dir.string() + "/items.dat", m_dir.string() + "/index.dat");
  RawBlock block = generateRandomBlocks(1, 0).front();
  storage.pushBlock(std::move(block));
  ASSERT_EQ(1, storage.getBlockCount());
}

TEST_F(BlockchainStorageTests, SwappedBlockchainStorageGetBlock) {
  SwappedBlockchainStorage storage(m_dir.string() + "/items.dat", m_dir.string() + "/index.dat");
  std::vector<RawBlock> blocks = generateRandomBlocks(2, 0);
  std::vector<RawBlock> blocksCopy = blocks;
  storage.pushBlock(std::move(blocksCopy.front()));
  storage.pushBlock(std::move(blocksCopy.back()));
  ASSERT_EQ(2, storage.getBlockCount());
  ASSERT_EQ(blocks.front(), storage.getBlockByIndex(0));
  ASSERT_EQ(blocks.back(), storage.getBlockByIndex(1));
}

TEST_F(BlockchainStorageTests, SwappedBlockchainStorageSplit) {
  const uint32_t BLOCKS_COUNT = 10;
  const uint32_t SPLIT_INDEX = 4;
  SwappedBlockchainStorage storage(m_dir.string() + "/items.dat", m_dir.string() + "/index.dat");
  std::vector<RawBlock> blocks = generateRandomBlocks(BLOCKS_COUNT, 0);
  std::vector<RawBlock> blocksCopy = blocks;
  for (RawBlock& block : blocksCopy) {
    storage.pushBlock(std::move(block));
  }

  ASSERT_EQ(BLOCKS_COUNT, storage.getBlockCount());

  std::unique_ptr<BlockchainStorage::IBlockchainStorageInternal> newStorage = storage.splitStorage(SPLIT_INDEX);
  ASSERT_EQ(SPLIT_INDEX, storage.getBlockCount());
  ASSERT_EQ(BLOCKS_COUNT - SPLIT_INDEX, newStorage->getBlockCount());

  for (uint32_t i = 0; i < SPLIT_INDEX; ++i) {
    ASSERT_EQ(blocks[i], storage.getBlockByIndex(i));
  }

  for (uint32_t i = 0; i < BLOCKS_COUNT - SPLIT_INDEX; ++i) {
    ASSERT_EQ(blocks[SPLIT_INDEX + i], newStorage->getBlockByIndex(i));
  }
}

TEST_F(BlockchainStorageTests, BlockchainStoragePush) {
  BlockchainStorage storage(1);
  RawBlock block = generateRandomBlocks(1, 0).front();
  storage.pushBlock(std::move(block));
  ASSERT_EQ(1, storage.getBlockCount());
}

TEST_F(BlockchainStorageTests, BlockchainStorageGetBlock) {
  BlockchainStorage storage(2);
  std::vector<RawBlock> blocks = generateRandomBlocks(2, 0);
  std::vector<RawBlock> blocksCopy = blocks;
  storage.pushBlock(std::move(blocksCopy.front()));
  storage.pushBlock(std::move(blocksCopy.back()));
  ASSERT_EQ(2, storage.getBlockCount());
  ASSERT_EQ(blocks.front(), storage.getBlockByIndex(0));
  ASSERT_EQ(blocks.back(), storage.getBlockByIndex(1));
}

TEST_F(BlockchainStorageTests, BlockchainStorageSplit) {
  const uint32_t BLOCKS_COUNT = 10;
  const uint32_t SPLIT_INDEX = 4;
  BlockchainStorage storage(BLOCKS_COUNT);
  std::vector<RawBlock> blocks = generateRandomBlocks(BLOCKS_COUNT, 0);
  std::vector<RawBlock> blocksCopy = blocks;
  for (RawBlock& block : blocksCopy) {
    storage.pushBlock(std::move(block));
  }

  ASSERT_EQ(BLOCKS_COUNT, storage.getBlockCount());

  std::unique_ptr<BlockchainStorage> newStorage = storage.splitStorage(SPLIT_INDEX);
  ASSERT_EQ(BLOCKS_COUNT - SPLIT_INDEX, newStorage->getBlockCount());
  ASSERT_EQ(SPLIT_INDEX, storage.getBlockCount());

  for (uint32_t i = 0; i < BLOCKS_COUNT - SPLIT_INDEX; ++i) {
    ASSERT_EQ(blocks[SPLIT_INDEX + i], newStorage->getBlockByIndex(i));
  }

  for (uint32_t i = 0; i < SPLIT_INDEX; ++i) {
    ASSERT_EQ(blocks[i], storage.getBlockByIndex(i));
  }
}

max_stars_repo_name: sehiotbe/alloy

max_issues_repo_name: sehiotbe/alloy

max_forks_repo_name: sehiotbe/alloy