text:
#include <ostream>
#include <sstream>
#include <string>

#define BOOST_TEST_NO_MAIN
#define BOOST_TEST_ALTERNATIVE_INIT_API
#include <boost/test/included/unit_test.hpp>

static bool my_init_function()
{
    return true;
}

void X()
{
     char *apArgVals[] =
        {
                "AndroidSDKTest",
                 "--log_level=warning",
                 "--show_progress=yes",
                0
        };
    int nArgc = 3;
    ::boost::unit_test::unit_test_main(::my_init_function, nArgc, apArgVals);
}

int main(int argc, char *argv[])
{
#ifdef CALL_X
    X();
#else
    ::boost::unit_test::unit_test_main(::my_init_function, argc, argv);
#endif
    return 0;
}

ext: cpp


text:
#pragma once

#include <boost/algorithm/string.hpp>

int main();

ext: hpp

max_stars_repo_name: firedaky/CGen

max_issues_repo_name: firedaky/CGen

max_forks_repo_name: firedaky/CGen


text:
//  (C) Copyright Edward Diener 2011-2015
//  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).

#if !defined(BOOST_VMD_ASSERT_IS_IDENTIFIER_HPP)
#define BOOST_VMD_ASSERT_IS_IDENTIFIER_HPP

#include <boost/vmd/detail/setup.hpp>

#if BOOST_PP_VARIADICS

/*

  The succeeding comments in this file are in doxygen format.

*/

/** \file
*/

/** \def BOOST_VMD_ASSERT_IS_IDENTIFIER(...)

    \brief Asserts that the sequence is an identifier.

    The macro checks that the sequence is an identifier.
    If it is not an identifier, it forces a compiler error.

    The macro normally checks for an identifier only in
    debug mode. However an end-user can force the macro
    to check or not check by defining the macro
    BOOST_VMD_ASSERT_DATA to 1 or 0 respectively.

    ...       = variadic parameters

    The variadic parameters are:

    sequence         = A sequence to test as an identifier.
    ids (optional)   = The data may take one of two forms:
                       it is either one or more single identifiers
                       or a single Boost PP tuple of identifiers.

    returns = Normally the macro returns nothing.

              If the sequence is an identifier, nothing is
              output. If optional ids are specified, for the
              sequence to be an identifier it must be an
              identifier that matches one of the optional
              ids.

              For VC++, because there is no sure way of forcing
              a compiler error from within a macro without producing
              output, if the sequence is not an identifier the
              macro forces a compiler error by outputting invalid C++.

              For all other compilers a compiler error is forced
              without producing output if the sequence is not an
              identifier.

    Identifiers are registered in VMD with:

        #define BOOST_VMD_REG_XXX (XXX) where XXX is a v-identifier.

    The identifier must be registered to be found.

    Identifiers are pre-detected in VMD with:

        #define BOOST_VMD_DETECT_XXX_XXX where XXX is an identifier.

    If you specify optional ids and have not specified the detection
    of an optional id, that id will never match an identifier.

*/

/** \def BOOST_VMD_ASSERT_IS_IDENTIFIER_D(d,...)

    \brief Asserts that the sequence is an identifier. Re-entrant version.

    The macro checks that the sequence is an identifier.
    If it is not an identifier, it forces a compiler error.

    The macro normally checks for an identifier only in
    debug mode. However an end-user can force the macro
    to check or not check by defining the macro
    BOOST_VMD_ASSERT_DATA to 1 or 0 respectively.

    d         = The next available BOOST_PP_WHILE iteration.
    ...       = variadic parameters

    The variadic parameters are:

    sequence         = A sequence to test as an identifier.
    ids (optional)   = The data may take one of two forms:
                       it is either one or more single identifiers
                       or a single Boost PP tuple of identifiers.

    returns = Normally the macro returns nothing.

              If the sequence is an identifier, nothing is
              output. If optional ids are specified, for the
              sequence to be an identifier it must be an
              identifier that matches one of the optional
              ids.

              For VC++, because there is no sure way of forcing
              a compiler error from within a macro without producing
              output, if the sequence is not an identifier the
              macro forces a compiler error by outputting invalid C++.

              For all other compilers a compiler error is forced
              without producing output if the sequence is not an
              identifier.

    Identifiers are registered in VMD with:

        #define BOOST_VMD_REG_XXX (XXX) where XXX is a v-identifier.

    The identifier must be registered to be found.

    Identifiers are pre-detected in VMD with:

        #define BOOST_VMD_DETECT_XXX_XXX where XXX is an identifier.

    If you specify optional ids and have not specified the detection
    of an optional id, that id will never match an identifier.

*/

#if !BOOST_VMD_ASSERT_DATA

#define BOOST_VMD_ASSERT_IS_IDENTIFIER(...)
#define BOOST_VMD_ASSERT_IS_IDENTIFIER_D(d,...)

#else

#include <boost/vmd/assert.hpp>
#include <boost/vmd/is_identifier.hpp>

#define BOOST_VMD_ASSERT_IS_IDENTIFIER(...) \
    BOOST_VMD_ASSERT \
          ( \
          BOOST_VMD_IS_IDENTIFIER(__VA_ARGS__), \
          BOOST_VMD_IDENTIFIER_ASSERT_ERROR \
          ) \
/**/

#define BOOST_VMD_ASSERT_IS_IDENTIFIER_D(d,...) \
    BOOST_VMD_ASSERT \
          ( \
          BOOST_VMD_IS_IDENTIFIER_D(d,__VA_ARGS__), \
          BOOST_VMD_IDENTIFIER_ASSERT_ERROR \
          ) \
/**/

#endif // !BOOST_VMD_ASSERT_DATA
#endif /* BOOST_PP_VARIADICS */
#endif /* BOOST_VMD_ASSERT_IS_IDENTIFIER_HPP */

max_stars_repo_name: cpp-pm/boost


text:
// Boost.Range 2.0 Extension library
// via PStade Oven Library
//
// Copyright Akira Takahashi 2011.
// Copyright Shunsuke Sogame 2005-2007.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>
#include <boost/range/regular.hpp>
#include <boost/range/iteration.hpp>
#include <boost/range/adaptor/taken.hpp>
#include <boost/lambda/lambda.hpp>

void disp(int x)
{
    std::cout << x << std::endl;
}

template <class InputIterator, class F>
void for_each_(InputIterator first, InputIterator last, F f)
{
    InputIterator it; // Default Constructible
    it = first; // Copy Assignable
    for (; it != last; ++it) {
        f(*it);
    }
}

template <class SinglePassRange, class F>
void for_each_(const SinglePassRange& rng, F f)
{
    return for_each_(boost::begin(rng), boost::end(rng), f);
}

int main()
{
    using boost::lambda::_1;

    for_each_(boost::iteration(1, boost::regular(_1 * 2)) | boost::adaptors::taken(5), disp);
}

max_stars_repo_name: Flast/OvenToBoost

max_issues_repo_name: Flast/OvenToBoost

max_forks_repo_name: Flast/OvenToBoost


text:
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// Aegisub Project http://www.aegisub.org/

/// @file dialog_spellchecker.cpp
/// @brief Spell checker dialogue box
/// @ingroup spelling
///

#include "config.h"

#include "dialog_spellchecker.h"

#include "ass_dialogue.h"
#include "ass_file.h"
#include "compat.h"
#include "help_button.h"
#include "include/aegisub/context.h"
#include "include/aegisub/spellchecker.h"
#include "libresrc/libresrc.h"
#include "options.h"
#include "selection_controller.h"
#include "text_selection_controller.h"
#include "subs_edit_ctrl.h"
#include "utils.h"

#include <libaegisub/ass/dialogue_parser.h>
#include <libaegisub/exception.h>
#include <libaegisub/spellchecker.h>

#include <boost/locale/conversion.hpp>
#include <wx/checkbox.h>
#include <wx/combobox.h>
#include <wx/intl.h>
#include <wx/listbox.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>

DialogSpellChecker::DialogSpellChecker(agi::Context *context)
: wxDialog(context->parent, -1, _("Spell Checker"))
, context(context)
, spellchecker(SpellCheckerFactory::GetSpellChecker())
{
	SetIcon(GETICON(spellcheck_toolbutton_16));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);

	auto current_word_sizer = new wxFlexGridSizer(2, 5, 5);
	main_sizer->Add(current_word_sizer, wxSizerFlags().Expand().Border(wxALL, 5));

	wxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
	main_sizer->Add(bottom_sizer, wxSizerFlags().Expand().Border(~wxTOP & wxALL, 5));

	wxSizer *bottom_left_sizer = new wxBoxSizer(wxVERTICAL);
	bottom_sizer->Add(bottom_left_sizer, wxSizerFlags().Expand().Border(wxRIGHT, 5));

	wxSizer *actions_sizer = new wxBoxSizer(wxVERTICAL);
	bottom_sizer->Add(actions_sizer, wxSizerFlags().Expand());

	// Misspelled word and currently selected correction
	current_word_sizer->AddGrowableCol(1, 1);
	current_word_sizer->Add(new wxStaticText(this, -1, _("Misspelled word:")), 0, wxALIGN_CENTER_VERTICAL);
	current_word_sizer->Add(orig_word = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY), wxSizerFlags(1).Expand());
	current_word_sizer->Add(new wxStaticText(this, -1, _("Replace with:")), 0, wxALIGN_CENTER_VERTICAL);
	current_word_sizer->Add(replace_word = new wxTextCtrl(this, -1, ""), wxSizerFlags(1).Expand());

	replace_word->Bind(wxEVT_TEXT, [=](wxCommandEvent&) {
		remove_button->Enable(spellchecker->CanRemoveWord(from_wx(replace_word->GetValue())));
	});

	// List of suggested corrections
	suggest_list = new wxListBox(this, -1, wxDefaultPosition, wxSize(300, 150));
	suggest_list->Bind(wxEVT_LISTBOX, &DialogSpellChecker::OnChangeSuggestion, this);
	suggest_list->Bind(wxEVT_LISTBOX_DCLICK, &DialogSpellChecker::OnReplace, this);
	bottom_left_sizer->Add(suggest_list, wxSizerFlags(1).Expand());

	// List of supported spellchecker languages
	{
		if (!spellchecker.get()) {
			wxMessageBox("No spellchecker available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
			throw agi::UserCancelException("No spellchecker available");
		}

		dictionary_lang_codes = to_wx(spellchecker->GetLanguageList());
		if (dictionary_lang_codes.empty()) {
			wxMessageBox("No spellchecker dictionaries available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
			throw agi::UserCancelException("No spellchecker dictionaries available");
		}

		wxArrayString language_names(dictionary_lang_codes);
		for (size_t i = 0; i < dictionary_lang_codes.size(); ++i) {
			if (const wxLanguageInfo *info = wxLocale::FindLanguageInfo(dictionary_lang_codes[i]))
				language_names[i] = info->Description;
		}

		language = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, language_names, wxCB_DROPDOWN | wxCB_READONLY);
		wxString cur_lang = to_wx(OPT_GET("Tool/Spell Checker/Language")->GetString());
		int cur_lang_index = dictionary_lang_codes.Index(cur_lang);
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = dictionary_lang_codes.Index("en");
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = dictionary_lang_codes.Index("en_US");
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = 0;
		language->SetSelection(cur_lang_index);
		language->Bind(wxEVT_COMBOBOX, &DialogSpellChecker::OnChangeLanguage, this);

		bottom_left_sizer->Add(language, wxSizerFlags().Expand().Border(wxTOP, 5));
	}

	{
		wxSizerFlags button_flags = wxSizerFlags().Expand().Bottom().Border(wxBOTTOM, 5);

		auto make_checkbox = [&](wxString const& text, const char *opt) {
			auto checkbox = new wxCheckBox(this, -1, text);
			actions_sizer->Add(checkbox, button_flags);
			checkbox->SetValue(OPT_GET(opt)->GetBool());
			checkbox->Bind(wxEVT_CHECKBOX,
				[=](wxCommandEvent &evt) { OPT_SET(opt)->SetBool(!!evt.GetInt()); });
		};

		make_checkbox(_("&Skip Comments"), "Tool/Spell Checker/Skip Comments");
		make_checkbox(_("Ignore &UPPERCASE words"), "Tool/Spell Checker/Skip Uppercase");

		wxButton *button;

		actions_sizer->Add(button = new wxButton(this, -1, _("&Replace")), button_flags);
		button->Bind(wxEVT_BUTTON, &DialogSpellChecker::OnReplace, this);

		actions_sizer->Add(button = new wxButton(this, -1, _("Replace &all")), button_flags);
		button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			auto_replace[from_wx(orig_word->GetValue())] = from_wx(replace_word->GetValue());
			Replace();
			FindNext();
		});

		actions_sizer->Add(button = new wxButton(this, -1, _("&Ignore")), button_flags);
		button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { FindNext(); });

		actions_sizer->Add(button = new wxButton(this, -1, _("Ignore a&ll")), button_flags);
		button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			auto_ignore.insert(from_wx(orig_word->GetValue()));
			FindNext();
		});

		actions_sizer->Add(add_button = new wxButton(this, -1, _("Add to &dictionary")), button_flags);
		add_button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			spellchecker->AddWord(from_wx(orig_word->GetValue()));
			FindNext();
		});

		actions_sizer->Add(remove_button = new wxButton(this, -1, _("Remove fro&m dictionary")), button_flags);
		remove_button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			spellchecker->RemoveWord(from_wx(replace_word->GetValue()));
			SetWord(from_wx(orig_word->GetValue()));
		});

		actions_sizer->Add(new HelpButton(this, "Spell Checker"), button_flags);

		actions_sizer->Add(new wxButton(this, wxID_CANCEL), button_flags.Border(0));
	}

	SetSizerAndFit(main_sizer);
	CenterOnParent();

	if (FindNext())
		Show();
}

DialogSpellChecker::~DialogSpellChecker() {
}

void DialogSpellChecker::OnReplace(wxCommandEvent&) {
	Replace();
	FindNext();
}

void DialogSpellChecker::OnChangeLanguage(wxCommandEvent&) {
	wxString code = dictionary_lang_codes[language->GetSelection()];
	OPT_SET("Tool/Spell Checker/Language")->SetString(from_wx(code));

	FindNext();
}

void DialogSpellChecker::OnChangeSuggestion(wxCommandEvent&) {
	replace_word->SetValue(suggest_list->GetStringSelection());
}

bool DialogSpellChecker::FindNext() {
	AssDialogue *real_active_line = context->selectionController->GetActiveLine();
	// User has changed the active line; restart search from this position
	if (real_active_line != active_line) {
		active_line = real_active_line;
		has_looped = false;
		start_line = active_line;
	}

	int start_pos = context->textSelectionController->GetInsertionPoint();
	int commit_id = -1;

	if (CheckLine(active_line, start_pos, &commit_id))
		return true;

	entryIter it = context->ass->Line.iterator_to(*active_line);

	// Note that it is deliberate that the start line is checked twice, as if
	// the cursor is past the first misspelled word in the current line, that
	// word should be hit last
	while(!has_looped || active_line != start_line) {
		do {
			// Wrap around to the beginning if we hit the end
			if (++it == context->ass->Line.end()) {
				it = context->ass->Line.begin();
				has_looped = true;
			}
		} while (!(active_line = dynamic_cast<AssDialogue*>(&*it)));

		if (CheckLine(active_line, 0, &commit_id))
			return true;
	}

	if (IsShown()) {
		wxMessageBox(_("Aegisub has finished checking spelling of this script."), _("Spell checking complete."));
		Close();
	}
	else {
		wxMessageBox(_("Aegisub has found no spelling mistakes in this script."), _("Spell checking complete."));
		throw agi::UserCancelException("No spelling mistakes");
	}

	return false;
}

bool DialogSpellChecker::CheckLine(AssDialogue *active_line, int start_pos, int *commit_id) {
	if (active_line->Comment && OPT_GET("Tool/Spell Checker/Skip Comments")->GetBool()) return false;

	std::string text = active_line->Text;
	auto tokens = agi::ass::TokenizeDialogueBody(text);
	agi::ass::SplitWords(text, tokens);

	bool ignore_uppercase = OPT_GET("Tool/Spell Checker/Skip Uppercase")->GetBool();

	word_start = 0;
	for (auto const& tok : tokens) {
		if (tok.type != agi::ass::DialogueTokenType::WORD || word_start < start_pos) {
			word_start += tok.length;
			continue;
		}

		word_len = tok.length;
		std::string word = text.substr(word_start, word_len);

		if (auto_ignore.count(word) || spellchecker->CheckWord(word) || (ignore_uppercase && word == boost::locale::to_upper(word))) {
			word_start += tok.length;
			continue;
		}

		auto auto_rep = auto_replace.find(word);
		if (auto_rep == auto_replace.end()) {
#ifdef __WXGTK__
			// http://trac.wxwidgets.org/ticket/14369
			orig_word->Remove(0, -1);
			replace_word->Remove(0, -1);
#endif

			context->selectionController->SetSelectionAndActive({ active_line }, active_line);
			SetWord(word);
			return true;
		}

		text.replace(word_start, word_len, auto_rep->second);
		active_line->Text = text;
		*commit_id = context->ass->Commit(_("spell check replace"), AssFile::COMMIT_DIAG_TEXT, *commit_id);
		word_start += auto_rep->second.size();
	}
	return false;
}

void DialogSpellChecker::Replace() {
	AssDialogue *active_line = context->selectionController->GetActiveLine();

	// Only replace if the user hasn't changed the selection to something else
	if (to_wx(active_line->Text.get().substr(word_start, word_len)) == orig_word->GetValue()) {
		std::string text = active_line->Text;
		text.replace(word_start, word_len, from_wx(replace_word->GetValue()));
		active_line->Text = text;
		context->ass->Commit(_("spell check replace"), AssFile::COMMIT_DIAG_TEXT);
		context->textSelectionController->SetInsertionPoint(word_start + replace_word->GetValue().size());
	}
}

void DialogSpellChecker::SetWord(std::string const& word) {
	orig_word->SetValue(to_wx(word));

	wxArrayString suggestions = to_wx(spellchecker->GetSuggestions(word));
	replace_word->SetValue(suggestions.size() ? suggestions[0] : to_wx(word));
	suggest_list->Clear();
	suggest_list->Append(suggestions);

	context->textSelectionController->SetSelection(word_start, word_start + word_len);
	context->textSelectionController->SetInsertionPoint(word_start + word_len);

	add_button->Enable(spellchecker->CanAddWord(word));
}

max_stars_repo_name: rcombs/Aegisub

max_issues_repo_name: rcombs/Aegisub

max_forks_repo_name: rcombs/Aegisub


text:
//
//  A base class for classes which print different types of products
//  It serves to simplify the module code a bit
//
#ifndef Print_inc_ProductPrinter_hh
#define Print_inc_ProductPrinter_hh

#include "art/Framework/Principal/Event.h"
#include "art/Framework/Principal/SubRun.h"
#include "art/Framework/Principal/Run.h"
#include "fhiclcpp/ParameterSet.h"

#include "CLHEP/Matrix/SymMatrix.h"
#include <boost/io/ios_state.hpp>
#include <ostream>
#include <ios>
#include <iomanip>

namespace mu2e {

  class ProductPrinter {
  public:

    ProductPrinter():_verbose(1) {}
    virtual ~ProductPrinter() {}

    // 0 = none, 1 (default), 2, ..
    void setVerbose(int i) { _verbose = i; }
    int verbose() const {return _verbose; }

    virtual void Print(art::Event const& event,
		       std::ostream& os = std::cout) {}

    virtual void PrintSubRun(art::SubRun const& subrun,
		       std::ostream& os = std::cout) {}

    void PrintMatrix(const CLHEP::HepSymMatrix& matrix,
		     std::ostream& os, int mode=0) {
      // when this destructs, it restores the flag state
      boost::io::ios_flags_saver ifs(os);
      // print fixed or scientific
      os.flags(std::ios::right);
      for(int r=1; r<=matrix.num_row(); r++) {
	os << "   ";
	for(int c=1; c<=matrix.num_col(); c++) {
	  if(mode==0) {
	    os << " " << std::setw(13) << std::setprecision(6) << matrix(r,c);
	  } else {
	    double value = sqrt(fabs(matrix(r,r)*matrix(c,c)));
	    if( value!=0.0 ) value = matrix(r,c)/value;
	    os << " " << std::setw(13) << std::setprecision(6) << value;
	  }
	}
	os << "\n";
      }
    }

  private:
    int _verbose;

  };

}
#endif

ext: hh

max_stars_repo_name: sdifalco/Offline

max_issues_repo_name: sdifalco/Offline

max_forks_repo_name: sdifalco/Offline


text:
#include <chrono>
#include <iostream>
#include <memory>

#include <boost/asio.hpp>

#include "netcode/decoder.hh"

/*------------------------------------------------------------------------------------------------*/

static constexpr auto buffer_size = 4096;

/*------------------------------------------------------------------------------------------------*/

namespace boost {
namespace asio {

/// @brief Make ntc::packet usable as a mutable buffer for Asio.
inline
mutable_buffers_1
buffer(ntc::packet& p)
{
  return mutable_buffers_1{mutable_buffer{p.size() ? p.data() : nullptr, p.size()}};
}

} // namespace asio
} // namespace boost

/*------------------------------------------------------------------------------------------------*/

using boost::asio::ip::address_v4;
using boost::asio::ip::udp;

/*------------------------------------------------------------------------------------------------*/

/// @brief Called by encoder when a packet is ready to be written to the network
class packet_handler
{
public:

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

  packet_handler(packet_handler&&) = default;

  packet_handler(udp::socket& sock, udp::endpoint& end)
    : m_socket(sock), m_endpoint(end), m_buffer()
  {
    m_buffer.reserve(buffer_size);
  }

  /// @brief This function is invoked repeatedly until the packet is complete
  void
  operator()(const char* data, std::size_t sz)
  {
    std::copy_n(data, sz, std::back_inserter(m_buffer));
  }

  /// @brief This function is invoked when the packet received by the previous callback is complete
  void
  operator()()
  {
    // End of packet, we can now send it.

    auto buffer = std::make_shared<std::vector<char>>(std::move(m_buffer));
    m_socket.async_send_to( boost::asio::buffer(*buffer), m_endpoint
                          , [buffer](const boost::system::error_code& err, std::size_t len)
                            {
                              if (err)
                              {
                                throw std::runtime_error(err.message());
                              }

                              if (len != buffer->size())
                              {
                                throw std::runtime_error{"Invalid number of sent bytes"};
                              }
                            });
    m_buffer.reserve(buffer_size);
  }

private:

  udp::socket& m_socket;
  udp::endpoint& m_endpoint;

  std::vector<char> m_buffer;
};

/*------------------------------------------------------------------------------------------------*/

/// @brief Called by decoder when a data has been decoded or received
class data_handler
{
public:

  data_handler(udp::socket& sock, udp::endpoint& end)
    : m_socket(sock), m_endpoint(end)
  {}

  void
  operator()(const char* data, std::size_t sz)
  {
    auto buffer = std::make_shared<std::vector<char>>(data, data + sz);
    m_socket.async_send_to( boost::asio::buffer(*buffer), m_endpoint
                          , [buffer](const boost::system::error_code& err, std::size_t len)
                            {
                              if (err)
                              {
                                throw std::runtime_error(err.message());
                              }

                              if (len != buffer->size())
                              {
                                throw std::runtime_error{"Invalid number of sent bytes"};
                              }
                            });
  }

private:

  udp::socket& m_socket;
  udp::endpoint& m_endpoint;
};

/*------------------------------------------------------------------------------------------------*/

class netcode_handler
{
public:

  netcode_handler( boost::asio::io_service& io, ntc::decoder<packet_handler, data_handler>& decoder
                 , udp::socket& socket, udp::endpoint& end)
    : m_decoder(decoder)
    , m_socket(socket)
    , m_endpoint(end)
    , m_packet(buffer_size)
    , m_ack_timer(io, std::chrono::milliseconds{1})
    , m_tunnel_up(false)
    , m_stats_timer(io, std::chrono::seconds(5))
  {
    start();
    start_timer();
    start_stats_timer();
  }

private:

  void
  start()
  {
    m_socket.async_receive_from( boost::asio::buffer(m_packet), m_endpoint
                                , [this](const boost::system::error_code& err, std::size_t len)
                                 {
                                   if (err)
                                   {
                                     throw std::runtime_error(err.message());
                                   }

                                   if (len > 0)
                                   {
                                     m_packet.resize(len);
                                     m_decoder(std::move(m_packet));
                                     m_tunnel_up = true;
                                     m_packet.resize(buffer_size);
                                   }

                                   start();
                                 });
  }

  void
  start_timer()
  {
    m_ack_timer.expires_from_now(std::chrono::milliseconds{1});
    m_ack_timer.async_wait([this](const boost::system::error_code& err)
                           {
                             if (err)
                             {
                               throw std::runtime_error(err.message());
                             }
                             if (m_tunnel_up)
                             {
                               m_decoder.generate_ack();
                             }
                             start_timer();
                           });
  }

  /// @brief Display statistics every 5 seconds
  void
  start_stats_timer()
  {
    m_stats_timer.expires_from_now(std::chrono::seconds(5));
    m_stats_timer.async_wait([this](const boost::system::error_code& err)
                             {
                               if (err)
                               {
                                 throw std::runtime_error(err.message());
                               }
                               std::cout
                                 << "out acks   : " << m_decoder.nb_sent_acks() << '\n'
                                 << "in  repairs: " << m_decoder.nb_received_repairs() << '\n'
                                 << "in  sources: " << m_decoder.nb_received_sources() << '\n'
                                 << "decoded: " << m_decoder.nb_decoded() << '\n'
                                 << "failed : " << m_decoder.nb_failed_full_decodings() << '\n'
                                 << "useless: " << m_decoder.nb_useless_repairs() << '\n'
                                 << "missing: " << m_decoder.nb_missing_sources() << '\n'
                                 << '\n'
                                 << std::endl;

                               start_stats_timer();
                             });
  }

private:

  ntc::decoder<packet_handler, data_handler>& m_decoder;
  udp::socket& m_socket;
  udp::endpoint& m_endpoint;
  ntc::packet m_packet;
  boost::asio::steady_timer m_ack_timer;
  bool m_tunnel_up;
  boost::asio::steady_timer m_stats_timer;
};

/*------------------------------------------------------------------------------------------------*/

int
main(int argc, char** argv)
{
  if (argc != 4)
  {
    std::cerr << "Usage\n";
    std::cerr << argv[0] << " receiver_port app_ip app_port\n";
    std::exit(1);
  }

  try
  {
    boost::asio::io_service io;

    const auto netcode_port = static_cast<unsigned short>(std::atoi(argv[1]));
    const auto app_url = argv[2];
    const auto app_port = argv[3];

    udp::socket netcode_socket{io, udp::endpoint{udp::v4(), netcode_port}};
    netcode_socket.set_option(boost::asio::socket_base::receive_buffer_size{1 << 21});
    udp::endpoint netcode_endpoint;

    udp::socket app_socket{io, udp::endpoint(udp::v4(), 0)};
    app_socket.set_option(boost::asio::socket_base::send_buffer_size{1 << 21});
    udp::resolver resolver(io);
    udp::endpoint app_endpoint = *resolver.resolve({udp::v4(), app_url, app_port});

    ntc::decoder<packet_handler, data_handler>
      decoder( 8, ntc::in_order::yes
             , packet_handler{netcode_socket, netcode_endpoint}
             , data_handler{app_socket, app_endpoint});

    decoder.set_ack_period(std::chrono::milliseconds{5});
    decoder.set_ack_nb_packets(64);
    netcode_handler netcode{io, decoder, netcode_socket, netcode_endpoint};
    io.run();
  }
  catch (const ntc::packet_type_error& e)
  {
    std::cerr << "Invalid packet type " << +e.error_packet.data()[0] << '\n';
    std::exit(2);
  }
  catch (const std::exception& e)
  {
    std::cerr << e.what() << '\n';
    std::exit(3);
  }
  return 0;
}

/*------------------------------------------------------------------------------------------------*/

ext: cc

max_stars_repo_name: ahamez/netcode

max_issues_repo_name: ahamez/netcode

max_forks_repo_name: ahamez/netcode


text:
#pragma once

#include <Eigen/Dense>

#include "perceive/foundation.hpp"
#include "perceive/utils/sdbm-hash.hpp"
#include "vector-2.hpp"
#include "vector-3.hpp"

namespace perceive
{
// An "axis-aligned" bounding box
#pragma pack(push, 1)
template<typename T> class AABBT
{
 public:
   CUSTOM_NEW_DELETE(AABBT)

   using value_type = T;

   T left{T(0.0)}, top{T(0.0)}, right{T(0.0)}, bottom{T(0.0)};

   AABBT() noexcept             = default;
   AABBT(const AABBT&) noexcept = default;
   AABBT(AABBT&&) noexcept      = default;
   ~AABBT()                     = default;
   AABBT& operator=(const AABBT&) noexcept = default;
   AABBT& operator=(AABBT&&) noexcept = default;

   AABBT(T in_left, T in_top, T in_right, T in_bottom)
   noexcept
       : left(in_left)
       , top(in_top)
       , right(in_right)
       , bottom(in_bottom)
   {}
   AABBT(Vector2T<T> lefttop, Vector2T<T> rightbottom)
   noexcept
       : left(lefttop.x)
       , top(lefttop.y)
       , right(rightbottom.x)
       , bottom(rightbottom.y)
   {}

   template<class Iterator> AABBT(Iterator first, Iterator last) noexcept
   {
      *this = minmax();
      union_with(first, last);
   }

   static AABBT nan() noexcept { return AABBT(T(NAN), T(NAN), T(NAN), T(NAN)); }
   static AABBT minmax() noexcept
   {
      auto mmax = std::numeric_limits<T>::max();
      auto mmin = std::numeric_limits<T>::lowest();
      return AABBT<T>(mmax, mmax, mmin, mmin);
   }

   bool is_finite() const noexcept
   {
      return true && std::isfinite(left) && std::isfinite(top)
             && std::isfinite(right) && std::isfinite(bottom);
   }

   // Union a point with the AABB
   void union_point(T x, T y) noexcept
   {
      if(std::isfinite(x)) {
         if(x < left) left = x;
         if(x > right) right = x;
      }
      if(std::isfinite(y)) {
         if(y < top) top = y;
         if(y > bottom) bottom = y;
      }
   }

   void union_point(const Vector2T<T>& p) noexcept { union_point(p.x, p.y); }
   void union_point(const T p[2]) noexcept { union_point(p[0], p[1]); }

   bool contains(T x, T y) const noexcept
   {
      if constexpr(std::is_floating_point<T>::value) {
         return is_close_between(x, left, right)
                and is_close_between(y, top, bottom);
      }
      return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
   }
   bool contains(const Vector2T<T>& p) const noexcept
   {
      return contains(p.x, p.y);
   }
   bool contains(const T p[2]) const noexcept { return contains(p[0], p[1]); }

   template<class Iterator>
   void union_with(Iterator first, Iterator last) noexcept
   {
      while(first != last) union_point(*first++);
   }

   T w() const noexcept
   {
      return right - left;
      if constexpr(std::is_integral_v<T>)
         return abs(right - left);
      else
         return fabs(right - left);
   }
   T h() const noexcept
   {
      return bottom - top;
      if constexpr(std::is_integral_v<T>)
         return abs(bottom - top);
      else
         return fabs(bottom - top);
   }
   T width() const noexcept { return w(); }
   T height() const noexcept { return h(); }

   T area() const noexcept { return w() * h(); }

   AABBT& grow(T inc) noexcept
   {
      left -= inc;
      top -= inc;
      right += inc;
      bottom += inc;
      return *this;
   }

   static AABBT intersection(const AABBT& a, const AABBT& b) noexcept
   {
      AABBT<T> c = a;

      c.left   = std::max(a.left, b.left);
      c.right  = std::min(a.right, b.right);
      c.top    = std::max(a.top, b.top);
      c.bottom = std::min(a.bottom, b.bottom);

      if(c.w() < 0) {
         c.left  = T(0.5 * double(c.left + c.right));
         c.right = c.left;
      }

      if(c.h() < 0) {
         c.top    = T(0.5 * double(c.top + c.bottom));
         c.bottom = c.top;
      }

      return c;
   }

   static T intersection_area(const AABBT& a, const AABBT& b) noexcept
   {
      AABBT<T> c = a;

      c.left   = std::max(a.left, b.left);
      c.right  = std::min(a.right, b.right);
      c.top    = std::max(a.top, b.top);
      c.bottom = std::min(a.bottom, b.bottom);

      T w = c.w();
      T h = c.h();

      return (w > 0.0 && h > 0.0) ? (w * h) : T(0.0);
   }

   // Raster order in images has a "flipped" y-axis
   AABBT reflect_raster() const noexcept
   {
      AABBT o = *this;
      std::swap(o.top, o.bottom);
      return o;
   }

   T intersection_area(const AABBT& o) const noexcept
   {
      return intersection_area(*this, o);
   }

   static T union_area(const AABBT& a, const AABBT& b) noexcept
   {
      return a.area() + b.area() - intersection_area(a, b);
   }
   T union_area(const AABBT& o) const noexcept { return union_area(*this, o); }

   Vector2T<T> centre() const noexcept
   {
      return Vector2T<T>(T(left + 0.5 * (right - left)),
                         T(top + 0.5 * (bottom - top)));
   }
   Vector2T<T> center() const noexcept { return centre(); }

   real aspect_ratio() const noexcept { return real(width()) / real(height()); }

   // Scale the AABB by some size
   AABBT& operator*=(T scalar) noexcept
   {
      Vector2T<T> c = centre();
      T w           = this->w() * scalar * 0.5;
      T h           = this->h() * scalar * 0.5;
      left          = c.x - w;
      right         = c.x + w;
      top           = c.y - h;
      bottom        = c.y + h;
      return *this;
   }

   AABBT& operator/=(T scalar) noexcept { return *this *= (1.0 / scalar); }
   AABBT operator*(T scalar) const noexcept
   {
      AABBT res(*this);
      res *= scalar;
      return res;
   }
   AABBT operator/(T scalar) const noexcept
   {
      AABBT res(*this);
      res /= scalar;
      return res;
   }

   Vector2T<T> left_top() const noexcept { return Vector2T<T>(left, top); }
   Vector2T<T> top_left() const noexcept { return Vector2T<T>(left, top); }
   Vector2T<T> right_bottom() const noexcept
   {
      return Vector2T<T>(right, bottom);
   }
   Vector2T<T> bottom_right() const noexcept
   {
      return Vector2T<T>(right, bottom);
   }

   Vector2T<T> corner(int index) const noexcept
   {
      switch(index) {
      case 0: return Vector2T<T>(left, bottom);
      case 1: return Vector2T<T>(left, top);
      case 2: return Vector2T<T>(right, top);
      case 3: return Vector2T<T>(right, bottom);
      }
      FATAL("kBAM!");
      return {};
   }

   std::array<Vector2T<T>, 4> to_array_polygon() const noexcept
   {
      std::array<Vector2T<T>, 4> X;
      X[0] = Vector2T<T>(left, top);
      X[1] = Vector2T<T>(right, top);
      X[2] = Vector2T<T>(right, bottom);
      X[3] = Vector2T<T>(left, bottom);
      return X;
   }

   vector<Vector2T<T>> to_polygon() const noexcept(false)
   {
      vector<Vector2T<T>> X(4);
      X[0] = Vector2T<T>(left, top);
      X[1] = Vector2T<T>(right, top);
      X[2] = Vector2T<T>(right, bottom);
      X[3] = Vector2T<T>(left, bottom);
      return X;
   }

   Vector3T<T> left_line() const noexcept
   {
      T l = this->left, t = this->top, r = this->right, b = this->bottom;
      return to_homgen_line(Vector3T<T>(l, t, 1), Vector3T<T>(l, b, 1));
   }

   Vector3T<T> right_line() const noexcept
   {
      T l = this->left, t = this->top, r = this->right, b = this->bottom;
      return to_homgen_line(Vector3T<T>(r, t, 1), Vector3T<T>(r, b, 1));
   }

   Vector3T<T> top_line() const noexcept
   {
      T l = this->left, t = this->top, r = this->right, b = this->bottom;
      return to_homgen_line(Vector3T<T>(l, t, 1), Vector3T<T>(r, t, 1));
   }

   Vector3T<T> bottom_line() const noexcept
   {
      T l = this->left, t = this->top, r = this->right, b = this->bottom;
      return to_homgen_line(Vector3T<T>(l, b, 1), Vector3T<T>(r, b, 1));
   }

   Vector3T<T> line(int ind) const noexcept
   {
      switch(ind) {
      case 0: return left_line();
      case 1: return top_line();
      case 2: return right_line();
      case 3: return bottom_line();
      }
      return left_line();
   }

   bool operator!=(const AABBT<T>& rhs) const noexcept
   {
      return !(*this == rhs);
   }
   bool operator==(const AABBT<T>& rhs) const noexcept
   {
      return is_close(left, rhs.left) and is_close(top, rhs.top)
             and is_close(right, rhs.right) and is_close(bottom, rhs.bottom);
   }

   AABBT& set_to(const T& l, const T& t, const T& r, const T& b) noexcept
   {
      left   = l;
      top    = t;
      right  = r;
      bottom = b;
      return *this;
   }
   AABBT& set_to(T a[4]) noexcept
   {
      set_to(a[0], a[1], a[2], a[3]);
      return *this;
   }

   T* copy_to(T a[4]) const noexcept
   {
      a[0] = left;
      a[1] = top;
      a[2] = right;
      a[3] = bottom;
      return a;
   }

   T* ptr() noexcept { return &left; }
   const T* ptr() const noexcept { return &left; }
   T& operator[](int idx) noexcept
   {
#ifdef DEBUG_BUILD
      assert(idx >= 0 && idx < 4);
#endif
      return ptr()[idx];
   }

   const T& operator[](int idx) const noexcept
   {
#ifdef DEBUG_BUILD
      assert(idx >= 0 && idx < 4);
#endif
      return ptr()[idx];
   }

   T& operator()(int idx) noexcept
   {
#ifdef DEBUG_BUILD
      assert(idx >= 0 && idx < 4);
#endif
      return ptr()[idx];
   }
   const T& operator()(int idx) const noexcept
   {
#ifdef DEBUG_BUILD
      assert(idx >= 0 && idx < 4);
#endif
      return ptr()[idx];
   }

   unsigned size() const noexcept { return 4; }

   std::string to_string(const char* fmt = "[{} {} {} {}]") const
   {
      return format(fmt, left, top, right, bottom);
   }

   std::string to_str() const { return to_string(); }

   size_t hash() const noexcept { return sdbm_hash(ptr(), sizeof(T) * size()); }

   friend std::string str(const AABBT<T>& aabb) { return aabb.to_string(); }
};
#pragma pack(pop)

template<typename T>
AABBT<T> intersection(const AABBT<T>& a, const AABBT<T>& b) noexcept
{
   return AABBT<T>::intersection(a, b);
}

template<typename T>
T intersection_area(const AABBT<T>& a, const AABBT<T>& b) noexcept
{
   return AABBT<T>::intersection_area(a, b);
}

template<typename T> T union_area(const AABBT<T>& a, const AABBT<T>& b) noexcept
{
   return AABBT<T>::union_area(a, b);
}

// Scalar multiples
template<typename T> AABBT<T> operator*(float a, const AABBT<T>& v) noexcept
{
   return v * a;
}
template<typename T> AABBT<T> operator/(float a, const AABBT<T>& v) noexcept
{
   return v / a;
}
template<typename T> AABBT<T> operator*(double a, const AABBT<T>& v) noexcept
{
   return v * a;
}
template<typename T> AABBT<T> operator/(double a, const AABBT<T>& v) noexcept
{
   return v / a;
}

// Intersection of homogeneous line ('line') with AABB
template<typename T>
std::pair<Vector2T<T>, Vector2T<T>>
intersect(const AABBT<T>& aabb, const Vector3T<T>& in_line) noexcept
{
   array<Vector3T<T>, 4> lines;
   array<Vector3T<T>, 4> isects;
   array<bool, 4> bounded;
   std::pair<Vector2T<T>, Vector2T<T>> ret
       = {Vector2T<T>::nan(), Vector2T<T>::nan()};

   const auto line = in_line.normalised_line();

   { // What are the lines of the AABB?, the order is [left, top, right, bot]
      int counter = 0;
      std::generate(
          begin(lines), end(lines), [&]() { return aabb.line(counter++); });
   }

   { // Where does 'line' intersect with each line of the AABB?
      std::transform(
          cbegin(lines), cend(lines), begin(isects), [&](const auto& ll) {
             return cross(line, ll).normalise_point();
          });
   }

   { // Are inserections on the border of the AABB?
     // Point 'X' is between lines 'l1' and 'l2'
      auto is_between = [&](const Vector3T<T>& X,
                            const Vector3T<T>& l1,
                            const Vector3T<T>& l2) -> bool {
         return X.is_finite() && (dot(X, l1) < 0.0) == (dot(X, l2) < 0.0);
      };

      bounded[0] = is_close_between(isects[0].y, aabb.top, aabb.bottom);
      bounded[1] = is_close_between(isects[1].x, aabb.left, aabb.right);
      bounded[2] = is_close_between(isects[2].y, aabb.top, aabb.bottom);
      bounded[3] = is_close_between(isects[3].x, aabb.left, aabb.right);
   }

   unsigned pos     = 0;
   auto push_result = [&](const Vector3T<T>& X) {
      if(pos < 2) {
         auto& p = (pos++ == 0) ? ret.first : ret.second;
         p(0)    = X(0);
         p(1)    = X(1);
      } else {
         const auto v  = Vector2T<T>(X(0), X(1));
         const auto q0 = (ret.first - ret.second).quadrance();
         const auto q1 = (ret.first - v).quadrance();
         if(q1 > q0) ret.second = v;
      }
   };

   for(size_t i = 0; i < 4; ++i)
      if(bounded[i]) push_result(isects[i]);

   if(false) {
      INFO("FEEDBACK");
      cout << format("AABB  = {}", str(aabb)) << endl;
      cout << format("line  = {}", str(line)) << endl;
      for(auto i = 0; i < 4; ++i) {
         cout << format(" {:c} ll = {}, isect = {{}, {}}",
                        (bounded[size_t(i)] ? '*' : ' '),
                        str(lines[size_t(i)]),
                        isects[size_t(i)].x,
                        isects[size_t(i)].y)
              << endl;
      }
      cout << format("out   = {{}, {}} -> {{}, {}}",
                     ret.first.x,
                     ret.first.y,
                     ret.second.x,
                     ret.second.y)
           << endl
           << endl;
   }

   return ret;
}

template<typename T>
std::pair<Vector2T<T>, Vector2T<T>> intersect(const AABBT<T>& aabb,
                                              const Vector2T<T>& A,
                                              const Vector2T<T>& B) noexcept
{
   const bool A_in = aabb.contains(A);
   const bool B_in = aabb.contains(B);

   if(A_in and B_in) return {A, B};

   const auto ll     = to_homgen_line(A, B);
   const auto [U, V] = intersect(aabb, ll);

   auto orthogonal_line_at = [&](const auto& U) -> auto
   {
      return Vector3T<T>(-ll.y, ll.x, ll.y * U.x - ll.x * U.y);
   };

   auto is_between_A_B = [&](const auto& U) -> bool {
      const auto tt = orthogonal_line_at(U);
      const auto da = tt.x * A.x + tt.y * A.y + tt.z;
      const auto db = tt.x * B.x + tt.y * B.y + tt.z;
      return std::signbit(da) != std::signbit(db);
   };

   auto subline
       = [&](const auto& X, const auto& Y, const auto& U, const auto& V) {
            return is_between_A_B(U) ? U : V;
         };

   if(A_in)
      return {A, subline(A, B, U, V)};
   else if(B_in)
      return {subline(B, A, U, V), B};
   if(is_between_A_B(U) and is_between_A_B(V)) return {U, V};
   return {Vector2T<T>::nan(), Vector2T<T>::nan()};
}

// The returned homography maps points in the 'src' AABB to the 'dst' AABB
template<typename T>
inline Eigen::Matrix3d rescale_homography(const AABBT<T>& src,
                                          const AABBT<T>& dst) noexcept
{
   Eigen::Matrix3d H = Eigen::Matrix3d::Identity();
   H(0, 0)           = dst.width() / src.width();
   H(1, 1)           = dst.height() / src.height();
   H(0, 2)           = dst.left - H(0, 0) * src.left;
   H(1, 2)           = dst.top - H(1, 1) * src.top;

   // auto tryit = [&] (Vector2 s, Vector2 d) {
   //     Vector3r x = H * Vector3r(s.x, s.y, 1.0);
   //     x /= x(2);
   //     cout << format("{} => {} ({}, {})",
   //                    s.to_string(), d.to_string(), x(0), x(1))
   //     << endl;
   // };

   // tryit(src.top_left(), dst.top_left());
   // tryit(src.right_bottom(), dst.right_bottom());

   return H;
}

template<typename T>
inline bool in_bounding_box(const Vector3T<T>& X,
                            const Vector3T<T>& A,
                            const Vector3T<T>& B)
{
   for(auto i = 0; i < 3; ++i)
      if(X(i) < A(i)) return false;
   for(auto i = 0; i < 3; ++i)
      if(X(i) > B(i)) return false;
   return true;
};

} // namespace perceive

max_stars_repo_name: prcvlabs/multiview

max_issues_repo_name: prcvlabs/multiview

max_forks_repo_name: prcvlabs/multiview


text:
#include <iostream>

#include <boost/asio.hpp>

using boost::asio::ip::udp;

class ClientSet {
public:
  udp::endpoint m_clientEndpoint;
  std::string m_nickname;
  bool m_online;
  ClientSet(const std::string& name, udp::endpoint& clientEndpoint)
  : m_clientEndpoint(clientEndpoint), m_nickname(name), m_online(true) {}
};

class WaServer {

  boost::asio::io_service& m_io_service;
  udp::socket m_socket;
  std::array<uint8_t, 255> m_buffer;
  udp::endpoint m_sender_endpoint;
  std::vector<ClientSet> clientList;

  void set_async_receive() {
    m_socket.async_receive_from(
            boost::asio::buffer(m_buffer), m_sender_endpoint,
            [this](const boost::system::error_code& error, size_t bytes_recvd){receiveHandler(error, bytes_recvd); });
  }

  std::string getNickname(const udp::endpoint& sender) {
    std::string nickname("unknown");
    for (auto client : clientList)
      if (client.m_clientEndpoint == sender)
        nickname = client.m_nickname;
    return nickname;
  }

  udp::endpoint getEndpoint(const std::string& nickname) {
    udp::endpoint ep;
    for (auto client : clientList)
      if (client.m_nickname == nickname)
        ep = client.m_clientEndpoint;
    return ep;
  }

public:
  WaServer(boost::asio::io_service& service, uint16_t port = 12001)
  : m_io_service(service), m_socket(m_io_service, udp::endpoint(udp::v4() /* any UDP */, port)) {

    // now, we need to listen to any IP, and react on incomming data
    set_async_receive();
  }

  void receiveHandler(const boost::system::error_code& error,
                      size_t bytes_recvd) {

    if (!error && bytes_recvd > 0) {

      // simplify with strings
      std::string data((char*)&m_buffer[0],bytes_recvd);

      if (data.substr(0,8) == "register")
        do_register(data.substr(9));

      if (data.substr(0,9) == "broadcast")
        do_broadcast(data.substr(10));

      if (data.substr(0,4) == "send")
        do_send(data.substr(5));
    }
    else
      std::cout << "error\n";

    set_async_receive();
  }

  void do_register(const std::string& nickname) {
    std::cout << "new client registered <" << nickname << ">\n";

    // informing all other clients about the new one and send available clients to new one
    std::string ownName("newone "+nickname);
    for (auto client : clientList) {
      std::string msg("newone "+client.m_nickname);
      m_socket.send_to(boost::asio::buffer(msg), m_sender_endpoint);
      m_socket.send_to(boost::asio::buffer(ownName), client.m_clientEndpoint);
    }

    // keep client in our databas
    clientList.push_back(ClientSet(nickname, m_sender_endpoint));
  }

  void do_broadcast(const std::string& message) {
    std::cout << "new broadcast message <" << message << ">\n";

    std::string msg("send "+getNickname(m_sender_endpoint)+" "+message);

    std::for_each(std::begin(clientList),std::end(clientList),
                  [&](ClientSet& cs)
                  { if (m_sender_endpoint != cs.m_clientEndpoint)
                    m_socket.send_to(boost::asio::buffer(msg), cs.m_clientEndpoint);
                  });
  }

  void do_send(const std::string& remainder) {
    std::string::size_type nickEnd = remainder.find_first_of(' ');
    std::string toNickName = remainder.substr(0,nickEnd);
    std::string message = "send " + getNickname(m_sender_endpoint) + " " + remainder.substr(nickEnd+1);

    udp::endpoint ep = getEndpoint(toNickName);

    if (ep.port() == 0)
      std::cout << "no client found for nick <"<<toNickName<<">\n";
    else
      m_socket.send_to(boost::asio::buffer(message), ep);

  }

};

#ifndef ALL_MAIN
int main() {

  boost::asio::io_service io_service;

  WaServer server(io_service);

  io_service.run();

  return 0;
}
#endif


text:
#pragma once

#include <memory>

#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/ip/tcp.hpp>

#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/chain/plugin_interface.hpp>

#include "session.hpp"
#include "cache.hpp"
#include "api.hpp"

namespace icp {

using namespace std;
using tcp = boost::asio::ip::tcp;
namespace ws = boost::beast::websocket;

using namespace eosio;
using namespace eosio::chain;
using namespace eosio::chain::plugin_interface;

class listener : public std::enable_shared_from_this<listener> {
public:
   listener(boost::asio::io_context& ioc, tcp::endpoint endpoint, relay_ptr relay);

   void do_accept();
   void on_accept(boost::system::error_code ec);

private:
   tcp::acceptor acceptor_;
   tcp::socket socket_;
   relay_ptr relay_;
};

class relay : public std::enable_shared_from_this<relay> {
public:
   void start();
   void stop();

   read_only get_read_only_api() { return read_only{shared_from_this()}; }
   read_write get_read_write_api() { return read_write{shared_from_this()}; }

   void start_reconnect_timer();

   void update_local_head(bool force = false);

   void async_add_session(std::weak_ptr<session> s);
   void on_session_close(const session* s);

   void for_each_session(std::function<void (session_ptr)> callback);
   void send(const icp_message& msg);

   void clear_cache_block_state();

   void open_channel(const block_header_state& seed);
   void push_transaction(vector<action> actions, function<void(bool)> callback = nullptr, packed_transaction::compression_type compression = packed_transaction::none);
   void handle_icp_actions(recv_transaction&& rt);

   std::string endpoint_address_;
   std::uint16_t endpoint_port_;
   std::uint32_t num_threads_ = 1;
   std::vector<std::string> connect_to_peers_;

   public_key_type id_ = fc::crypto::private_key::generate().get_public_key(); // random key to identify this process
   account_name local_contract_;
   account_name peer_contract_;
   chain_id_type peer_chain_id_;
   vector<chain::permission_level> signer_;
   flat_set<public_key_type> signer_required_keys_;

   head peer_head_;

   block_state_index block_states_;

private:
   void on_applied_transaction(const transaction_trace_ptr& t);
   void on_accepted_block(const block_state_with_action_digests_ptr& b);
   void on_irreversible_block(const block_state_ptr& s);
   void on_bad_block(const signed_block_ptr& b);

   void cache_block_state(block_state_ptr b);

   void push_icp_actions(const sequence_ptr& s, recv_transaction&& rt);

   void cleanup();
   void update_send_transaction_index(const send_transaction& t);
   // void cleanup_sequences();

   std::unique_ptr<boost::asio::io_context> ioc_;
   std::vector<std::thread> socket_threads_;
   std::shared_ptr<listener> listener_;
   std::shared_ptr<boost::asio::deadline_timer> timer_; // only access on app io_service
   std::map<const session*, std::weak_ptr<session>> sessions_; // only access on app io_service

   channels::applied_transaction::channel_type::handle on_applied_transaction_handle_;
   channels::accepted_block_with_action_digests::channel_type::handle on_accepted_block_handle_;
   channels::irreversible_block::channel_type::handle on_irreversible_block_handle_;
   channels::rejected_block::channel_type::handle on_bad_block_handle_;

   fc::microseconds tx_expiration_ = fc::seconds(30);
   uint8_t  tx_max_cpu_usage_ = 0;
   uint32_t tx_max_net_usage_ = 0;
   uint32_t delaysec_ = 0;

   fc::time_point last_transaction_time_ = fc::time_point::now();

   // uint32_t cumulative_cleanup_sequences_ = 0;
   uint32_t cumulative_cleanup_count_ = 0;

   send_transaction_index send_transactions_;
   block_with_action_digests_index block_with_action_digests_;
   recv_transaction_index recv_transactions_;
   uint32_t pending_schedule_version_ = 0;

   head local_head_;
};

}


text:
/**
 ** Isaac Genome Alignment Software
 ** Copyright (c) 2010-2017 Illumina, Inc.
 ** All rights reserved.
 **
 ** This software is provided under the terms and conditions of the
 ** GNU GENERAL PUBLIC LICENSE Version 3
 **
 ** You should have received a copy of the GNU GENERAL PUBLIC LICENSE Version 3
 ** along with this program. If not, see
 ** <https://github.com/illumina/licenses/>.
 **
 ** \file RunInfoXml.cpp
 **
 ** Run folder RunInfo.xml helper.
 **
 ** \author Roman Petrovski
 **/

#include <boost/assign.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/xml_parser.hpp>

#include "common/Debug.hh"
#include "io/PtreeXml.hh"

#include "rta/RunInfoXml.hh"

namespace isaac
{
namespace rta
{

namespace ptree=boost::property_tree;

std::vector<RunInfoXml::ReadInfo> RunInfoXml::getReadInfos() const
{
    const ptree::ptree &readsElements(get_child("RunInfo.Run.Reads"));

    std::vector<RunInfoXml::ReadInfo> ret;
    BOOST_FOREACH (const boost::property_tree::ptree::value_type &readElement, readsElements)
    {
        static const std::string readsElementName("Read");
        if (readElement.first == readsElementName)
        {
            ReadInfo read;
            read.number_ = readElement.second.get<unsigned>("<xmlattr>.Number");
            read.numberOfCycles_ = readElement.second.get<unsigned>("<xmlattr>.NumCycles");
            read.isBarcode_ = 'Y' == readElement.second.get<char>("<xmlattr>.IsIndexedRead");
            ret.push_back(read);
        }
    }

    return ret;
}

std::vector<unsigned> RunInfoXml::getLanes() const
{
    const ptree::ptree &flowcellLayout(get_child("RunInfo.Run.FlowcellLayout"));
    const unsigned laneCount = flowcellLayout.get<unsigned>("<xmlattr>.LaneCount");
    const std::vector<unsigned> ret(boost::make_counting_iterator(1U), boost::make_counting_iterator(laneCount + 1U));
    return ret;
}

std::vector<unsigned> RunInfoXml::getTiles(unsigned lane) const
{
    std::vector<unsigned> ret;
    const ptree::ptree &flowcellLayout(get_child("RunInfo.Run.FlowcellLayout"));
//    const unsigned laneCount = flowcellLayout.get<unsigned>("<xmlattr>.LaneCount");
    const unsigned surfaceCount = flowcellLayout.get<unsigned>("<xmlattr>.SurfaceCount");
    const unsigned swathCount = flowcellLayout.get<unsigned>("<xmlattr>.SwathCount");
    const unsigned tileCount = flowcellLayout.get<unsigned>("<xmlattr>.TileCount");
    const unsigned sectionPerLane = flowcellLayout.get<unsigned>("<xmlattr>.SectionPerLane", 0);
    const unsigned lanePerSection = flowcellLayout.get<unsigned>("<xmlattr>.LanePerSection", 0);

    for (unsigned surface = 1; surface <= surfaceCount; ++surface)
    {
        for (unsigned swath = 1; swath <= swathCount; ++swath)
        {
            for (unsigned tile = 1; tile <= tileCount; ++tile)
            {
                if (sectionPerLane)
                {
                    ISAAC_ASSERT_MSG(lanePerSection, "Unexpected Zero lanePerSection");
                    const unsigned firstSection = 1 + sectionPerLane * ((lane-1)/lanePerSection);
                    for (unsigned section = firstSection; section <= firstSection + sectionPerLane; ++section)
                    {
                        ret.push_back(tile + section * 100 + swath * 1000 + surface * 10000);
                    }
                }
                else
                {
                    ret.push_back(tile + swath * 100 + surface * 1000);
                }
            }
        }
    }

    return ret;
}

std::string RunInfoXml::getFlowcellId() const
{
    const ptree::ptree &flowcell(get_child("RunInfo.Run.Flowcell"));
    return flowcell.get_value<std::string>();
}

std::ostream &operator <<(std::ostream &os, const RunInfoXml &tree)
{
    return io::serializeAsXml(os, tree);
}

std::istream &operator >> (std::istream &is, RunInfoXml &tree)
{
    boost::property_tree::read_xml<boost::property_tree::ptree>(is, tree);
    return is;
}

} // namespace rta
} // namespace isaac


text:
/* CirKit: A circuit toolkit
 * Copyright (C) 2009-2015  University of Bremen
 * Copyright (C) 2015-2017  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @file coi.hpp
 *
 * @brief Cone-of-influence functions
 *
 * @author Mathias Soeken
 * @since  2.3
 */

#ifndef CIRKIT_COI_HPP
#define CIRKIT_COI_HPP

#include <algorithm>
#include <stack>
#include <vector>

#include <boost/dynamic_bitset.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/range/iterator_range.hpp>

#include <core/utils/graph_utils.hpp>

namespace cirkit
{

template<class Graph>
std::vector<vertex_t<Graph>> compute_coi( const Graph& g, const vertex_t<Graph>& node )
{
  std::vector<vertex_t<Graph>> coi; /* in reverse topological order */
  boost::dynamic_bitset<> mark( boost::num_vertices( g ) );

  std::stack<vertex_t<Graph>> stack;
  stack.push( node );

  while ( !stack.empty() )
  {
    auto top = stack.top(); stack.pop();

    if ( mark[top] ) { continue; }
    coi.push_back( top );
    mark.set( top );

    for ( const auto& child : boost::make_iterator_range( boost::adjacent_vertices( top, g ) ) )
    {
      stack.push( child );
    }
  }

  return coi;
}

template<class Graph>
unsigned compute_coi_size( const Graph& g, const vertex_t<Graph>& node )
{
  return compute_coi( g, node ).size();
}

template<class Graph>
std::vector<vertex_t<Graph>> coi_topological_nodes( const Graph& g, const std::vector<vertex_t<Graph>>& nodes )
{
  /* get cois for each output */
  using pair_t = std::pair<vertex_t<Graph>, std::vector<vertex_t<Graph>>>;
  std::vector<pair_t> output_cois;
  for ( const auto& n : nodes )
  {
    output_cois.emplace_back( n, compute_coi( g, n ) );
  }

  /* sort cois by size */
  std::stable_sort( output_cois.begin(), output_cois.end(),
                    []( const pair_t& p1, const pair_t& p2 ) {
                      return p1.second.size() > p2.second.size();
                    } );

  std::vector<vertex_t<Graph>> topo;
  boost::dynamic_bitset<> mark( boost::num_vertices( g ) );
  for ( const auto& p : output_cois )
  {
    for ( auto it = p.second.rbegin(); it != p.second.rend(); ++it )
    {
      if ( mark[*it] ) { continue; }
      topo.push_back( *it );
      mark.set( *it );
    }
  }

  return topo;
}

}

#endif

// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End:

max_stars_repo_name: eletesta/cirkit

max_issues_repo_name: eletesta/cirkit

max_forks_repo_name: eletesta/cirkit


text:
#include <stdlib.h>
#include <iostream>

#include "hybrid/DistributionParameters/FelixPeriodPerThreadDistributionParameter.h"
#include "sinks/ParameterReader.h"
#include "MockClasses.h"

#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/included/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(FelixPeriodPerThreadDistributionParameterTest);

class FelixPeriodPerThreadDistributionParameter_wrapper : public FelixPeriodPerThreadDistributionParameter { // just exposes the protected members
public:
	FelixPeriodPerThreadDistributionParameter_wrapper(): FelixPeriodPerThreadDistributionParameter() {};

	std::shared_ptr<IDistributionParameter> getSizeDistribution() {  return this->sizeDistribution; }
	std::shared_ptr<IDistributionParameter> getPeriodDistribution() {  return this->periodDistribution; }
	std::vector<std::string> getNames() {  return this->parameterNames; }
	std::vector<double> getValues() {  return this->parameterValues; }
	FelixPeriodPerThreadDistributionParameter::FELIX_MODE getMode() { return this->mode;};
	double getBuffer_bytes() { return FelixPeriodPerThreadDistributionParameter::getBuffer_bytes(); } ;
	double getTimeout() { return FelixPeriodPerThreadDistributionParameter::getTimeout(); } ;
	double getOutSize_bytes() { return FelixPeriodPerThreadDistributionParameter::getOutSize_bytes(); } ;
};

BOOST_AUTO_TEST_CASE(getName_shouldReturnFelix)
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EQUAL(distribution->getName(), "FelixGBTLink");
}

BOOST_AUTO_TEST_CASE(getFullName_withoutReadingParams_shouldReturnFelix)
{
	CmdLineModelParams.clear();

	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();

	// without reading params
	std::string fullName = distribution->getFullName();

	BOOST_MESSAGE("The full name is: " + fullName);
	BOOST_REQUIRE(fullName.find("FelixGBTLink") != std::string::npos);
}

BOOST_AUTO_TEST_CASE(readParameters_whenLowLatencyModel_shouldReadOnlyPeriodAndModeParameters)
{
	CmdLineModelParams.clear();
	setCmdLineParameter("NotGoodParam", 1234);
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	auto paramDistributionName = "felix_dist";

	// base parameters: size, period, buffer, mode, timeout
	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
				{ return std::string(ex.what()).find("felix_dist_period") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);

	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
					{ return std::string(ex.what()).find("felix_dist_mode") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_mode", 66799);

	// specific values
	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
						{ return std::string(ex.what()).find("mode") != std::string::npos; /*found*/} );
	CmdLineModelParams.clear();
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY);

	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
										{ return std::string(ex.what()).find("felix_dist_period_mu") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_period_mu", 77);

	// no exceptions
	auto distribution_wrapper = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	BOOST_REQUIRE_NO_THROW(distribution_wrapper->readParameters(paramDistributionName));

	// only 2 values read
	BOOST_REQUIRE_EQUAL(distribution_wrapper->getNames().size(), 2);
	BOOST_REQUIRE_EQUAL(distribution_wrapper->getValues().size(), 2);
}

BOOST_AUTO_TEST_CASE(readParameters_shouldThrowExceptionIfParametersAreNotDefined)
{
	CmdLineModelParams.clear();
	setCmdLineParameter("NotGoodParam", 1234);
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	auto paramDistributionName = "felix_dist";

	// base parameters: size, period, buffer, mode, timeout
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);
	setCmdLineParameter("felix_dist_period_mu", 77);
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);

	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
			{ return std::string(ex.what()).find("felix_dist_size_bytes") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);

	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
				{ return std::string(ex.what()).find("felix_dist_buffer_bytes") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_buffer_bytes", 33);

	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
						{ return std::string(ex.what()).find("felix_dist_timeout") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_timeout", 55);

	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
						{ return std::string(ex.what()).find("felix_dist_out_size_bytes") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_out_size_bytes", 11);

	// sub distributions: constant and exp (set before)
	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	BOOST_REQUIRE_EXCEPTION(distribution->readParameters(paramDistributionName), std::runtime_error, [](std::runtime_error const& ex)
								{ return std::string(ex.what()).find("felix_dist_size_bytes_value") != std::string::npos; /*found*/} );
	setCmdLineParameter("felix_dist_size_bytes_value", 66);

	// no exceptions
	distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	distribution->readParameters(paramDistributionName);

}

BOOST_AUTO_TEST_CASE(readParameters_withLowLatency_shouldLoadParametersCorrectly)
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);
	setCmdLineParameter("felix_dist_period_mu", 44);
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY);

	// test
	distribution->readParameters(paramDistributionName);

	// expections
	auto names = distribution->getNames();
	auto values = distribution->getValues();
	BOOST_REQUIRE_EQUAL(names.size(), 2);
	BOOST_REQUIRE_EQUAL(values.size(), 2);

	int paramIndex = 0;
	BOOST_CHECK_EQUAL(names[paramIndex], "period");
	BOOST_CHECK_EQUAL(values[paramIndex++], DISTRIBUTION_PARAMETER::EXPONENTIAL);
	auto distribution_period = distribution->getPeriodDistribution();
	BOOST_CHECK_EQUAL(distribution_period->getName(), "Exponential");
	BOOST_CHECK(distribution_period->getFullName().find("mu=44") != std::string::npos);

	BOOST_CHECK_EQUAL(names[paramIndex], "mode");
	BOOST_CHECK_EQUAL(values[paramIndex++], FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY);
	BOOST_CHECK_EQUAL(distribution->getMode(), FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY);
}

BOOST_AUTO_TEST_CASE(readParameters_withHighThroughoput_shouldLoadParametersCorrectly)
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_size_bytes_value", 66.5);
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);
	setCmdLineParameter("felix_dist_period_mu", 77.1);
	setCmdLineParameter("felix_dist_buffer_bytes", 33.5);
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	setCmdLineParameter("felix_dist_timeout", 22.123);
	setCmdLineParameter("felix_dist_out_size_bytes", 31);

	// test
	distribution->readParameters(paramDistributionName);

	// expections
	auto names = distribution->getNames();
	auto values = distribution->getValues();
	BOOST_REQUIRE_EQUAL(names.size(), 6);
	BOOST_REQUIRE_EQUAL(values.size(), 6);

	int paramIndex = 0;
	BOOST_CHECK_EQUAL(names[paramIndex], "period");
	BOOST_CHECK_EQUAL(values[paramIndex++], DISTRIBUTION_PARAMETER::EXPONENTIAL);
	auto distribution_period = distribution->getPeriodDistribution();
	BOOST_CHECK_EQUAL(distribution_period->getName(), "Exponential");
	BOOST_CHECK(distribution_period->getFullName().find("mu=77.1") != std::string::npos);

	BOOST_CHECK_EQUAL(names[paramIndex], "mode");
	BOOST_CHECK_EQUAL(values[paramIndex++], FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	BOOST_CHECK_EQUAL(distribution->getMode(), FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);

	BOOST_CHECK_EQUAL(names[paramIndex], "size_bytes");
	BOOST_CHECK_EQUAL(values[paramIndex++], DISTRIBUTION_PARAMETER::CONSTANT);
	auto distribution_size = distribution->getSizeDistribution();
	BOOST_CHECK_EQUAL(distribution_size->getName(), "Constant");
	BOOST_CHECK_EQUAL(distribution_size->nextValue(), 66.5);

	BOOST_CHECK_EQUAL(names[paramIndex], "buffer_bytes");
	BOOST_CHECK_EQUAL(values[paramIndex++], 33.5);
	BOOST_CHECK_EQUAL(distribution->getBuffer_bytes(), 33.5);

	BOOST_CHECK_EQUAL(names[paramIndex], "timeout");
	BOOST_CHECK_EQUAL(values[paramIndex++], 22.123);
	BOOST_CHECK_EQUAL(distribution->getTimeout(), 22.123);

	BOOST_CHECK_EQUAL(names[paramIndex], "out_size_bytes");
	BOOST_CHECK_EQUAL(values[paramIndex++], 31);
	BOOST_CHECK_EQUAL(distribution->getOutSize_bytes(), 31);
}

BOOST_AUTO_TEST_CASE(getFullName_readingParamsLowLatency_shouldReturnFelixAndParams)
{
	CmdLineModelParams.clear();
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);
	setCmdLineParameter("felix_dist_period_mu", 44);
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY);

	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	distribution->readParameters("felix_dist");

	std::string fullName = distribution->getFullName();

	BOOST_MESSAGE("The full name is: " + fullName);
	BOOST_CHECK(fullName.find("FelixGBTLink") != std::string::npos);
	BOOST_CHECK(fullName.find(std::to_string(DISTRIBUTION_PARAMETER::EXPONENTIAL)) != std::string::npos);
	BOOST_CHECK(fullName.find(std::to_string(FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY)) != std::string::npos);
}

BOOST_AUTO_TEST_CASE(getFullName_readingParamsHighThroughput_shouldReturnFelixAndParams)
{
	CmdLineModelParams.clear();
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::EXPONENTIAL);
	setCmdLineParameter("felix_dist_period_mu", 44);
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_size_bytes_value", 66.5);
	setCmdLineParameter("felix_dist_buffer_bytes", 33.5);
	setCmdLineParameter("felix_dist_timeout", 22.123);
	setCmdLineParameter("felix_dist_out_size_bytes", 31);

	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter>();
	distribution->readParameters("felix_dist");

	std::string fullName = distribution->getFullName();

	BOOST_MESSAGE("The full name is: " + fullName);
	BOOST_CHECK(fullName.find("FelixGBTLink") != std::string::npos);
	BOOST_CHECK(fullName.find(std::to_string(DISTRIBUTION_PARAMETER::EXPONENTIAL)) != std::string::npos);
	BOOST_CHECK(fullName.find(std::to_string(FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT)) != std::string::npos);
}

BOOST_AUTO_TEST_CASE(nextValue_withLowLatency_shouldForwardInmediatlyAccordingToPeriodDistribution)
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	// TODO: use a custom testing distribution --> copy from felixGeneratorTests
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_period_value", 0.1); // 10 packets per second
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_LOW_LATENCY);

	// test
	distribution->readParameters(paramDistributionName);

	// assert ==> should forward inmediatly, independent of buffer, size, etc
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0.1);
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0.1);
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0.1);
}

BOOST_AUTO_TEST_CASE(nextValue_withBigBufferAndHighThroughput_shouldUseTheTimeoutAsManyTimesAsSizeOverTime )
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_size_bytes_value", 1); // 1B per packet
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_period_value", 1); // 1 packet per second
	setCmdLineParameter("felix_dist_buffer_bytes", std::numeric_limits<int>::max());  // buffer will not get filled
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	setCmdLineParameter("felix_dist_timeout", 10);
	setCmdLineParameter("felix_dist_out_size_bytes", 2);  // each out packet of 2B

	// test
	distribution->readParameters(paramDistributionName);

	// assert ==> should mark 5 out packets of 2B each, total 10B in the 10s timeout
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 10); // first period should come with the time out
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0

	// start again
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 10); // first period should come with the time out
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 4 other times 0
}

BOOST_AUTO_TEST_CASE(nextValue_withBigBufferAndHighThroughput_shouldUseTheTimeoutAsManyTimesAsSizeOverTimeRoundingUp )
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_size_bytes_value", 1); // 1B per packet
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_period_value", 1); // 1 packet per second
	setCmdLineParameter("felix_dist_buffer_bytes", std::numeric_limits<int>::max());  // buffer will not get filled
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	setCmdLineParameter("felix_dist_timeout", 11);
	setCmdLineParameter("felix_dist_out_size_bytes", 2);  // each out packet of 2B

	// test
	distribution->readParameters(paramDistributionName);

	// assert ==> should mark 6 out packets of 2B each, total 12B (round up 11/2) in the 10s timeout
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 11); // first period should come with the time out
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0

	// start again
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 11); // first period should come with the time out
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 5 other times 0
}

BOOST_AUTO_TEST_CASE(nextValue_withHighThroughput_shouldUseBufferSizeAndRateAndSize)
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_size_bytes_value", 1); // 1B per packet
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_period_value", 1); // 10 packets per second
	setCmdLineParameter("felix_dist_buffer_bytes", 6);  // buffer can fit 6 packets --> 0.6s to get filled
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	setCmdLineParameter("felix_dist_timeout", 100); // big timeout wont be reached
	setCmdLineParameter("felix_dist_out_size_bytes", 2);  // each out packet of 2B  --> 3 packets per buffer

	// test
	distribution->readParameters(paramDistributionName);

	// assert ==> should mark 3 out packets of 2B each, total 6B in  0.5s
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 6); // first period should come with bufferSize/(rate*size)
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 2 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 2 other times 0

	// start again
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 6); // first period should come with bufferSize/(rate*size)
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 2 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 2 other times 0
}

BOOST_AUTO_TEST_CASE(nextValue_withHighThroughputAndBigBuffer_shouldRoundUp_alsoToMeasurePerformance)
{
	CmdLineModelParams.clear();
	auto distribution = std::make_shared<FelixPeriodPerThreadDistributionParameter_wrapper>();
	auto paramDistributionName = "felix_dist";

	int totalPacketsInBuffer = 10 * 1000 * 1000; // Lar will have 4kB messages at 100kHz => 1MB fits 250 messages
	int outSize = 3;
	setCmdLineParameter("felix_dist_size_bytes", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_size_bytes_value", 1); // 1B per packet
	setCmdLineParameter("felix_dist_period", DISTRIBUTION_PARAMETER::CONSTANT);
	setCmdLineParameter("felix_dist_period_value", 1); // 10 packets per second
	setCmdLineParameter("felix_dist_buffer_bytes", totalPacketsInBuffer);  // buffer can fit 100k packets --> 100k seg to get filled
	setCmdLineParameter("felix_dist_mode", FelixPeriodPerThreadDistributionParameter::FELIX_MODE_HIGH_THROUGHPUT);
	setCmdLineParameter("felix_dist_timeout", std::numeric_limits<double>::max()); // big timeout wont be reached
	setCmdLineParameter("felix_dist_out_size_bytes", outSize);  // each out packet of 2B  --> 3 packets per buffer

	// test
	distribution->readParameters(paramDistributionName);

	// assert ==> should mark 33334 out packets of 3B each, total 100kB/3 (rounded up) in  100k seg
	auto startTime = std::chrono::system_clock::now();
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), totalPacketsInBuffer); // first period should come with bufferSize/(rate*size)
	auto finishTime = std::chrono::system_clock::now();

	auto totalTime = std::chrono::duration_cast<std::chrono::milliseconds>(finishTime - startTime);
	BOOST_MESSAGE("Time to generate " + std::to_string(totalPacketsInBuffer) + "*2 random numbers: " + std::to_string(totalTime.count()) + " ms \n");

	int counter = 0;
	double lastValue;
	while((lastValue = distribution->nextValue()) == 0 ) counter++;

	int expectedTimes = (totalPacketsInBuffer + outSize - 1) / outSize;
	BOOST_REQUIRE_EQUAL(counter, expectedTimes - 1); // then, 33333 other times 0

	// start again
	BOOST_REQUIRE_EQUAL(lastValue, totalPacketsInBuffer); // first period should come with bufferSize/(rate*size)
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 2 other times 0
	BOOST_REQUIRE_EQUAL(distribution->nextValue(), 0); // then, 2 other times 0
}

/* TODO: check next value:
 *              - custom distribution: not always constant: copy from FelixMultiFlowTest
 * */

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: jorexe/haikunet

max_issues_repo_name: jorexe/haikunet

max_forks_repo_name: jorexe/haikunet


text:
// Copyright 2014-2015 SDL plc
// 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

    equality/hash for never-null pointers (by their pointed-to contents).
*/

#ifndef NONNULLPOINTEE_JG_2013_03_06_HPP
#define NONNULLPOINTEE_JG_2013_03_06_HPP
#pragma once

#include <boost/functional/hash.hpp>

namespace sdl {
namespace Util {

/**
   compare pointer-likes by their pointed-to contents.
*/
struct NonNullPointeeEqual {
  typedef bool result_type;

  template <class Ptr1, class Ptr2>
  bool operator()(Ptr1 p1, Ptr2 p2) const {
    return *p1 == *p2;
  }
};

/**
   if value == is expensive and pointers may alias, check pointers first. not
   useful for hash tables unless you know you'll reuse same raw-pointer key
*/
struct NonNullPointeeEqualExpensive {
  typedef bool result_type;

  template <class Ptr1, class Ptr2>
  bool operator()(Ptr1 p1, Ptr2 p2) const {
    return p1 == p2 || *p1 == *p2;
  }
};

/**
   Hash pointer-likes by their pointed-to contents.
*/
template <class T>
struct NonNullPointeeHash : boost::hash<T> {
  typedef std::size_t result_type;

  result_type operator()(T* p) const { return boost::hash<T>()(*p); }
  result_type operator()(T const* p) const { return boost::hash<T>()(*p); }
  template <class Ptr>
  result_type operator()(Ptr const& p) const {
    return boost::hash<T>()(*p);
  }
};

struct NonNullPointeeHashValue {
  typedef std::size_t result_type;

  template <class T>
  result_type operator()(T* p) const {
    return hash_value(*p);
  }
  template <class T>
  result_type operator()(T const* p) const {
    return hash_value(*p);
  }
};

}}

#endif

max_stars_repo_name: sdl-research/hyp

max_issues_repo_name: hypergraphs/hyp

max_forks_repo_name: hypergraphs/hyp


text:
#include <iostream>
#include <algorithm>
#include <functional>
#include <iomanip> // std::setwのみ
#include <random>
#include <boost/range/algorithm.hpp>
#include <data_type.hpp>
#include <image_algorithm/genetic.hpp>

void genetic::shuffle(std::vector<int>& arr) const
{
    std::uniform_int_distribution<int> distribution(0, arr.size()-1);

    for(int i = 0; i < arr.size(); ++i)
    {
        int j = distribution(mt_);
        std::swap(arr[i], arr[j]);
    }
}

void genetic::shuffle_all()
{
    for(auto it = children_.begin(); it != children_.end(); ++it)
    {
        shuffle(it->children_gene);
    }
}

unsigned int genetic::assess(std::vector<int> const& arr) const
{
    auto const sepx = data_.split_num.first;
    auto const sepy = data_.split_num.second;

    unsigned int ass = 0;
    for(int i = 0; i < arr.size(); ++i)
    {
        if(i + 1 < arr.size())
        {
            if(arr[i] == arr[i + 1])
            {
                std::cout << "!!!" << arr[i] << arr[i + 1] << std::endl;
            }
            ass += comp_[arr[i] / sepx][arr[i] % sepx][arr[i + 1] / sepx][arr[i + 1] % sepx].right;
        }
        if(i + sepy < arr.size())
        {
            if(arr[i] == arr[i + sepy])
            {
                std::cout << "???" << arr[i] << arr[i + sepy] << std::endl;
            }
            ass += comp_[arr[i] / sepx][arr[i] % sepx][arr[i + sepy] / sepx][arr[i + sepy] % sepx].right;
        }
    }
    return ass;
}

void genetic::assess_all()
{
    for(auto it = children_.begin(); it != children_.end(); ++it)
    {
        //for(int i = 0; i < split_total; ++i)
        //{
        //    std::cout << it->children_gene[i] << " - ";
        //}
        it->assessment = assess(it->children_gene);
		//std::cout << "     " << it->assessment << std::endl;
    }
}

std::vector<std::vector<int>> genetic::select_parent(std::vector<int>& top10)
{
    top10.assign(PARENT_NUM, 0);

    std::vector<int> childred_copy;
    childred_copy.reserve(children_.size());

    boost::transform(
        children_, std::back_inserter(childred_copy),
        [](children_t const& base){ return base.assessment; }
        );
    boost::sort(childred_copy);
    //boost::for_each(childred_copy, [](int const base){ std::cout << base << std::endl; });

    for(int i=0; i<top10.size(); ++i)
    {
        for(int j=0; j<CHILDREN_NUM; ++j)
        {
            if(childred_copy.at(i) == children_[j].assessment)
            {
                top10[i] = j;
            }
        }
    }

    auto const split_total = data_.split_num.first * data_.split_num.second;
    std::vector<std::vector<int>> parent_gene(PARENT_NUM, std::vector<int>(split_total, 0));

    //親遺伝子配列にいいやつTop10を突っ込む
    for(int i=0; i<top10.size(); ++i)
    {
        for(int j=0; j<split_total; ++j)
        {
            parent_gene[i][j] = children_[top10[i]].children_gene[j];
        }
    }

    std::cout << "番号  " << "評価" << std::endl;
    for(auto const& elem : top10)
    {
        std::cout << elem << "   " << children_[elem].assessment << std::endl;
    }

    return parent_gene;
}

void genetic::cross_over(std::vector<std::vector<int>> const& parent_gene)
{
    auto const split_width  = data_.split_num.first;
    auto const split_height = data_.split_num.second;
    auto const split_total  = split_width * split_height;

    std::uniform_int_distribution<int> parent_dist(0, PARENT_NUM - 1);
    std::uniform_int_distribution<int> mutate_dist(0, 4 - 1);
    std::uniform_int_distribution<int> split_dist(0, split_total - 1);

    for(int i=0; i<CHILDREN_NUM; i+=2)
    {
        auto const& pra1 = parent_gene[parent_dist(mt_)];
        auto const& pra2 = parent_gene[parent_dist(mt_)];
        auto      & child1 = children_[i  ].children_gene;
        auto      & child2 = children_[i+1].children_gene;

        //std::cout << "par1 ";
        //boost::for_each(pra1, [](int const elem){ std::cout << elem << "*"; });
        //std::cout << std::endl;
        //
        //std::cout << "par2 ";
        //boost::for_each(pra2, [](int const elem){ std::cout << elem << "*"; });
        //std::cout << std::endl;

        child1.assign(child1.size(), -1);
        child2.assign(child2.size(), -1);

        int select_gene = split_dist(mt_);
        //std::cout << "  s" << select_gene;
        while(child1[select_gene] != pra1[select_gene])
        {
			child1[select_gene] = pra1[select_gene];
			child2[select_gene] = pra2[select_gene];

            for(int i=0; i<split_total; ++i)
            {
                if(child2[select_gene] == pra1[i])
                {
                    select_gene = i;
                }
            }
            //std::cout << "  s" << select_gene;
        }

        for(int i=0; i<split_total; ++i)
        {
            if(child1[i] == -1)
            {
				child1[i] = pra2[i];
				child2[i] = pra1[i];
            }
        }

        for(int n = parent_dist(mt_); n < 10; ++n) //このループ数をいじらないと収束しなかったりすぐに収束してしまったり
        {
            if(mutate_dist(mt_) == 0) //ここの確率で突然変異率を変化させる
            {
                int rand1 = split_dist(mt_);
                int rand2 = split_dist(mt_);
                std::swap(child1[rand1], child1[rand2]);
                //std::cout << "rand1" << std::endl;
            }
            if(mutate_dist(mt_) == 0) //ここの確率で突然変異率を変化させる
            {
                int rand1 = split_dist(mt_);
                int rand2 = split_dist(mt_);
                std::swap(child2[rand1], child2[rand2]);
				//std::cout << "rand2" << std::endl;
            }
        }

        //std::cout << std::endl;
        //std::cout << "chi1 ";
        //boost::for_each(child1, [](int const elem){ std::cout << elem << "+"; });
        //
        //std::cout << std::endl;
        //std::cout << "chi2 ";
        //boost::for_each(child2, [](int const elem){ std::cout << elem << "+"; });
        //
        //std::cout << std::endl;
    }
}

genetic::genetic(question_raw_data const& data, compared_type const& comp)
    : data_(data), comp_(comp)
{
    //メルセンヌ・ツイスタの初期化
    std::random_device rd;
    std::vector<std::uint_least64_t> random_seed(10);
    boost::generate(random_seed, std::ref(rd));

    std::seed_seq seed(random_seed.cbegin(), random_seed.cend());
    mt_.seed(seed);
}

std::vector<std::vector<std::vector<point_type>>> genetic::operator() ()
{
    auto const split_total = data_.split_num.first * data_.split_num.second;

    // children_の初期化
    {
        //連番リスト(0~split_total-1)の作製
        std::vector<int> tmp_vector;
        tmp_vector.reserve(split_total);
        for(int i = 0; i < split_total; ++i) tmp_vector.push_back(i);

        //連番リストでchildren_を初期化
        children_.assign(CHILDREN_NUM, {tmp_vector, 0});
    }

    shuffle_all();
    assess_all();

    int top;
    std::vector<int> top10(PARENT_NUM);
    std::vector<int> toppers(1000);
    for(int i = 0; i < toppers.size(); ++i)
    {
        for(int j = 0; j < 10000; ++j)
        {
            auto const parent_gene = select_parent(top10);
            top = children_.at(top10[0]).assessment;

            cross_over(parent_gene);
            assess_all();

			std::cout << "最上位遺伝子";
			for (int i = 0; i < split_total; i++)
            {
				std::cout << std::setw(3) << parent_gene[0][i]; //unspecified(std::setw)
			}

            std::cout << "番号" << top10[0] << std::endl;

            int const base = top10[0]; // VCのための苦肉の策
            if(
                std::all_of(
                    top10.begin(), top10.end(),
                    [base](int const elem){ return base == elem; }
                    //[base = top10[0]](int const elem){ return base == elem; }
                )
            )
            {
                //Top10の遺伝子がすべて同じものになったら収束したと判断する
                break;
            }
            std::cout << "世代=" << j << "ループ" << i << std::endl;

        }
        toppers[i] = top;

        shuffle_all();
    }

	int toptop = std::numeric_limits<int>::max();
	int topnum = 0;
	for(auto const elem : toppers)
    {
        if(elem < toptop)
        {
            toptop = elem;
            topnum = 0;
        }
        else if(elem == toptop)
        {
            ++topnum;
        }
		std::cout << elem << std::endl;
    }
	std::cout << "最適値" << toptop << "数" << topnum << std::endl;

    return {}; //ごめん，どこが答えか分からなかったから空白返す．
}


text:
#include <cctbx/boost_python/flex_fwd.h>

#include <cctbx/sgtbx/sym_equiv_sites.h>
#include <cctbx/import_scitbx_af.h>
#include <scitbx/boost_python/is_polymorphic_workaround.h>
#include <scitbx/array_family/versa.h>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/return_internal_reference.hpp>
#include <vector>

namespace cctbx { namespace boost_python { namespace emma_ext {

  struct add_pair
  {
    double tolerance_;
    af::shared<scitbx::vec3<double> > ref_model2_sites_;
    af::versa<bool, af::c_grid<2> > pair_flags_;
    std::vector<sgtbx::sym_equiv_sites<> > equiv1_;
    sgtbx::rt_mx eucl_symop_;
    int new_pair_1_;
    int new_pair_2_;

    add_pair(double tolerance,
             uctbx::unit_cell const& unit_cell,
             sgtbx::space_group const& space_group,
             double min_distance_sym_equiv,
             af::const_ref<scitbx::vec3<double> > const& ref_model1_sites,
             af::shared<scitbx::vec3<double> > const& ref_model2_sites)
    :
      tolerance_(tolerance),
      ref_model2_sites_(ref_model2_sites),
      pair_flags_(af::versa<bool, af::c_grid<2> >(
        af::c_grid<2>(ref_model1_sites.size(),
                      ref_model2_sites.size())))
    {
      for(std::size_t i=0;i<ref_model1_sites.size();i++) {
        sgtbx::site_symmetry site_symmetry(
          unit_cell, space_group,
          ref_model1_sites[i], min_distance_sym_equiv);
        equiv1_.push_back(sgtbx::sym_equiv_sites<>(site_symmetry));
      }
    }

    sgtbx::sym_equiv_sites<> const&
    equiv1(std::size_t i) const { return equiv1_[i]; }

    void
    next_pivot(af::tiny<bool, 3> const& continuous_shift_flags,
               sgtbx::rt_mx const& eucl_symop,
               scitbx::vec3<double> const& adjusted_shift,
               af::const_ref<int> const& singles1,
               af::const_ref<int> const& singles2)
    {
      CCTBX_ASSERT(ref_model2_sites_.size() == pair_flags_.accessor()[1]);
      pair_flags_.fill(false);
      eucl_symop_ = eucl_symop;
      CCTBX_ASSERT(equiv1_.size() > 0);
      bool no_continuous_shifts = continuous_shift_flags.all_eq(false);
      uctbx::unit_cell const& unit_cell = equiv1_[0].unit_cell();
      af::ref<bool, af::c_grid<2> > pair_flags_ref = pair_flags_.ref();
      for (const int* is2 = singles2.begin(); is2 != singles2.end(); is2++) {
        scitbx::vec3<double>
          c2 = eucl_symop_ * ref_model2_sites_[*is2] + adjusted_shift;
        for (const int* is1 = singles1.begin(); is1 != singles1.end(); is1++) {
          sgtbx::min_sym_equiv_distance_info<> dist_info(equiv1_[*is1], c2);
          double dist = dist_info.dist();
          if (no_continuous_shifts) {
            if (dist < tolerance_) {
              pair_flags_ref(*is1,*is2) = true;
            }
          }
          else if (dist < 4 * tolerance_) {
            // ensure that this pair can be matched within 1 * tolerance.
            // (not entirely sure that this is safe under all circumstances.)
            fractional<> const& diff = dist_info.diff();
            fractional<> diff_allowed;
            for (std::size_t j=0;j<3;j++) {
              diff_allowed[j] = (continuous_shift_flags[j] ? diff[j] : 0);
            }
            double dist_allowed = unit_cell.length(diff_allowed);
            if (dist_allowed < tolerance_) {
              pair_flags_ref(*is1,*is2) = true;
            }
          }
        }
      }
    }

    bool
    next_pair(scitbx::vec3<double> const& adjusted_shift,
              af::const_ref<int> const& singles1,
              af::const_ref<int> const& singles2)
    {
      double shortest_dist = 2 * tolerance_;
      bool have_new_pair = false;
      new_pair_1_ = 0;
      new_pair_2_ = 0;
      af::const_ref<bool, af::c_grid<2> >
        pair_flags_ref = pair_flags_.const_ref();
      for (const int* is2 = singles2.begin(); is2 != singles2.end(); is2++) {
        scitbx::vec3<double>
          c2 = eucl_symop_ * ref_model2_sites_[*is2] + adjusted_shift;
        for (const int* is1 = singles1.begin(); is1 != singles1.end(); is1++) {
          if (pair_flags_ref(*is1,*is2)) {
            sgtbx::min_sym_equiv_distance_info<> dist_info(equiv1_[*is1], c2);
            double dist = dist_info.dist();
            if (dist < shortest_dist) {
              shortest_dist = dist;
              have_new_pair = true;
              new_pair_1_ = *is1;
              new_pair_2_ = *is2;
            }
          }
        }
      }
      return have_new_pair;
    }

    int
    new_pair_1() const { return new_pair_1_; }

    int
    new_pair_2() const { return new_pair_2_; }
  };

}}} // namespace cctbx::boost_python::emma_ext

SCITBX_BOOST_IS_POLYMORPHIC_WORKAROUND(cctbx::boost_python::emma_ext::add_pair)

namespace cctbx { namespace boost_python { namespace emma_ext {

  void init_module()
  {
    using namespace boost::python;

    typedef return_internal_reference<> rir;

    class_<add_pair>("add_pair", no_init)
      .def(init<double,
                uctbx::unit_cell const&,
                sgtbx::space_group const&,
                double,
                af::const_ref<scitbx::vec3<double> > const&,
                af::shared<scitbx::vec3<double> > const&>())
      .def("equiv1", &add_pair::equiv1, rir())
      .def("next_pivot", &add_pair::next_pivot)
      .def("next_pair", &add_pair::next_pair)
      .def("new_pair_1", &add_pair::new_pair_1)
      .def("new_pair_2", &add_pair::new_pair_2)
    ;
  }

}}} // namespace cctbx::boost_python::emma_ext

BOOST_PYTHON_MODULE(cctbx_emma_ext)
{
  cctbx::boost_python::emma_ext::init_module();
}