text:
/* -*- Mode:C++; c-file-style:"bsd"; indent-tabs-mode:nil; -*- */
/**
 * Copyright 2020 Washington University in St. Louis
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <../src/api.hpp>

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/validator-null.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>

#include <boost/asio.hpp>

#include <unordered_map>
#include <vector>
#include <iostream>

// global variable to support debug
int DEBUG = 0;

enum class Status
{
    Good,
    Bad
};

std::string status2str(int status)
{
    std::string rval;
    switch(status)
    {
    case 0:
        rval = "Good";
        break;
    case 1:
        rval = "Bad";
        break;
    default:
        break;
    }
    return rval;
}

struct DetailedEvent
{
    uint64_t    rxTime;
    double      latitude;
    double      longitude;
    Status      status;
    std::string entityName;

    DetailedEvent(uint64_t time, double lat, double lon, Status stat, std::string name) :
        rxTime(time), latitude(lat), longitude(lon), status(stat), entityName(name)
    { }

    DetailedEvent(uint64_t time, double lat, double lon, int stat, std::string name) :
        rxTime(time), latitude(lat), longitude(lon), entityName(name)
    {
        status = static_cast<Status>(stat);
    }

    DetailedEvent(const DetailedEvent& other) :
        rxTime(other.rxTime), latitude(other.latitude), longitude(other.longitude),
        status(other.status), entityName(other.entityName)
    { }

    DetailedEvent(DetailedEvent&& other) noexcept :
        rxTime( std::move(other.rxTime) ),
        latitude( std::move(other.latitude) ),
        longitude( std::move(other.longitude) ),
        status( std::move(other.status) ),
        entityName( std::move(other.entityName) )
    { }

    DetailedEvent& operator=(const DetailedEvent& other)
    {
        if (this != &other)
        {
            rxTime = other.rxTime;
            latitude = other.latitude;
            longitude = other.longitude;
            status = other.status;
            entityName = other.entityName;
        }
        return *this;
    }

    DetailedEvent& operator=(DetailedEvent&& other)
    {
        if (this != &other)
        {
            rxTime = std::move(other.rxTime);
            latitude = std::move(other.latitude);
            longitude = std::move(other.longitude);
            status = std::move(other.status);
            entityName = std::move(other.entityName);
        }
        return *this;
    }
};

namespace ndn
{

typedef std::unordered_map<uint64_t, std::vector<Name>> NotificationMap;

class NotificationConsumer
{
public:
    NotificationConsumer(char* programName)
        : m_programName(programName)
    {

    }

    void
    usage()
    {
        std::cout << "\n Usage:\n " << m_programName <<
            ""
            " [-h] -f filters_file [-d debug_mode]\n"
            " request notifications for a namespace and its filters.\n"
            "\n"
            " \t-h - print this message and exit\n"
            " \t-f - file containing event filters\n"
            " \t-d - sets the debug mode, 1 - debug on, 0 - debug off (default)\n"
            "\n";
        exit(1);
    }

    void
    setFile(std::string file)
    {
        m_fileName = file;
        if (DEBUG) {
            std::cout << "set file name to " << m_fileName << std::endl;
        }
    }

    void
    listen()
    {
        m_face.processEvents();
    }

    void
    listen(int timeout)
    {
        time::milliseconds timeout_ms(timeout);
        while (true)
        {
            m_face.processEvents(timeout_ms);
            if (changes) {
                printStatus();
                changes = false;
            }
        }
    }

    void init()
    {
        if (m_notificationHandler != nullptr) {
            std::cout << "Trying to initialize notification handler, but it already exists";
            return;
        }

        m_notificationHandler = std::make_shared<notificationLib::api>(m_face,
                                                                       notificationLib::api::DEFAULT_NAME,
                                                                       notificationLib::api::DEFAULT_VALIDATOR);
        m_notificationHandler->init(m_fileName,
                                    std::bind(&NotificationConsumer::onNotificationUpdateWithTime, this, _1, _2));

        changes = false;
        sleep(2);
    }

    void
    onNotificationUpdateWithTime(uint64_t receivedTime,
                                 const NotificationMap& notiMap)
    {
        std::vector<DetailedEvent> events;
        for (auto& map_itr : notiMap)
        {
            for (auto& noti : map_itr.second)
            {
                if (DEBUG) {
                    std::cout << "application received notification (t = "
                              << receivedTime << "): " << noti << std::endl;
                }

                int status = std::stoi( noti.get(-1).toUri() );
                double longitude = std::stod( noti.get(-2).toUri() );
                double latitude = std::stod( noti.get(-3).toUri() );
                std::string entityName( noti.get(-4).toUri() );

                events.emplace_back( DetailedEvent(receivedTime,
                                                   latitude, longitude,
                                                   status, entityName) );
            }
        }

        handleEvents( std::move(events) );
    }

    void
    handleEvents(std::vector<DetailedEvent>&& events)
    {
        for (auto &event : events)
        {
            auto mapItr = recentUpdates.find(event.entityName);
            // if name is already in map, keep the most recent update only
            if ( mapItr != recentUpdates.end() )
            {
                if (mapItr->second.rxTime < event.rxTime) {
                    mapItr->second = event;
                    changes = true;
                }
                continue;
            }
            recentUpdates.insert( std::make_pair(event.entityName, event) );
            changes = true;
        }
    }

    void printStatus()
    {
        std::cout << "**Status**\n";
        for (auto entry : recentUpdates)
        {
            std::cout << entry.first << " (t = " << entry.second.rxTime << "): "
                      << entry.second.latitude << "," << entry.second.longitude << "\t"
                      << status2str( (int) entry.second.status) << "\n";
        }
        std::cout << std::endl;
    }

private:
    std::shared_ptr<notificationLib::api> m_notificationHandler;

    Face m_face;
    Name m_name;
    KeyChain m_keyChain;
    security::ValidatorNull m_validator;

    std::string m_programName;
    std::string m_fileName;

    std::unordered_map<std::string, DetailedEvent> recentUpdates;
    bool changes;
};

} // namespace ndn

int
main(int argc, char* argv[])
{
    ndn::NotificationConsumer consumer(argv[0]);
    int option;
    bool filterSet = false;

    while ((option = getopt(argc, argv, "hf:d:")) != -1)
    {
        switch (option)
        {
        case 'f':
            consumer.setFile((std::string)(optarg));
            filterSet = true;
            break;
        case 'h':
            consumer.usage();
            break;
        case 'd':
            DEBUG = atoi(optarg);
            break;
        default:
            consumer.usage();
            break;
        }
    }

    argc -= optind;
    argv += optind;

    if(!filterSet)
    {
        consumer.usage();
        return 1;
    }

    consumer.init();
    consumer.listen(5000);
    std::cout << "end of program" << std::endl;
    return 0;
}


text:
#define BOOST_TEST_MODULE
#include <boost/test/unit_test.hpp>
#include <util/test_macros.hpp>
#include <fstream>
#include <logger/logger.hpp>
#include <logger/log_rotate.hpp>
#include <logger/log_level_setter.hpp>
using namespace turi;

struct logger_test {
 public:
  void test_empty_log() {
    global_logger().set_log_level(LOG_INFO);
    logstream(LOG_INFO) << "\n";
    logstream(LOG_INFO);
    logstream(LOG_INFO);
    logstream(LOG_INFO) << std::endl;
  }

  void test_log_level_setter() {
    logprogress_stream << "This should show up" << std::endl;
    auto x = log_level_setter(LOG_NONE);
    logprogress_stream << "This should not print." << std::endl;
  }

  void test_log_rotation() {
    global_logger().set_log_level(LOG_INFO);
    begin_log_rotation("rotate.log",
                       1 /* log rotates every second */,
                       2 /* we only keep the last 2 logs around*/);
    for (size_t i = 0;i < 5; ++i) {
      logstream(LOG_INFO) << i << std::endl;
      timer::sleep(1);
    }
    TS_ASSERT(std::ifstream("rotate.log").good());
    TS_ASSERT(std::ifstream("rotate.log.0").good() == false);
    TS_ASSERT(std::ifstream("rotate.log.1").good() == false);
    stop_log_rotation();
  }
};

BOOST_FIXTURE_TEST_SUITE(_logger_test, logger_test)
BOOST_AUTO_TEST_CASE(test_empty_log) {
  logger_test::test_empty_log();
}
BOOST_AUTO_TEST_CASE(test_log_level_setter) {
  logger_test::test_log_level_setter();
}
BOOST_AUTO_TEST_CASE(test_log_rotation) {
  logger_test::test_log_rotation();
}
BOOST_AUTO_TEST_SUITE_END()

ext: cxx

max_forks_repo_name: ZeroInfinite/turicreate


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

#ifndef MTL_MATRIX_ALGORITHMS_INCLUDE
#define MTL_MATRIX_ALGORITHMS_INCLUDE

#include <boost/numeric/mtl/interface/vpt.hpp>
#include <boost/numeric/mtl/mtl.hpp>
#include <boost/numeric/mtl/matrix/element.hpp>
#include <boost/numeric/mtl/matrix/element_structure.hpp>

#include <iostream>

namespace mtl {  namespace mat {

/// Construct the sparse data structure from an elementstructure
template< typename ElementStructure, typename Matrix, typename Vector>
void assemble_compressed(const ElementStructure& es, Matrix& A, Vector& order)
{

    typedef typename ElementStructure::element_type::value_type   value_type;
    typedef typename ElementStructure::element_iterator           iterator;
    typedef typename ElementStructure::element_type               element_type;
    typedef typename element_type::index_type                     index_type;
    typedef typename element_type::matrix_type                    matrix_type;
    typedef typename matrix_type::size_type                       size_type;
    A.change_dim(es.get_total_vars(), es.get_total_vars());
    set_to_zero(A);
    value_type zero(0);

    {//start inserterblock
	mtl::mat::inserter<Matrix, mtl::operations::update_plus<value_type> >  ins(A);
	for (iterator it = es.element_begin(); it != es.element_end(); ++it) {
	    element_type& element = *it;
	    const index_type& idx = element.get_indices();
	    matrix_type& values = element.get_values();
	    for (std::size_t i = 0; i < element.nb_vars(); ++i)
		for (std::size_t j = 0; j < element.nb_vars(); ++j)
		    if (values(i,j) != zero)
			ins[size_type(order(idx(i)))][size_type(order(idx(j)))] << values(i,j);
	}
    }//end inserterblock
}

/// Construct the sparse data structure from an elementstructure
template< typename ElementStructure, typename Matrix>
void assemble_compressed(const ElementStructure& es, Matrix& A)
{
  typedef typename  ElementStructure::element_type::matrix_type::size_type size_type;
  mtl::dense_vector<size_type> ident(es.get_total_vars());
  iota(ident);
  assemble_compressed(es, A, ident);
}

}}//end namespace mtl

#endif // MTL_MATRIX_ALGORITHMS_INCLUDE

ext: hpp


text:
#include <type_safe/constrained_type.hpp>
#include <type_safe/flag.hpp>
#include <type_safe/integer.hpp>
#include <type_safe/optional.hpp>

#include <boost/core/demangle.hpp>

#include <iostream>
#include <limits>
#include <type_traits>

#include <boost/test/unit_test.hpp>

namespace ts = type_safe;

using namespace std;

using boost::core::demangle;

BOOST_AUTO_TEST_SUITE(type_safe)

BOOST_AUTO_TEST_CASE(ts_integer)
{
    {
        using ts_uint = ts::integer<unsigned>;

        const ts_uint      a{1u};
        const unsigned int b{2};

        const ts_uint c = a + b;
        BOOST_TEST(c == ts::make_unsigned(3));
    }
    {
        using ts_uint = ts::integer<unsigned, ts::checked_arithmetic>;

        const ts_uint a{numeric_limits<ts_uint::integer_type>::max() - 1};
        const auto    b{2u};

        BOOST_REQUIRE_THROW(a + b, ts::checked_arithmetic::error);
    }
}

BOOST_AUTO_TEST_CASE(ts_flag)
{
    using flag = ts::flag;
    {
        flag a{true};

        BOOST_TEST(a.toggle());
        BOOST_TEST(!a.toggle());

        a.change(false);
        a.change(true);

        a.set();
        a.reset();

        BOOST_TEST(a.try_set());
        BOOST_TEST(!a.try_set());

        BOOST_TEST(a.try_reset());
        BOOST_TEST(!a.try_reset());
    }
    {
        vector      nums = {1, 2, 1, 3, 4, 1, 5, 6, 7};
        flag        found_one{false};
        vector<int> nums_after_one{};
        for(const auto& a : nums) {
            if(a == 1)
                found_one.change(true);
            else if(found_one.try_reset())
                nums_after_one.push_back(a);
        }
        const vector expected{2, 3, 5};
        BOOST_REQUIRE_EQUAL_COLLECTIONS(begin(nums_after_one), end(nums_after_one), begin(expected),
                                        end(expected));
    }
}

struct boost_test_verifier
{
    template <class Value, class Constrain>
    static constexpr Value verify(Value a, const Constrain& c)
    {
        BOOST_TEST(c(a), "constraint: \"" << demangle(typeid(c).name())
                                          << "\" not satisfied with value = " << a);
        return a;
    }
};

struct is_odd
{
    template <class Value>
    struct is_valid : is_unsigned<Value>
    {
    };

    template <class Value>
    constexpr bool operator()(Value a) const noexcept(noexcept(a % 2))
    {
        return a % 2;
    }
};

using always_odd = ts::constrained_type<unsigned, is_odd, boost_test_verifier>;

ostream& operator<<(ostream& s, const always_odd& v)
{
    s << "always_odd(" << v.get_value() << ")";
    return s;
}

BOOST_AUTO_TEST_CASE(ts_constrained_type)
{
    static_assert(!is_constructible<always_odd, signed>::value);
    always_odd a{3u};
    BOOST_TEST(is_odd{}(a.get_value()));

    const auto b = ts::constrain<boost_test_verifier>(3u, is_odd{});
    static_assert(is_same_v<decay_t<decltype(b)>, always_odd>);
    BOOST_TEST(a == b);

    auto a_mod = a.modify();
    a_mod.get() += 2;
    ts::with(a, [](auto& a) { a -= 2; });
    BOOST_TEST(a == b);
}

BOOST_AUTO_TEST_CASE(ts_optional)
{
    ts::optional<int> a;
    BOOST_TEST(!a.has_value());
    BOOST_TEST(a.value_or(11) == 11);

    a = 11;
    ts::optional<string> b = a.map([](const auto& a) { return to_string(a); })
                                 .map([](const auto& a) { return stoi(a); })
                                 .map([](const auto& a) { return to_string(a); });
    BOOST_TEST(b.has_value());
    BOOST_TEST(b.value() == "11");

    int i;
    ts::with(b, [](const auto& a, auto& b) { b = stoi(a); }, i);
    BOOST_TEST(i == 11);
}

BOOST_AUTO_TEST_SUITE_END()

ext: cpp


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

	.

	@author		Johan Pauwels
	@date		20100913
*/
//============================================================================

#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <ctime>
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/program_options.hpp>
#include <Eigen/Core>
#include "MusOO/ModeQMUL.h"
#include "MusOO/ChordTypeQMUL.h"
#include "MusOOFile/KeyFileUtil.h"
#include "MusOOFile/ChordFileUtil.h"
#include "MusOOFile/NoteFileMaps.h"
#include "PairwiseEvaluation.h"
#include "KeyEvaluationStats.h"
#include "ChordEvaluationStats.h"
#include "NoteEvaluationStats.h"
#include "SimilarityScoreKey.h"
#include "SimilarityScoreChord.h"
#include "SimilarityScoreNote.h"
#include "SegmentationEvaluation.h"

using std::cout;
using std::cerr;
using std::endl;
using std::fixed;
using std::setw;
using std::setprecision;
using std::string;
using std::vector;
using std::exception;
using std::invalid_argument;
using std::runtime_error;
using boost::filesystem::path;
using boost::filesystem::ifstream;
using boost::filesystem::ofstream;
using boost::program_options::options_description;
using boost::program_options::value;
using boost::program_options::variables_map;
using boost::program_options::parse_command_line;
using boost::program_options::store;
using boost::program_options::notify;
using namespace MusOO;

void parseCommandLine(int inNumOfArguments, char* inArguments[], path& outOutputFilePath, path& outListPath,
                      path& outRefPath, path& outTestPath, string& outRefExt, string& outTestExt, string& outRefFormat,
                      string& outTestFormat, double& outBegin, double& outEnd, double& outMinRefDuration, double& outMaxRefDuration, double& outTimeDelay,
                      variables_map& outVarMap)
{
	options_description theGeneralOptions("General options");
	theGeneralOptions.add_options()
		("help,h", "produce this help message")
		("output", value<path>(&outOutputFilePath), "path to the output file")
		("chords", value<string>(), "select chords mode")
		("keys", value<string>(), "select keys mode")
		("globalkey", value<string>(), "select global key mode")
        ("notes", value<string>(), "select notes mode")
        ("segmentation", value<string>(), "select segmentation mode")
        ("refformat", value<string>(&outRefFormat)->default_value("auto"), "format of the reference file(s)")
        ("testformat", value<string>(&outTestFormat)->default_value("auto"), "format of the file(s) under test")
		("csv", "Print results for individual files to file in comma separated format")
        ("confusion", value<path>(), "path to resulting global confusion matrix")
        ("verbose", "Write comparison file for each individual file")
        ("begin", value<double>(&outBegin)->default_value(0.), "the start time in seconds")
        ("end", value<double>(&outEnd)->default_value(0., "file end"), "the end time in seconds")
        ("minduration", value<double>(&outMinRefDuration)->default_value(0.), "minimum duration the reference label needs to have to be included in evaluation")
        ("maxduration", value<double>(&outMaxRefDuration)->default_value(std::numeric_limits<double>::infinity(), "inf"), "maximum duration the reference label is allowed to have to be included in evaluation")
        ("delay", value<double>(&outTimeDelay)->default_value(0.), "Add a time delay to the files to evaluate")
		;

	options_description theRelativeListOptions("Relative list options");
	theRelativeListOptions.add_options()
		("list", value<path>(&outListPath), "list with base file names")
        ("refdir", value<path>(&outRefPath), "directory with reference annotations")
        ("refext", value<string>(&outRefExt), "extension of the reference annotations")
		("testdir", value<path>(&outTestPath), "directory with files to evaluate")
		("testext", value<string>(&outTestExt), "extension of the files to evaluate")
		("timingdir", value<path>(), "directory with files with start and end times")
		("timingext", value<string>()->default_value("-timing.txt"), "extension of the files with start and end times")
		;

	options_description theSingleFileOptions("Single file options");
	theSingleFileOptions.add_options()
        ("reffile", value<path>(&outRefPath), "file with reference annotation")
        ("testfile", value<path>(&outTestPath), "file to evaluate")
        ("timingfile", value<path>(), "file with start and end times")
        ;

	options_description theOptions;
	theOptions.add(theGeneralOptions).add(theRelativeListOptions).add(theSingleFileOptions);

	store(parse_command_line(inNumOfArguments, inArguments, theOptions), outVarMap);
	notify(outVarMap);

	if (inNumOfArguments < 2 ||outVarMap.count("help") > 0)
	{
		cout << "Description: This application compares music label sequences.\n"
			<< "    The reference and test sequence(s) can be specified by two modes:\n"
			<< "    as single files or as a list of multiple files.\n" << endl;
		cout << theOptions << endl;
		cout << "Author: Johan Pauwels - Build: " << __DATE__ << endl;
		cout << endl;
		exit(0);
	}

	if (outVarMap.count("chords") + outVarMap.count("keys") + outVarMap.count("globalkey") + outVarMap.count("notes") + outVarMap.count("segmentation") != 1)
	{
		throw invalid_argument("Please select a single 'chords', 'keys', 'globalkey', 'notes' or 'segmentation' mode");
	}
	if (!exists(absolute(outOutputFilePath.parent_path())))
	{
		create_directories(outOutputFilePath.parent_path());
	}

	if (outVarMap.count("list") > 0)
    {
        // One list mode
        if (!is_regular_file(outListPath))
        {
            throw invalid_argument("'" + outListPath.string() + "' is not an existing file");
        }
        if (outVarMap.count("refdir") > 0)
        {
             if(!is_directory(outRefPath))
            {
                throw invalid_argument("'" + outRefPath.string() + "' is not an existing directory");
            }
        }
        else
        {
            throw invalid_argument("Please specifiy a reference directory");
        }
        if (outVarMap.count("testdir") > 0)
        {
            if (!is_directory(outTestPath))
            {
                throw invalid_argument("'" + outTestPath.string() + "' is not an existing directory");
            }
        }
        else
        {
            throw invalid_argument("Please specifiy a test directory");
        }
        if (outVarMap.count("timingdir") > 0 && !is_directory(outVarMap["timingdir"].as<path>()))
        {
            throw invalid_argument("'" + outVarMap["timingdir"].as<path>().string() + "' is not an existing directory");
        }
    }
    else
    {
        // Single file mode
        if (outVarMap.count("reffile") > 0)
        {
            if (!is_regular_file(outRefPath))
            {
                throw invalid_argument("'" + outRefPath.string() + "' is not an existing file");
            }
        }
        else
        {
            throw invalid_argument("Please specifiy a reference file");
        }
        if (outVarMap.count("testfile") > 0)
        {
            if (!is_regular_file(outTestPath))
            {
                throw invalid_argument("'" + outTestPath.string() + "' is not an existing file");
            }
        }
        else
        {
            throw invalid_argument("Please specifiy a test file");
        }
        if (outVarMap.count("timingfile") > 0 && !is_regular_file(outVarMap["timingfile"].as<path>()))
        {
            throw invalid_argument("'" + outVarMap["timingfile"].as<path>().string() + "' is not an existing file");
        }
    }
}

const std::vector<std::string> readList(const path& inListPath)
{
    if (inListPath.empty())
    {
        return vector<string>(1, "");
    }
    else
    {
        vector<string> theListItems;
        ifstream theListIn(inListPath);

        if(!theListIn.is_open())
        {
            throw runtime_error("Could not open list '" + inListPath.string() + "'");
        }
        std::stringstream theFileStream;
        normaliseLineEndings(theListIn, theFileStream);
        //run over all files in the list
        string theListItem;
        while(getline(theFileStream, theListItem))
        {
            if (!theListItem.empty() && theListItem[0] != '#')
            {
                if ((theListItem[0] == '"' && *(theListItem.end()-1) == '"') || (theListItem[0] == '\'' && *(theListItem.end()-1) == '\''))
                {
                    theListItem.erase(theListItem.begin());
                    theListItem.erase(theListItem.end()-1);
                }
                theListItems.push_back(theListItem);
            }
        }
        return theListItems;
    }
}

Key findLongestKey(TimedKeySequence inKeySequence)
{
	vector<std::pair<Key,double> > theUniqueKeys;
	//	std::unordered_map<Key,double> theUniqueKeys;
	for (TimedKeySequence::const_iterator i = inKeySequence.begin(); i != inKeySequence.end(); ++i)
	{
		//		theUniqueKeys[i->label()] += i->offset()-i->onset();
		bool theKeyFound = false;
		for (size_t j = 0; j < theUniqueKeys.size(); ++j)
		{
			if (i->label() == theUniqueKeys[j].first)
			{
				theUniqueKeys[j].second += i->offset()-i->onset();
				theKeyFound = true;
			}
		}
		if (!theKeyFound)
		{
			theUniqueKeys.push_back(std::pair<Key,double>(i->label(), i->offset()-i->onset()));
		}
	}
	Key theLongestKey = theUniqueKeys.front().first;
	double theDuration = theUniqueKeys.front().second;
	for (size_t j = 1; j < theUniqueKeys.size(); ++j)
	{
		if (theUniqueKeys[j].second > theDuration)
		{
			theLongestKey = theUniqueKeys[j].first;
			theDuration = theUniqueKeys[j].second;
		}
	}
	return theLongestKey;
}

void constructPaths(std::string& ioBaseName, const path& theRefDirName, const std::string& theRefExt, const path& theTestDirName, const std::string& theTestExt, const variables_map& theVarMap, path& outRefFileName, path& outTestFileName, double& outBegin, double& outEnd)
{
    if (ioBaseName.empty())
    {
        ioBaseName = theTestDirName.stem().string();
        outRefFileName = theRefDirName;
        outTestFileName = theTestDirName;
    }
    else
    {
        outRefFileName = theRefDirName / path(ioBaseName + theRefExt);
        outTestFileName = theTestDirName / path(ioBaseName + theTestExt);
    }
    if (theVarMap.count("timingdir") > 0 || theVarMap.count("timingfile") > 0)
    {
        path theTimingPath;
        if (theVarMap.count("timingdir") > 0)
        {
            theTimingPath = theVarMap["timingdir"].as<path>() / path(ioBaseName + theVarMap["timingext"].as<string>());
        }
        else
        {
            theTimingPath = theVarMap["timingfile"].as<path>();
        }
        boost::filesystem::ifstream theTimingFile(theTimingPath);
        if (!theTimingFile.is_open())
        {
            throw runtime_error("Could not open file '" + theTimingPath.string() + "' for reading.");
        }
        theTimingFile >> outBegin >> outEnd;
    }
}

const std::string printResultLine(const double inResult, const double inTotal, const std::string& inUnit)
{
    std::ostringstream stringStream;
    stringStream << inResult << inUnit << " (";
    if (inTotal > 0)
    {
        stringStream << 100 * inResult / inTotal << "%)";
    }
    else
    {
        stringStream << "n/a)";
    }
    return stringStream.str();
}

/**	Start point of the program. */
int main(int inNumOfArguments,char* inArguments[])
{ try {

	path theOutputPath;
	path theListPath;
	path theRefDirPath;
	path theTestDirPath;
	string theRefExt;
	string theTestExt;
    string theRefFormat;
    string theTestFormat;
	double theBegin;
	double theEnd;
    double theMinRefDuration;
    double theMaxRefDuration;
	double theDelay;
	variables_map theVarMap;

	parseCommandLine(inNumOfArguments, inArguments, theOutputPath, theListPath,
		theRefDirPath, theTestDirPath, theRefExt, theTestExt, theRefFormat, theTestFormat,
		theBegin, theEnd, theMinRefDuration, theMaxRefDuration, theDelay, theVarMap);

	string theCSVSeparator = ",";
    string theCSVQuotes = "\"";

    path theRefPath;
    path theTestPath;
	double theTotalDuration;
	Eigen::ArrayXXd theGlobalConfusionMatrix;
	vector<string> theLabels;

	vector<string> theListItems = readList(theListPath);

	ofstream theOutputFile(theOutputPath);
	if (!theOutputFile.is_open())
	{
		throw runtime_error("Could not open output file '" + theOutputPath.string() + "'");
	}
    if (!theListPath.empty())
    {
        theOutputFile << "List: " << theListPath << "\n" << endl;
    }
    else
    {
        theOutputFile << "Files: " << theRefDirPath << " vs " << theTestDirPath << "\n" << endl;
    }

	/**********************/
	/* Keys or global key */
	/**********************/
	if (theVarMap.count("keys") > 0 || theVarMap.count("globalkey") > 0)
	{
		PairwiseEvaluation<Key>* theKeyEvaluation = NULL;
		if (theVarMap.count("keys") > 0)
		{
			theKeyEvaluation = new PairwiseEvaluation<Key>(theVarMap["keys"].as<string>());
		}
		else
		{
			theKeyEvaluation = new PairwiseEvaluation<Key>(theVarMap["globalkey"].as<string>());
		}
        theLabels.resize(theKeyEvaluation->getNumOfTestLabels());
        std::transform(theKeyEvaluation->getLabels().begin(), theKeyEvaluation->getLabels().end(), theLabels.begin(), std::mem_fun_ref(&MusOO::KeyQMUL::str));

		ofstream theCSVFile;
		if (theVarMap.count("csv") > 0)
		{
			theCSVFile.open(path(theOutputPath).replace_extension("csv"));
			if (theVarMap.count("keys") > 0)
			{
				theCSVFile << theVarMap["keys"].as<string>() << endl;
				theCSVFile << "File" << theCSVSeparator << "Pairwise score (%)"
					<< theCSVSeparator << "Duration (s)"
					<< theCSVSeparator << "Unique ref keys"
                    << theCSVSeparator << "Unique test keys"
                    << theCSVSeparator << "Correct keys"
                    << theCSVSeparator << "Adjacent keys"
                    << theCSVSeparator << "Relative keys"
                    << theCSVSeparator << "Parallel keys"
                    << theCSVSeparator << "Chromatic keys" << endl;
			}
			else
			{
				theCSVFile << theVarMap["globalkey"].as<string>() << endl;
				theCSVFile << "File"
					<< theCSVSeparator << "Score"
					<< theCSVSeparator << "Ref key"
					<< theCSVSeparator << "Test key" << endl;
			}
			theCSVFile << std::fixed;
		}

        theGlobalConfusionMatrix = Eigen::ArrayXXd::Zero(theKeyEvaluation->getNumOfRefLabels(), theKeyEvaluation->getNumOfTestLabels());
        double theGlobalKeyScore = 0.;
		for (vector<string>::iterator i = theListItems.begin(); i != theListItems.end(); ++i)
		{
            constructPaths(*i, theRefDirPath, theRefExt, theTestDirPath, theTestExt, theVarMap, theRefPath, theTestPath, theBegin, theEnd);
			cout << "Evaluating file " << *i << endl;

            TimedKeySequence theRefKeys = KeyFileUtil::readKeySequenceFromFile(theRefPath, true, theRefFormat);
			TimedKeySequence theTestKeys = KeyFileUtil::readKeySequenceFromFile(theTestPath, false, theTestFormat);

			if (theVarMap.count("keys") > 0)
			{
                ofstream theVerboseStream;
                if (theVarMap.count("verbose"))
                {
                    path theVerbosePath = theOutputPath.parent_path() / path(*i + ".csv");
                    theVerboseStream.open(theVerbosePath);
                    theVerboseStream << "Start" << theCSVSeparator << "End" << theCSVSeparator << "RefLabel" << theCSVSeparator << "TestLabel" << theCSVSeparator << "Score" << theCSVSeparator << "Duration" << endl;
                }
				theKeyEvaluation->addSequencePair(theRefKeys, theTestKeys, theBegin, theEnd, theVerboseStream, theMinRefDuration, theMaxRefDuration, theDelay);

				if (theVarMap.count("csv") > 0)
				{
					KeyEvaluationStats theStats(theKeyEvaluation->getConfusionMatrix());
					theCSVFile << theCSVQuotes << *i << theCSVQuotes << theCSVSeparator
						<< 100*theKeyEvaluation->getScore() << theCSVSeparator
						<< theKeyEvaluation->getDuration() << theCSVSeparator
						<< theStats.getNumOfUniquesInRef() << theCSVSeparator
                        << theStats.getNumOfUniquesInTest() << theCSVSeparator
                        << theStats.getCorrectKeys() << theCSVSeparator
                        << theStats.getAdjacentKeys() << theCSVSeparator
                        << theStats.getRelativeKeys() << theCSVSeparator
                        << theStats.getParallelKeys() << theCSVSeparator
                        << theStats.getChromaticKeys() << endl;
				}
			}
			else
			{
				SimilarityScoreKey theSimilarityScoreKey(theVarMap["globalkey"].as<string>());
				Key theGlobalRefKey = findLongestKey(theRefKeys);
				Key theGlobalTestKey = findLongestKey(theTestKeys);
				double theScore = theSimilarityScoreKey.score(theGlobalRefKey, theGlobalTestKey);
                theGlobalKeyScore += theScore;
				++theGlobalConfusionMatrix(theSimilarityScoreKey.getRefIndex(), theSimilarityScoreKey.getTestIndex());
				if (theVarMap.count("csv") > 0)
				{
					theCSVFile << theCSVQuotes << *i << theCSVQuotes << theCSVSeparator
						<< theScore << theCSVSeparator
						<< KeyQMUL(theGlobalRefKey).str() << theCSVSeparator
						<< KeyQMUL(theGlobalTestKey).str() << endl;
				}
			}
 		}

        // Global output file
        string theUnit;
		if (theVarMap.count("keys") > 0)
		{
            theUnit = " s";
            theTotalDuration = theKeyEvaluation->calcTotalDuration();
            theGlobalConfusionMatrix = theKeyEvaluation->calcTotalConfusionMatrix();
			string theKeyMode = theVarMap["keys"].as<string>();
			theOutputFile << string(theKeyMode.size()+9,'*') << "\n* Keys " << theKeyMode << " *\n" << string(theKeyMode.size()+9,'*') << endl;
            theOutputFile << "Duration of evaluated keys: " << theTotalDuration << " s" << endl;
            theOutputFile << "Average score: " << 100 * theKeyEvaluation->calcWeightedAverageScore() << "%\n" << endl;
		}
		else
        {
            theTotalDuration = theListItems.size();
            theGlobalKeyScore /= theTotalDuration;
			string theGlobalKeyMode = theVarMap["globalkey"].as<string>();
			theOutputFile << string(theGlobalKeyMode.size()+15,'*') << "\n* Global key " << theGlobalKeyMode << " *\n" << string(theGlobalKeyMode.size()+15,'*') << endl;
            theOutputFile << "Number of evaluated files: " << theTotalDuration << endl;
            theOutputFile << "Average score: " << 100 * theGlobalKeyScore << "%\n" << endl;
		}

		KeyEvaluationStats theGlobalStats(theGlobalConfusionMatrix);
        theOutputFile << "Correct keys: " << printResultLine(theGlobalStats.getCorrectKeys(), theTotalDuration, theUnit) << endl;
        theOutputFile << "Adjacent keys: " << printResultLine(theGlobalStats.getAdjacentKeys(), theTotalDuration, theUnit) << endl;
        theOutputFile << "Relative keys: " << printResultLine(theGlobalStats.getRelativeKeys(), theTotalDuration, theUnit) << endl;
        theOutputFile << "Parallel keys: " << printResultLine(theGlobalStats.getParallelKeys(), theTotalDuration, theUnit) << endl;
        theOutputFile << "Chromatic keys: " << printResultLine(theGlobalStats.getChromaticKeys(), theTotalDuration, theUnit) << endl;

		if (theVarMap.count("keys") > 0)
		{
            theOutputFile << "Deleted keys: " << printResultLine(theGlobalStats.getKeyDeletions(), theTotalDuration, theUnit) << endl;
            theOutputFile << "\nCorrect no-keys: " << printResultLine(theGlobalStats.getCorrectNoKeys(), theTotalDuration, theUnit) << endl;
            theOutputFile << "Inserted keys: " << printResultLine(theGlobalStats.getKeyInsertions(), theTotalDuration, theUnit) << endl;
		}

        theOutputFile << "\nResults per mode\n" << "----------------" << endl;
        const Eigen::ArrayXXd theResultsPerMode = theGlobalStats.getCorrectKeysPerMode();
        for (Eigen::ArrayXXd::Index iMode = 0; iMode < theResultsPerMode.rows(); ++iMode)
        {
            theOutputFile << ModeQMUL(theKeyEvaluation->getLabels()[iMode].mode()) << ": "
                << printResultLine(theResultsPerMode(iMode,0), theResultsPerMode(iMode,1), theUnit) << " of "
                << printResultLine(theResultsPerMode(iMode,1), theTotalDuration, theUnit) << endl;
        }
		delete theKeyEvaluation;
	}
	/**********/
	/* Chords */
	/**********/
	else if (theVarMap.count("chords") > 0)
	{
		PairwiseEvaluation<Chord> theChordEvaluation(theVarMap["chords"].as<string>());
        theLabels.resize(theChordEvaluation.getNumOfTestLabels());
        std::transform(theChordEvaluation.getLabels().begin(), theChordEvaluation.getLabels().end(), theLabels.begin(), std::mem_fun_ref(&MusOO::ChordQMUL::str));
        const size_t numChordTypes = theChordEvaluation.getNumOfRefLabels()/12;
        vector<size_t> cardinalities(numChordTypes);
        std::transform(theChordEvaluation.getLabels().begin(), theChordEvaluation.getLabels().begin()+numChordTypes, cardinalities.begin(), std::mem_fun_ref(&MusOO::Chord::cardinality));
        const size_t maxCardinality = *std::max_element(cardinalities.begin(), cardinalities.end());
        const size_t minCardinality = *std::min_element(cardinalities.begin(), cardinalities.end());

		ofstream theCSVFile;
		if (theVarMap.count("csv") > 0)
		{
			theCSVFile.open(path(theOutputPath).replace_extension("csv"));
			theCSVFile << theVarMap["chords"].as<string>() << endl;
			theCSVFile << "File"
				<< theCSVSeparator << "Pairwise score (%)"
                << theCSVSeparator << "Duration (s)"
                << theCSVSeparator << "Correct chords (%)"
                << theCSVSeparator << "Substituted chords (%)"
                << theCSVSeparator << "Deleted chords (%)"
                << theCSVSeparator << "Inserted chords (%)"
                << theCSVSeparator << "Correct no-chords (%)";
            for (size_t iChordType = 0; iChordType < numChordTypes; ++iChordType)
            {
                theCSVFile << theCSVSeparator << theCSVQuotes << ChordTypeQMUL(theChordEvaluation.getLabels()[iChordType].type()) << " correct (%)" << theCSVQuotes << theCSVSeparator << theCSVQuotes << ChordTypeQMUL(theChordEvaluation.getLabels()[iChordType].type()) << " proportion (%)" << theCSVQuotes;
            }
            for (size_t iNumOfWrongChromas = 0; iNumOfWrongChromas <= maxCardinality; ++iNumOfWrongChromas)
            {
                theCSVFile << theCSVSeparator << iNumOfWrongChromas << " chroma" << (iNumOfWrongChromas==1?"":"s") << " wrong (%)";
            }
            theCSVFile
				<< theCSVSeparator << "Both correct (%)"
				<< theCSVSeparator << "Only root correct (%)"
				<< theCSVSeparator << "Only type correct (%)"
				<< theCSVSeparator << "Both wrong (%)"
				<< theCSVSeparator << "Unique ref chords"
				<< theCSVSeparator << "Unique test chords" << endl;
			theCSVFile << std::fixed;
		}

		for (vector<string>::iterator i = theListItems.begin(); i != theListItems.end(); ++i)
		{
            constructPaths(*i, theRefDirPath, theRefExt, theTestDirPath, theTestExt, theVarMap, theRefPath, theTestPath, theBegin, theEnd);
			cout << "Evaluating file " << *i << endl;

			TimedChordSequence theRefChords = ChordFileUtil::readChordSequenceFromFile(theRefPath, true, theRefFormat);
            TimedChordSequence theTestChords = ChordFileUtil::readChordSequenceFromFile(theTestPath, false, theTestFormat);

            ofstream theVerboseStream;
            if (theVarMap.count("verbose"))
            {
                path theVerbosePath = theOutputPath.parent_path() / path(*i + ".csv");
                theVerboseStream.open(theVerbosePath);
                theVerboseStream << "Start" << theCSVSeparator << "End" << theCSVSeparator << "RefLabel" << theCSVSeparator << "TestLabel" << theCSVSeparator << "Score" << theCSVSeparator << "Duration" << theCSVSeparator << "MappedRefLabel" << theCSVSeparator << "MappedTestLabel" << theCSVSeparator << "RefChromas" << theCSVSeparator << "TestChromas" << theCSVSeparator << "NumCommonChromas" << theCSVSeparator << "RefBass" << theCSVSeparator << "TestBass" << endl;
            }
			theChordEvaluation.addSequencePair(theRefChords, theTestChords, theBegin, theEnd, theVerboseStream, theMinRefDuration, theMaxRefDuration, theDelay);

			if (theVarMap.count("csv") > 0)
			{
                theCSVFile << theCSVQuotes << *i << theCSVQuotes << theCSVSeparator;
                ChordEvaluationStats theStats(theChordEvaluation.getConfusionMatrix(), theChordEvaluation.getLabels());
                double theDuration = theChordEvaluation.getDuration();
				if (theDuration > 0.)
				{
					theCSVFile << 100*theChordEvaluation.getScore() << theCSVSeparator << theDuration;
                    theCSVFile
                        << theCSVSeparator << 100*theStats.getCorrectChords()/theDuration
                        << theCSVSeparator << 100*theStats.getChordSubstitutions()/theDuration
                        << theCSVSeparator << 100*theStats.getChordDeletions()/theDuration
                        << theCSVSeparator << 100*theStats.getChordInsertions()/theDuration
                        << theCSVSeparator << 100*theStats.getCorrectNoChords()/theDuration;
                    const Eigen::ArrayXXd theResultsPerType = theStats.getCorrectChordsPerType();
                    for (Eigen::ArrayXXd::Index iChordType = 0; iChordType < theResultsPerType.rows(); ++iChordType)
                    {
                        theCSVFile
                            << theCSVSeparator << 100*theResultsPerType(iChordType,0)/theResultsPerType(iChordType,1)
                            << theCSVSeparator << 100*theResultsPerType(iChordType,1)/theDuration;
                    }
                    for (size_t iNumOfWrongChromas = 0; iNumOfWrongChromas <= maxCardinality; ++iNumOfWrongChromas)
                    {
                        theCSVFile << theCSVSeparator << 100*theStats.getChordsWithNWrong(iNumOfWrongChromas)/theDuration;
                    }
                    theCSVFile
                        << theCSVSeparator << 100*theStats.getCorrectChords()/theDuration
						<< theCSVSeparator << 100*theStats.getOnlyRootCorrect()/theDuration
						<< theCSVSeparator<< 100*theStats.getOnlyTypeCorrect()/theDuration
						<< theCSVSeparator << 100*theStats.getBothRootAndTypeWrong()/theDuration;
				}
				else
				{
					theCSVFile << "n/a" << theCSVSeparator << theDuration;
                    for (size_t i = 0; i < 9+2*numChordTypes+maxCardinality+1; ++i)
                    {
                        theCSVFile << theCSVSeparator << "n/a";
                    }
				}
                theCSVFile << theCSVSeparator << theStats.getNumOfUniquesInRef() << theCSVSeparator << theStats.getNumOfUniquesInTest() << endl;
			}
		}
		theCSVFile.close();

        // Global output file
        theTotalDuration = theChordEvaluation.calcTotalDuration();
		string theChordMode = theVarMap["chords"].as<string>();
		theOutputFile << string(theChordMode.size()+11,'*') << "\n* Chords " << theChordMode << " *\n"
        << string(theChordMode.size()+11,'*') << endl;
		theOutputFile << "Duration of evaluated chords: " << theTotalDuration << " s" << endl;
		theOutputFile << "Average score: " << 100 * theChordEvaluation.calcWeightedAverageScore() << "%" << endl;

        theGlobalConfusionMatrix = theChordEvaluation.calcTotalConfusionMatrix();
		ChordEvaluationStats theGlobalStats(theGlobalConfusionMatrix, theChordEvaluation.getLabels());
        theOutputFile << "\nChord detection results\n" << "-----------------------" << endl;
		theOutputFile << "Correct chords: " << printResultLine(theGlobalStats.getCorrectChords(), theTotalDuration, " s") << endl;
		theOutputFile << "Substituted chords: " << printResultLine(theGlobalStats.getChordSubstitutions(), theTotalDuration, " s") << endl;
		theOutputFile << "Deleted chords: " << printResultLine(theGlobalStats.getChordDeletions(), theTotalDuration, " s") << endl;
		theOutputFile << "Inserted chords: " << printResultLine(theGlobalStats.getChordInsertions(), theTotalDuration, " s") << endl;
		theOutputFile << "Correct no-chords: " << printResultLine(theGlobalStats.getCorrectNoChords(), theTotalDuration, " s") << endl;

        theOutputFile << "\nResults per chord type\n" << "----------------------" << endl;
        const Eigen::ArrayXXd theResultsPerType = theGlobalStats.getCorrectChordsPerType();
        for (Eigen::ArrayXXd::Index iChordType = 0; iChordType < theResultsPerType.rows(); ++iChordType)
        {
            theOutputFile << ChordTypeQMUL(theChordEvaluation.getLabels()[iChordType].type()) << ": "
                << printResultLine(theResultsPerType(iChordType,0), theResultsPerType(iChordType,1), " s") << " of "
                << printResultLine(theResultsPerType(iChordType,1), theTotalDuration, " s") << endl;
        }

        theOutputFile << "\nResults per number of chromas wrong\n" << "-----------------------------------" << endl;
        theOutputFile << "0 chromas wrong: " << printResultLine(theGlobalStats.getChordsWithNWrong(0), theTotalDuration, " s") << endl;
        theOutputFile << "  of which root correct: " << printResultLine(theGlobalStats.getCorrectChords(), theTotalDuration, " s") << endl;
        theOutputFile << "  of which root incorrect: " << printResultLine(theGlobalStats.getChordsWithNWrong(0)-theGlobalStats.getCorrectChords(), theTotalDuration, " s") << endl;
        for (size_t iNumOfWrongChromas = 1; iNumOfWrongChromas <= maxCardinality; ++iNumOfWrongChromas)
        {
            theOutputFile << iNumOfWrongChromas << " chroma" << (iNumOfWrongChromas==1?"":"s") << " wrong: " << printResultLine(theGlobalStats.getChordsWithNWrong(iNumOfWrongChromas), theTotalDuration, " s") << endl;
            theOutputFile << "  of which " << iNumOfWrongChromas << " substitution" << (iNumOfWrongChromas==1?"":"s") << ": " << printResultLine(theGlobalStats.getChordsWithSDI(iNumOfWrongChromas, 0, 0), theTotalDuration, " s") << endl;
            //prune impossible combinations for this set of chord types
            if (minCardinality + iNumOfWrongChromas <= maxCardinality)
            {
                theOutputFile << "  of which " << iNumOfWrongChromas << " deletion" << (iNumOfWrongChromas==1?"":"s") << ": " << printResultLine(theGlobalStats.getChordsWithSDI(0, iNumOfWrongChromas, 0), theTotalDuration, " s") << endl;
            }
            if (maxCardinality - iNumOfWrongChromas >= minCardinality)
            {
                theOutputFile << "  of which " << iNumOfWrongChromas << " insertion" << (iNumOfWrongChromas==1?"":"s") << ": " << printResultLine(theGlobalStats.getChordsWithSDI(0, 0, iNumOfWrongChromas), theTotalDuration, " s") << endl;
            }
            for (size_t iNumSubstitutions = iNumOfWrongChromas-1; iNumSubstitutions > 0; --iNumSubstitutions)
            {
                const size_t numDI = iNumOfWrongChromas-iNumSubstitutions;
                if (minCardinality + numDI <= maxCardinality)
                {
                    theOutputFile << "  of which " << iNumSubstitutions << " substitution" << (iNumSubstitutions==1?"":"s") << ", " << numDI << " deletion" << (numDI==1?"":"s") << ": " << printResultLine(theGlobalStats.getChordsWithSDI(iNumSubstitutions, numDI, 0), theTotalDuration, " s") << endl;
                }
                if (maxCardinality - numDI >= minCardinality)
                {
                    theOutputFile << "  of which " << iNumSubstitutions << " substitution" << (iNumSubstitutions==1?"":"s") << ", " << numDI << " insertion" << (numDI==1?"":"s") << ": " << printResultLine(theGlobalStats.getChordsWithSDI(iNumSubstitutions, 0, numDI), theTotalDuration, " s") << endl;
                }
            }
        }
        const double unknownWrong = theGlobalStats.getChordsWithUnknownWrong();
        if (unknownWrong > 0.)
        {
            theOutputFile << "unknown chromas wrong: " << printResultLine(unknownWrong, theTotalDuration, " s") << endl;
        }

        theOutputFile << "\nRoot/type results\n" << "-----------------" << endl;
        theOutputFile << "Both correct: " << printResultLine(theGlobalStats.getCorrectChords(), theTotalDuration, " s") << endl;
		theOutputFile << "Only root correct: " << printResultLine(theGlobalStats.getOnlyRootCorrect(), theTotalDuration, " s") << endl;
		theOutputFile << "Only type correct: " << printResultLine(theGlobalStats.getOnlyTypeCorrect(), theTotalDuration, " s") << endl;
		theOutputFile << "Both wrong: " << printResultLine(theGlobalStats.getBothRootAndTypeWrong(), theTotalDuration, " s") << endl;
	}
	/*********/
	/* Notes */
	/*********/
	else if (theVarMap.count("notes") > 0)
	{
		PairwiseEvaluation<Note> theNoteEvaluation(theVarMap["notes"].as<string>());
        theLabels.resize(theNoteEvaluation.getNumOfTestLabels());
        std::transform(theNoteEvaluation.getLabels().begin(), theNoteEvaluation.getLabels().end(), theLabels.begin(), std::mem_fun_ref(&MusOO::NoteMidi::str));

		ofstream theCSVFile;
		if (theVarMap.count("csv") > 0)
		{
			theCSVFile.open(path(theOutputPath).replace_extension("csv"));
			theCSVFile << theVarMap["notes"].as<string>() << endl;
			theCSVFile << "File"
				<< theCSVSeparator << "Pairwise score (%)"
				<< theCSVSeparator << "Duration (s)"
				<< theCSVSeparator << "Correct notes (%)"
				<< theCSVSeparator << "Octave error (%)"
				<< theCSVSeparator << "Fifth error (%)"
				<< theCSVSeparator << "Chromatic up error (%)"
				<< theCSVSeparator << "Chromatic down error (%)"
				<< theCSVSeparator << "Correct no-notes (%)"
				<< theCSVSeparator << "Note deletions (%)"
				<< theCSVSeparator << "Note insertions (%)"  << endl;
			theCSVFile << std::fixed;
		}

		for (vector<string>::iterator i = theListItems.begin(); i != theListItems.end(); ++i)
		{
            constructPaths(*i, theRefDirPath, theRefExt, theTestDirPath, theTestExt, theVarMap, theRefPath, theTestPath, theBegin, theEnd);
			cout << "Evaluating file " << *i << endl;

			NoteFileMaps theTestFile(theTestPath.string());
			NoteSequence theTestNotes = theTestFile.readAll();

			NoteFileMaps theRefFile(theRefPath.string());
			NoteSequence theRefNotes = theRefFile.readAll();

            ofstream theVerboseStream;
            if (theVarMap.count("verbose"))
            {
                path theVerbosePath = theOutputPath.parent_path() / path(*i + ".csv");
                theVerboseStream.open(theVerbosePath);
            }
			theNoteEvaluation.addSequencePair(theRefNotes, theTestNotes, theBegin, theEnd, theVerboseStream, theMinRefDuration, theMaxRefDuration, theDelay);

			if (theVarMap.count("csv") > 0)
            {
                NoteEvaluationStats theStats(theNoteEvaluation.getConfusionMatrix());
                double theDuration = theNoteEvaluation.getDuration();
				theCSVFile << theCSVQuotes << *i << theCSVQuotes << theCSVSeparator
					<< 100*theNoteEvaluation.getScore() << theCSVSeparator
					<< theDuration << theCSVSeparator
					<< 100*theStats.getCorrectNotes()/theDuration << theCSVSeparator
					<< 100*theStats.getOctaveErrors()/theDuration << theCSVSeparator
					<< 100*theStats.getFifthErrors()/theDuration << theCSVSeparator
					<< 100*theStats.getChromaticUpErrors()/theDuration << theCSVSeparator
					<< 100*theStats.getChromaticDownErrors()/theDuration
					<< 100*theStats.getCorrectNoNotes()/theDuration << theCSVSeparator
					<< 100*theStats.getNoteDeletions()/theDuration << theCSVSeparator
					<< 100*theStats.getNoteInsertions()/theDuration << theCSVSeparator << endl;
			}
		}
		theCSVFile.close();

        // Global output file
        theTotalDuration = theNoteEvaluation.calcTotalDuration();
		string theNoteMode = theVarMap["notes"].as<string>();
		theOutputFile << string(theNoteMode.size()+10,'*') << "\n* Notes " << theNoteMode << " *\n"
        << string(theNoteMode.size()+10,'*') << endl;
		theOutputFile << "Duration of evaluated notes: " << theTotalDuration << " s" << endl;
		theOutputFile << "Average score: " << 100 * theNoteEvaluation.calcWeightedAverageScore() << "%\n" << endl;

        theGlobalConfusionMatrix = theNoteEvaluation.calcTotalConfusionMatrix();
		NoteEvaluationStats theGlobalStats(theGlobalConfusionMatrix);
		theOutputFile << "Correct notes: " << printResultLine(theGlobalStats.getCorrectNotes(), theTotalDuration, " s") << endl;
		theOutputFile << "Octave errors: " << printResultLine(theGlobalStats.getOctaveErrors(), theTotalDuration, " s") << endl;
		theOutputFile << "Fifth errors: " << printResultLine(theGlobalStats.getFifthErrors(), theTotalDuration, " s") << endl;
		theOutputFile << "Chromatic up errors: " << printResultLine(theGlobalStats.getChromaticUpErrors(), theTotalDuration, " s") << endl;
		theOutputFile << "Chromatic down errors: " << printResultLine(theGlobalStats.getChromaticDownErrors(), theTotalDuration, " s") << endl;
		theOutputFile << "Deleted notes: " << printResultLine(theGlobalStats.getNoteDeletions(), theTotalDuration, " s") << endl;

		theOutputFile << "\nCorrect no-notes: " << printResultLine(theGlobalStats.getCorrectNoNotes(), theTotalDuration, " s") << endl;
		theOutputFile << "Inserted notes: " << printResultLine(theGlobalStats.getNoteInsertions(), theTotalDuration, " s") << endl;
	}
	/****************/
	/* Segmentation */
	/****************/
	else if (theVarMap.count("segmentation") > 0)
	{
        std::vector<double> tol(1, 0.5);
        SegmentationEvaluation theSegmentationEvaluation(theVarMap["segmentation"].as<string>(), tol);

        ofstream theCSVFile;
		if (theVarMap.count("csv") > 0)
		{
			theCSVFile.open(path(theOutputPath).replace_extension("csv"));
			theCSVFile << theVarMap["segmentation"].as<string>() << endl;
            theCSVFile << "File"
            << theCSVSeparator << "Duration (s)"
            << theCSVSeparator << "NumRefSegments"
            << theCSVSeparator << "NumTestSegments"
            << theCSVSeparator << "CombinedHammingMeasureWorst"
            << theCSVSeparator << "CombinedHammingMeasureHarmonic"
            << theCSVSeparator << "UnderSegmentation"
            << theCSVSeparator << "OverSegmentation"
//            << theCSVSeparator << "SegmentationRecall"
//            << theCSVSeparator << "SegmentationPrecision"
            << endl;
			theCSVFile << std::fixed;
		}

		for (vector<string>::iterator i = theListItems.begin(); i != theListItems.end(); ++i)
		{
            constructPaths(*i, theRefDirPath, theRefExt, theTestDirPath, theTestExt, theVarMap, theRefPath, theTestPath, theBegin, theEnd);
			cout << "Evaluating file " << *i << endl;

			LabFile<std::string> theRefFile(theRefPath.string(), true);
            LabFile<std::string> theTestFile(theTestPath.string(), true);
            theSegmentationEvaluation.addSequencePair(theRefFile.readAll(), theTestFile.readAll());

			if (theVarMap.count("csv") > 0)
			{
                theCSVFile << theCSVQuotes << *i << theCSVQuotes
                << theCSVSeparator << theSegmentationEvaluation.getDuration()
                << theCSVSeparator << theSegmentationEvaluation.getNumRefSegments()
                << theCSVSeparator << theSegmentationEvaluation.getNumTestSegments()
                << theCSVSeparator << theSegmentationEvaluation.getCombinedHammingMeasureWorst()
                << theCSVSeparator << theSegmentationEvaluation.getCombinedHammingMeasureHarmonic()
                << theCSVSeparator << theSegmentationEvaluation.getUnderSegmentation()
                << theCSVSeparator << theSegmentationEvaluation.getOverSegmentation()
                << endl;
			}
		}
		theCSVFile.close();

        // Global output file
        string theSegmentationMode = theVarMap["segmentation"].as<string>();
		theOutputFile << string(theSegmentationMode.size()+17,'*') << "\n* Segmentation " << theSegmentationMode << " *\n"
        << string(theSegmentationMode.size()+17,'*') << endl;
        theOutputFile << "Duration of evaluated segments: " << theSegmentationEvaluation.calcTotalDuration() << " s" << endl;
        theOutputFile << "Average number of reference segments: " << theSegmentationEvaluation.calcAverageNumRefSegments() << endl;
        theOutputFile << "Average number of test segments: " << theSegmentationEvaluation.calcAverageNumTestSegments() << endl;
        theOutputFile << "Average ratio of number of segments: " << theSegmentationEvaluation.calcAverageSegmentsRatio() << endl;
        theOutputFile << "Average combined Hamming measure (worst): " << theSegmentationEvaluation.calcAverageCombinedHammingMeasureWorst() << endl;
        theOutputFile << "Average combined Hamming measure (harmonic): " << theSegmentationEvaluation.calcAverageCombinedHammingMeasureHarmonic() << endl;
        theOutputFile << "Average under-segmentation: " << theSegmentationEvaluation.calcAverageUnderSegmentation() << endl;
        theOutputFile << "Average over-segmentation: " << theSegmentationEvaluation.calcAverageOverSegmentation() << endl;
    }

    /********************/
	/* Confusion matrix */
    /********************/
	if (theVarMap.count("confusion") && theVarMap.count("segmentation") == 0)
	{
		ofstream theConfusionMatrixFile(theVarMap["confusion"].as<path>());
		if (!theConfusionMatrixFile.is_open())
		{
			throw runtime_error("Could not open confusion matrix file '" +
				theVarMap["confusion"].as<path>().string() + "'");
		}
		printConfusionMatrix(theConfusionMatrixFile, theGlobalConfusionMatrix, theLabels);
	}

	cout << "Total execution time: " << static_cast<double>(clock())/CLOCKS_PER_SEC << "s" << endl;
	return 0;
}
catch (exception& e)
{
	cerr << "Error: " << e.what() << endl;
	return -1;
} }

max_stars_repo_name: jpauwels/MusOOEvaluator

max_issues_repo_name: jpauwels/MusOOEvaluator

max_forks_repo_name: jpauwels/MusOOEvaluator


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

#include "CommonIncludes.h"
#include "R3DComputeMatchesThread.h"
#include "R3DComputeMatches.h"
#include "Regard3DMainFrame.h"
#include "R3DProject.h"

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/mean.hpp>

R3DComputeMatchesThread::R3DComputeMatchesThread() : wxThread(wxTHREAD_JOINABLE),
	pMainFrame_(NULL), pR3DComputeMatches_(NULL), isOK_(true), svgOutput_(false),
	pComputeMatches_(NULL), pPictureSet_(NULL), cameraModel_(3)
{
}

R3DComputeMatchesThread::~R3DComputeMatchesThread()
{
}

void R3DComputeMatchesThread::setMainFrame(Regard3DMainFrame *pMainFrame)
{
	pMainFrame_ = pMainFrame;
}

void R3DComputeMatchesThread::setParameters(const Regard3DFeatures::R3DFParams &params, bool svgOutput, int cameraModel)
{
	params_ = params;
	svgOutput_ = svgOutput;
	cameraModel_ = cameraModel;
}

void R3DComputeMatchesThread::setComputeMatches(R3DProject::ComputeMatches *pComputeMatches, R3DProject::PictureSet *pPictureSet)
{
	R3DProject *pProject = R3DProject::getInstance();
	pComputeMatches_ = pComputeMatches;
	pPictureSet_ = pPictureSet;
	pProject->getProjectPathsCM(paths_, pComputeMatches);
}

bool R3DComputeMatchesThread::startComputeMatchesThread()
{
	this->Create();
	this->Run();

	return true;
}

void R3DComputeMatchesThread::stopComputeMatchesThread()
{
	wxThread::ExitCode exitCode = this->Wait();
}

wxThread::ExitCode R3DComputeMatchesThread::Entry()
{
	R3DProject *pProject = R3DProject::getInstance();
	wxASSERT(pProject != NULL);

	wxDateTime beginTime = wxDateTime::UNow();

	// This call can be slow, as the matches directory might be deleted.
	// That's why it is done here and not in the main thread
	pProject->prepareComputeMatches(paths_, params_.threshold_, params_.distRatio_);

	if(pR3DComputeMatches_ != NULL)
		delete pR3DComputeMatches_;

	pR3DComputeMatches_ = new R3DComputeMatches();
	pR3DComputeMatches_->setMainFrame(pMainFrame_);

	if(pMainFrame_ != NULL)
		pMainFrame_->sendUpdateProgressBarEvent(0.1f, wxT("Importing images"));

	pProject->importAllImages(paths_);

	if(pMainFrame_ != NULL)
		pMainFrame_->sendUpdateProgressBarEvent(0.2f, wxT("Computing matches"));

	pR3DComputeMatches_->addImages(pPictureSet_->getImageInfoVector());
	isOK_ = pR3DComputeMatches_->computeMatches(params_, svgOutput_, paths_, cameraModel_);
//	pR3DComputeMatches_->computeMatchesOpenCV(R3DComputeMatches::R3DFER3DF);
//	pR3DComputeMatches_->computeMatchesOpenCV_NLOPT();

	wxTimeSpan runTime = wxDateTime::UNow() - beginTime;
	prepareResultStrings(pR3DComputeMatches_->getStatistics(), runTime);

	if(pMainFrame_ != NULL)
		pMainFrame_->sendComputeMatchesFinishedEvent();

	return 0;
}

using namespace boost::accumulators;

void R3DComputeMatchesThread::prepareResultStrings(const R3DComputeMatches::R3DComputeMatchesStatistics &statistics,
	wxTimeSpan runTime)
{
	resultStrings_.Clear();

	const std::vector<int> &numberOfKeypoints = statistics.numberOfKeypoints_;

	if(!numberOfKeypoints.empty())
	{
		accumulator_set<int, stats<tag::median, tag::min, tag::max, tag::mean> > acc;
		for(size_t i = 0; i < numberOfKeypoints.size(); i++)
		{
			acc(numberOfKeypoints[i]);
		}

		resultStrings_.Add(wxT("Keypoints per image (min/max/avg/median)"));
		resultStrings_.Add(wxString::Format(wxT("%d/%d/%d/%d"),
			(min)(acc), (max)(acc),
			static_cast<int>(mean(acc)),
			static_cast<int>(median(acc))));
	}

	pComputeMatches_->numberOfKeypoints_ = numberOfKeypoints;

	wxString runTimeStr;
	if(runTime.GetHours() > 0)
		runTimeStr = runTime.Format(wxT("%H:%M:%S.%l"));
	else
		runTimeStr = runTime.Format(wxT("%M:%S.%l"));
	resultStrings_.Add(wxT("Elapsed time"));
	resultStrings_.Add(runTimeStr);
	pComputeMatches_->runningTime_ = runTimeStr;
}


text:
#include <boost/thread.hpp>
#include <ros/ros.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/image_encodings.h>
#include <cv_bridge/cv_bridge.h>
#include <upperbody_detector/upperbody.h>
#include <upperbody_detector/upperbodyArray.h>

cv::CascadeClassifier classifier;
ros::Publisher upperbodyPublisher;

void image_cb_ (const sensor_msgs::ImageConstPtr& callback_image) {
	std::vector<cv::Rect> results;
	cv::Mat image = cv_bridge::toCvCopy(callback_image, "bgr8")->image;

  struct timespec timer1, timer2;
  clock_gettime(0, &timer1);
	classifier.detectMultiScale(image, results, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE );
  clock_gettime(0, &timer2);
  ROS_ERROR_STREAM(timer2.tv_sec - timer1.tv_sec << " seconds, " << timer2.tv_nsec - timer1.tv_nsec << " nanoseconds.");

	upperbody_detector::upperbodyArray publishedArray;
	for(std::vector<cv::Rect>::iterator it = results.begin(); it != results.end(); ++it) {
		upperbody_detector::upperbody publishedUBody;

		publishedUBody.x = it->x;
		publishedUBody.y = it->y;
		publishedUBody.height = it->height;
		publishedUBody.width = it->width;

		publishedArray.upperbodies.push_back(publishedUBody);
	}

	//cv::imshow("upperbody_detector", image);
	//cv::waitKey(30);

	upperbodyPublisher.publish(publishedArray);
}

int main(int argc, char** argv) {
	// Initialize ROS
  ros::init (argc, argv, "ground_based_detector");
  ros::NodeHandle nodeHandle;
  ros::Subscriber subscriberImage = nodeHandle.subscribe<sensor_msgs::Image>("/camera/rgb/image_raw", 1, image_cb_);
	std::string trained_upper_body_classifier_xml_path;
  nodeHandle.getParam("upperbody_detector/trained_ubc_xml_path", trained_upper_body_classifier_xml_path);
	upperbodyPublisher = nodeHandle.advertise<upperbody_detector::upperbodyArray>("upperbody_detector/upperbodies", 20);

	classifier.load(trained_upper_body_classifier_xml_path);
	//cv::namedWindow("upperbody_detector");

	ros::spin();
}


text:
/* Copyright (c) 2012-2021 Big Ladder Software LLC. All rights reserved.
 * See the LICENSE file for additional terms and conditions. */

#ifndef Simulator_HPP
#define Simulator_HPP

#include <iostream>

#include <boost/date_time/posix_time/posix_time.hpp>

#include "BoundaryConditions.hpp"
#include "Geometry.hpp"
#include "Ground.hpp"
#include "GroundOutput.hpp"
#include "GroundPlot.hpp"
#include "Input.hpp"
#include "WeatherData.hpp"

using namespace Kiva;

class Simulator {
public:
  // Constructor
  Simulator(WeatherData &weatherData, Input &input, std::string outputFileName);

  virtual ~Simulator();
  void simulate();

  WeatherData &weatherData;
  Input &input;

  double annualAverageDryBulbTemperature;

  double percentComplete;

private:
  Ground ground;
  BoundaryConditions bcs;

  std::vector<GroundPlot> plots;
  std::ofstream outputFile;
  filesys::path outputDir;
  void initializePlots();
  void initializeConditions();

  void printStatus(boost::posix_time::ptime t);

  std::string printOutputHeaders();
  std::string printOutputLine();

  void plot(boost::posix_time::ptime t);

  boost::posix_time::ptime prevStatusUpdate;
  boost::posix_time::ptime prevOutputTime;
  bool initPeriod;

  double getInitialTemperature(boost::posix_time::ptime t, double z);

  void updateBoundaryConditions(boost::posix_time::ptime t);
};

#endif // Simulator_HPP

max_stars_repo_name: bigladder/kiva

max_issues_repo_name: bigladder/kiva

max_forks_repo_name: bigladder/kiva


text:
/// \file
/// Maintainer: Felice Serena
///
///

#include "read_png.h"

#include <boost/test/unit_test.hpp>
#include <sstream>

using namespace MouseTrack;

void check_matrix(PictureI expected, PictureI received) {
  BOOST_CHECK(expected.rows() == received.rows());
  BOOST_CHECK(expected.cols() == received.cols());

  for (int i = 0; i < expected.rows(); i += 1) {
    for (int j = 0; j < expected.cols(); j += 1) {
      std::stringstream ss;
      ss << "i: " << i << " j: " << j << " expected: " << expected(i, j)
         << " pic: " << received(i, j) << "\n";
      BOOST_CHECK_MESSAGE(expected(i, j) == received(i, j), ss.str());
    }
  }
}

BOOST_AUTO_TEST_CASE(read_png_grey1x1) {
  // Note: make sure to run ./lib/tests to pass this test (from the build
  // directory which in turn is located in the project root)
  const PictureI pic = read_png("../lib/generic/read_png.test/grey1x1.png");
  PictureI expected(1, 1);
  expected(0, 0) = 128;

  check_matrix(expected, pic);
}

BOOST_AUTO_TEST_CASE(read_png_grey2x2) {
  // Note: make sure to run ./lib/tests to pass this test (from the build
  // directory which in turn is located in the project root)
  const PictureI pic = read_png("../lib/generic/read_png.test/grey2x2.png");
  PictureI expected(2, 2);
  expected(0, 0) = 26;
  expected(1, 0) = 77;
  expected(0, 1) = 51;
  expected(1, 1) = 102;

  check_matrix(expected, pic);
}

BOOST_AUTO_TEST_CASE(read_png_grey2x3) {
  // Note: make sure to run ./lib/tests to pass this test (from the build
  // directory which in turn is located in the project root)
  const PictureI pic = read_png("../lib/generic/read_png.test/grey2x3.png");
  PictureI expected(2, 3);
  expected(0, 0) = 26;
  expected(1, 0) = 102;
  expected(0, 1) = 51;
  expected(1, 1) = 128;
  expected(0, 2) = 77;
  expected(1, 2) = 153;

  check_matrix(expected, pic);
}

ext: cc

max_stars_repo_name: itko/scanbox

max_issues_repo_name: itko/scanbox

max_forks_repo_name: itko/scanbox


text: #include <boost/spirit/home/karma/string.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <Core/Core.h>
#include <Eigen/Eigen.h>
#include "Sundials.h"
#include "Mooring.h"

namespace Upp {

MooringStatus Catenary(double rho_m, double rho_m3, double rho_water, double moorlen, double BL,
			  double xanchorvessel, double zanchor, double zvessel,
			  double &Fhanchorvessel, double &Fvanchor, double &Fvvessel,
			  double &xonfloor, Vector<double> &x, Vector<double> &z, int num) {
	if (zanchor < 0 && zvessel < 0)
		throw Exc("Catenary. Anchor and vessel z positions have to be positive");
	if (xanchorvessel < 0)
		throw Exc("Catenary. x distance between anchor and vessel has to be positive");

	const double g = 9.81;

	double lmb = rho_m*(rho_m3 - rho_water)/rho_m3;

  	Buffer<double> udata(1, 1);
	SolveNonLinearEquationsSun(udata, 1, [&](const double y[], double residuals[])->bool {
		double Blimit = y[0];
		residuals[0] =  sqrt(zanchor*(zanchor + 2*Blimit)) + sqrt(zvessel*(zvessel + 2*Blimit)) - moorlen;
		return true;
	});
	double Blimit = udata[0];

    double xanchorvessel_limit = Blimit*(acosh(zanchor/Blimit + 1) + acosh(zvessel/Blimit + 1));

	double delta = xanchorvessel/(num - 1);
	x.SetCount(num);
	z.SetCount(num);

	MooringStatus status;

	if (xanchorvessel < moorlen - zanchor - zvessel) {
		status = LOOSE_ON_FLOOR;

		if (!IsNull(rho_m)) {
	        Fhanchorvessel = 0;
	        Fvanchor = lmb*g*zanchor;
	        Fvvessel = lmb*g*zvessel;
		} else
			Fhanchorvessel = Fvanchor = Fvvessel = Null;

     	xonfloor = xanchorvessel;

		x.SetCount(4);
		z.SetCount(4);
		x[0] = 0;				z[0] = zanchor;
		x[1] = 0;				z[1] = 0;
		x[2] = xanchorvessel;	z[2] = 0;
		x[3] = xanchorvessel;	z[3] = zvessel;
	} else if (xanchorvessel < xanchorvessel_limit) {
        status = CATENARY_ON_FLOOR;

	  	Buffer<int> consdata(1, 2);		// B > 0

	  	Buffer<double> udata(1, Blimit/2.);
		SolveNonLinearEquationsSun(udata, 1, [&](const double y[], double residuals[])->bool {
			double B = y[0];
			residuals[0] = xanchorvessel - B*acosh(zanchor/B + 1) - B*acosh(zvessel/B + 1) + sqrt(zanchor*(zanchor + 2*B)) + sqrt(zvessel*(zvessel + 2*B)) - moorlen;
			return true;
		}, consdata);
		double B = udata[0];

        double xcatanchor = B*acosh(zanchor/B + 1);
        double xcatvessel = B*acosh(zvessel/B + 1);
		xonfloor = xanchorvessel - xcatanchor - xcatvessel;

		if (!IsNull(rho_m)) {
	        Fhanchorvessel = lmb*g*B;
	        Fvanchor = Fhanchorvessel*sinh(xcatanchor/B);
	        Fvvessel = Fhanchorvessel*sinh(xcatvessel/B);
		} else
			Fhanchorvessel = Fvanchor = Fvvessel = Null;

        for (int i = 0; i < x.size(); ++i) {
            x[i] = i*delta;
            if (x[i] < xcatanchor)
        		z[i] = B*(cosh((xcatanchor - x[i])/B) - 1);
            else if (x[i] > (xanchorvessel - xcatvessel))
                z[i] = B*(cosh((max(0., x[i] - (xanchorvessel - xcatvessel)))/B) - 1);
            else
                z[i] = 0;
        }
    } else if (xanchorvessel < sqrt(sqr(moorlen) - sqr(zvessel - zanchor))) {
        status = CATENARY;

		int neq = 2;
        double deltaz = zvessel - zanchor;

	  	Buffer<double> udata(neq);
	  	Buffer<int> consdata(2);
	  	consdata[0] = 2;			// B > 0
	  	consdata[1] = 0;

	  	double x1_0, B_0, x1, B;
	  	bool done = false;
	  	for (x1_0 = 0; x1_0 < abs(xanchorvessel) && !done; x1_0 += abs(xanchorvessel)/4) {
	  		for (B_0 = abs(Blimit); B_0 < 10*B_0 && !done; B_0 += 5*abs(Blimit)/4) {
		  		udata[0] = B_0;
		  		udata[1] = x1_0;
				SolveNonLinearEquationsSun(udata, neq, [&](const double y[], double residuals[])->bool {
					double B = y[0];
					double x1 = y[1];

					residuals[0] = B*(sinh((x1 + xanchorvessel)/B) - sinh(x1/B)) - moorlen;
					residuals[1] = B*(cosh((x1 + xanchorvessel)/B) - cosh(x1/B)) - deltaz;

					return true;
				}, consdata);
				B = udata[0];
				x1 = udata[1];
				if (abs((x1 + xanchorvessel)/B) < 3)
					done = true;
	  		}
	  	}
	  	if (!done)
			throw Exc("Catenary. Solving problem");

		if (!IsNull(rho_m)) {
	        Fhanchorvessel = lmb*g*abs(B);
	        Fvanchor = -Fhanchorvessel*sinh(x1/B);
	        Fvvessel = Fhanchorvessel*sinh((x1 + xanchorvessel)/B);
		} else
			Fhanchorvessel = Fvanchor = Fvvessel = Null;

        xonfloor = 0;

        for (int i = 0; i < x.size(); ++i) {
            x[i] = i*delta;
        	z[i] = B*(cosh((x[i] + x1)/B) - 1) - B*(cosh(x1/B) - 1) + zanchor;
        }
    } else {
		status = BROKEN;
		if (!IsNull(rho_m))
			Fhanchorvessel = Fvanchor = Fvvessel = xonfloor = 0;
		else
			Fhanchorvessel = Fvanchor = Fvvessel = xonfloor = Null;

		x.Clear();
		z.Clear();
    }

	if (!IsNull(BL))
    	if (max(sqrt(sqr(Fhanchorvessel) + sqr(Fvanchor)), sqrt(sqr(Fhanchorvessel) + sqr(Fvvessel))) >= BL)
        	status = BL_EXCEDEED;

	return status;
}

MooringStatus Catenary(double rho_m, double rho_m3, double rho_water, double moorlen, double BL,
			  double xanchorvessel, double zanchor, double zvessel,
			  double &Fhanchorvessel, double &Fvanchor, double &Fvvessel, double &xonfloor) {
	Vector<double> x, z;

	return Catenary(rho_m, rho_m3, rho_water, moorlen, BL, xanchorvessel,
			zanchor, zvessel, Fhanchorvessel, Fvanchor, Fvvessel, xonfloor, x, z, 0);
}

MooringStatus Catenary(double moorlen, double xanchorvessel, double zanchor, double zvessel, double &xonfloor,
				Vector<double> &x, Vector<double> &z, int num) {
	double rho_m = Null,  rho_m3 = Null, rho_water = Null, BL = Null, Fhanchorvessel, Fvanchor, Fvvessel;

	return Catenary(rho_m, rho_m3, rho_water, moorlen, BL, xanchorvessel,
			zanchor, zvessel, Fhanchorvessel, Fvanchor, Fvvessel, xonfloor, x, z, num);
}

MooringStatus Catenary(double moorlen, double xanchorvessel, double zanchor, double zvessel, double &xonfloor) {
	double rho_m = Null,  rho_m3 = Null, rho_water = Null, BL = Null, Fhanchorvessel, Fvanchor, Fvvessel;
	Vector<double> x, z;
	return Catenary(rho_m, rho_m3, rho_water, moorlen, BL, xanchorvessel,
			zanchor, zvessel, Fhanchorvessel, Fvanchor, Fvvessel, xonfloor, x, z, 0);
}

bool CatenaryGetLen0(double xonfloor, double xanchorvessel, double zanchor, double zvessel,
					double &moorlen) {
	if (xonfloor >= xanchorvessel) {
		moorlen = xanchorvessel + 2*(xonfloor - xanchorvessel) + zanchor + zvessel;
		return false;
	}

	Buffer<int> consdata(2, 2);		// B > 0 && moorlen > 0
  	Buffer<double> udata(2);
  	udata[0] = 1;
  	udata[1] = sqrt(sqr(xanchorvessel) + sqr(zanchor - zvessel));
	SolveNonLinearEquationsSun(udata, 2, [&](const double y[], double residuals[])->bool {
		double B = y[0];
		double moorlen = y[1];
		residuals[0] = xanchorvessel - B*acosh(zanchor/B + 1) - B*acosh(zvessel/B + 1) + sqrt(zanchor*(zanchor + 2*B)) + sqrt(zvessel*(zvessel + 2*B)) - moorlen;
    	double xcatanchor = B*acosh(zanchor/B + 1);
    	double xcatvessel = B*acosh(zvessel/B + 1);
		residuals[1] = xanchorvessel - xcatanchor - xcatvessel - xonfloor;
		return true;
	}, consdata);
	//double B = udata[0];
	moorlen = udata[1];

	return true;
					}

MooringStatus CatenaryGetLen(double xonfloor, double xanchorvessel, double zanchor, double zvessel,
			double &moorlen) {
	if (!CatenaryGetLen0(xonfloor, xanchorvessel, zanchor, zvessel, moorlen))
		return LOOSE_ON_FLOOR;

	return Catenary(moorlen, xanchorvessel, zanchor, zvessel, xonfloor);
}

MooringStatus CatenaryGetLen(double rho_m, double rho_m3, double rho_water, double xonfloor,
			double BL, double xanchorvessel, double zanchor, double zvessel,
			double &Fhanchorvessel, double &Fvanchor, double &Fvvessel, double &moorlen) {
	if (!CatenaryGetLen0(xonfloor, xanchorvessel, zanchor, zvessel, moorlen))
		return LOOSE_ON_FLOOR;

	return Catenary(rho_m, rho_m3, rho_water, moorlen, BL, xanchorvessel, zanchor, zvessel,
					Fhanchorvessel, Fvanchor, Fvvessel, xonfloor);
}

const char *MooringStatusStr(MooringStatus status) {
	const char *str[5] = {"loose on floor", "catenary on floor", "catenary",
						 "line length exceeded", "break load exdeeded"};
	ASSERT(int(status) < 5);
	return str[int(status)];
}

bool IsOK(MooringStatus status) {
	return status < BROKEN;
}

}

max_stars_repo_name: XOULID/Anboto

max_issues_repo_name: XOULID/Anboto

max_forks_repo_name: XOULID/Anboto


text:
#include <sjc.h>
#include <boost/process.hpp>

namespace fs = boost::filesystem;
namespace bp = boost::process;

bool copyDir(fs::path const & source, fs::path const & destination) {
    try {
        // Check whether the function call is valid
        if(
            !fs::exists(source) ||
            !fs::is_directory(source)
        ) {
            std::cerr << "Source directory " << source.string()
                << " does not exist or is not a directory." << '\n';
            return false;
        }

        if(fs::exists(destination)) {
            std::cerr << "Destination directory " << destination.string()
                << " already exists." << '\n';
            return false;
        }
        // Create the destination directory
        if(!fs::create_directory(destination)) {
            std::cerr << "Unable to create destination directory"
                << destination.string() << '\n';
            return false;
        }
    } catch(fs::filesystem_error const & e) {
        std::cerr << e.what() << '\n';
        return false;
    }

    // Iterate through the source directory
    for(
        fs::directory_iterator file(source);
        file != fs::directory_iterator(); ++file
    ) {
        try {
            fs::path current(file->path());
            if(fs::is_directory(current)) {
                // Found directory: Recursion
                if(!copyDir(
                        current,
                        destination / current.filename()
                    )) {
                    return false;
                }
            } else {
                // Found file: Copy
                fs::copy_file(
                    current,
                    destination / current.filename()
                );
            }
        }
        catch(fs::filesystem_error const & e) {
            std:: cerr << e.what() << '\n';
        }
    }
    return true;
}

void NLibrary::initFunctionsImpl(Compiler* compiler, vector<pair<string, vector<string>>>& importNamespaces, vector<string>& packageNamespace, shared_ptr<CBaseFunctionDefinition> thisFunction) {
    if (thisFunction->name != "global") {
        compiler->addError(loc, CErrorCode::IncludeOnlyInGlobal, "can only use library in the global scope");
    }

    auto index = fileName.find(":");
    auto branchName = fileName.substr(0, index);
    auto repoName = fileName.substr(index + 1, fileName.size() - index - 1);
    auto index2 = repoName.find_last_of("/");
    if (!boost::ends_with(repoName, ".git")) {
        compiler->addError(loc, CErrorCode::InvalidType, "url in library must be for git");
        return;
    }
    auto libName = repoName.substr(index2, repoName.size() - index2 - 4);
    auto libRootPath = compiler->rootPath / fs::path("lib");
    auto libPath = libRootPath / fs::path(libName);
    auto mainPath = libPath / fs::path("main.sj");

    if (!fs::is_directory(libPath)) {
        // If it does not exist then enlist
        stringstream command;
        command << "git submodule add -b " << branchName << " " << repoName;
        printf("In \"%s\" running: %s\n", libRootPath.string().c_str(), command.str().c_str());

        fs::create_directory(libRootPath);
        bp::system(command.str(), bp::std_out > stdout, bp::std_err > stderr, bp::std_in < stdin, bp::start_dir = libRootPath);
    }
    else if (compiler->libraryPull) {
        // If it does exist then make sure we are using the correct branch
        stringstream command;
        command << "git checkout " << branchName;
        printf("In \"%s\" running: %s\n", libPath.string().c_str(), command.str().c_str());
        bp::system(command.str(), bp::std_out > stdout, bp::std_err > stderr, bp::std_in < stdin, bp::start_dir = libPath);

        printf("In \"%s\" running: git pull\n", libPath.string().c_str());
        bp::system("git pull", bp::std_out > stdout, bp::std_err > stderr, bp::std_in < stdin, bp::start_dir = libPath);
    }

    // Include the main.sj file
    compiler->includeFile(mainPath.string());

    // Copy assets
    if (compiler->libraryCopy) {
        if (fs::is_directory(libPath / "assets")) {
            fs::create_directory(compiler->rootPath / "assets");
            copyDir(libPath / "assets", compiler->rootPath / "assets" / libName);

            ofstream streamGitIgnore;
            streamGitIgnore.open((compiler->rootPath / "assets" / libName / ".gitignore").string());
            streamGitIgnore << "*";
        }
    }
}

void NLibrary::initVarsImpl(Compiler* compiler, shared_ptr<CScope> scope, CTypeMode returnMode) {
}

shared_ptr<CVar> NLibrary::getVarImpl(Compiler* compiler, shared_ptr<CScope> scope, shared_ptr<CType> returnType, CTypeMode returnMode) {
    return nullptr;
}

max_stars_repo_name: justinmann/sj

max_issues_repo_name: justinmann/sj

max_forks_repo_name: justinmann/sj


text:
/*!
 *\file
*/
// Config Class
// Author: Charles Gruenwald III
#include "section.hpp"
#include <boost/algorithm/string.hpp>
#include <iostream>

namespace config
{

    //! Section() Constructor for a root section
    Section::Section(const std::string & name, bool case_sensitive)
        :
            m_name(name),
            m_subSections(),
            m_keys(),
            m_parent(*this),
            m_isroot(true),
            m_case_sensitive(case_sensitive)
    {
    }

    //! Section() Constructor for a subsection
    Section::Section(Section const & parent, const std::string & name, bool case_sensitive)
        :
            m_name(name),
            m_subSections(),
            m_keys(),
            m_parent(parent),
            m_isroot(false),
            m_case_sensitive(case_sensitive)
    {
    }

    //! ~Section() Destructor
    Section::~Section()
    {
        m_subSections.clear();
        m_keys.clear();
    }

    //create a new section and add it to the subsection map
    Section & Section::addSubsection(const std::string & name_)
    {
        std::string iname(name_);
        if(!m_case_sensitive)
            boost::to_lower(iname);

        m_subSections.insert(std::make_pair(iname, new Section(*this, name_, m_case_sensitive)));
        return *(m_subSections[iname].get());
    }

    //add a new key/value pair to this section
    const Key & Section::addKey(const std::string & name_, const std::string & value)
    {
        //Make the key all lower-case if not case sensitive
        std::string iname(name_);
        if(!m_case_sensitive)
            boost::to_lower(iname);

        //Remove existing key if found
        KeyList::const_iterator found = m_keys.find(iname);
        if(found != m_keys.end())
            m_keys.erase(iname);

        m_keys.insert(std::make_pair(iname, new Key(this->getFullPath(),name_,value)));
        return *(m_keys[iname].get());
    }

    const Key & Section::addKey(const std::string & name_, const int value)
    {
        //Make the key all lower-case if not case sensitive
        std::string iname(name_);
        if(!m_case_sensitive)
            boost::to_lower(iname);

        //Remove existing key if found
        KeyList::const_iterator found = m_keys.find(iname);
        if(found != m_keys.end())
            m_keys.erase(iname);

        m_keys.insert(std::make_pair(iname, new Key(this->getFullPath(),name_,value)));
        return *(m_keys[iname].get());
    }

    const Key & Section::addKey(const std::string & name_, const double value)
    {
        //Make the key all lower-case if not case sensitive
        std::string iname(name_);
        if(!m_case_sensitive)
            boost::to_lower(iname);

        //Remove existing key if found
        KeyList::const_iterator found = m_keys.find(iname);
        if(found != m_keys.end())
            m_keys.erase(iname);

        m_keys.insert(std::make_pair(iname, new Key(this->getFullPath(),name_,value)));
        return *(m_keys[iname].get());
    }

    //get a subkey of the given name
    const Key & Section::getKey(const std::string & name_)
    {
        std::string iname(name_);
        if(!m_case_sensitive)
            boost::to_lower(iname);
        return *(m_keys[iname].get());
    }

    //get a subsection of the given name
    const Section & Section::getSection(const std::string & name)
    {
        return getSection_unsafe(name);
    }

    //Unsafe version of the getSection function, this should only be used internally
    Section & Section::getSection_unsafe(const std::string & name)
    {
        std::string iname(name);
        if(!m_case_sensitive)
            boost::to_lower(iname);
        return *(m_subSections[iname].get());
    }

    bool Section::hasSection(const std::string & name) const
    {
        std::string iname(name);
        if(!m_case_sensitive)
            boost::to_lower(iname);
        SectionList::const_iterator found = m_subSections.find(iname);
        return (found != m_subSections.end());
    }

    bool Section::hasKey(const std::string & name) const
    {
        std::string iname(name);
        if(!m_case_sensitive)
            boost::to_lower(iname);
        KeyList::const_iterator found = m_keys.find(iname);
        return (found != m_keys.end());
    }

    const std::string Section::getFullPath() const
    {
        std::string path = "";
        if(isRoot())
            return path;

        if(getParent().isRoot())
            return getName();

        //create the path from the parent section and this section's name
        path = std::string(getParent().getFullPath()) + "/" + getName();
        return path;
    }

}//end of namespace config

max_stars_repo_name: NoCModellingLab/Graphite

max_issues_repo_name: NoCModellingLab/Graphite

max_forks_repo_name: NoCModellingLab/Graphite


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.

// Contributed and/or modified by Tinko Bartels,
//   as part of Google Summer of Code 2020 program.

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

#ifndef BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_STATIC_UTIL_HPP
#define BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_STATIC_UTIL_HPP

#include <boost/mp11/integral.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/map.hpp>

namespace boost { namespace geometry
{

namespace detail { namespace generic_robust_predicates
{

template
<
    typename LOV,
    typename Void = boost::mp11::mp_same<LOV, void>
>
struct empty_or_void
{
    using type = boost::mp11::mp_empty<LOV>;
};

template <typename LOV>
struct empty_or_void<LOV, boost::mp11::mp_true>
{
    using type = boost::mp11::mp_true;
};

template <typename N>
struct log_2_floor_impl
{
    using type = typename boost::mp11::mp_plus
        <
            typename log_2_floor_impl<boost::mp11::mp_int<N::value / 2>>::type,
            boost::mp11::mp_int<1>
        >;
};

template <>
struct log_2_floor_impl<boost::mp11::mp_int<1>>
{
    using type = boost::mp11::mp_int<0>;
};

template <typename N> using log_2_floor = typename log_2_floor_impl<N>::type;

template <typename N>
struct log_2_ceil_impl
{
private:
    using floor = log_2_floor<N>;
public:
    using type = boost::mp11::mp_int
        <
            (1 << floor::value) == N::value ? floor::value : floor::value + 1
        >;
};

template <typename N> using log_2_ceil = typename log_2_ceil_impl<N>::type;

template <typename S> using is_not_zero = boost::mp11::mp_bool<S::value != 0>;

template
<
    typename M,
    typename K,
    typename Contained = boost::mp11::mp_map_contains<M, K>
>
struct mp_map_at_second_or_void
{
    using type = void;
};

template<typename M, typename K>
struct mp_map_at_second_or_void<M, K, boost::mp11::mp_true>
{
    using type = boost::mp11::mp_second<boost::mp11::mp_map_find<M, K>>;
};

template <typename T> using inc = boost::mp11::mp_int<T::value + 1>;

template <typename L> using indexed = boost::mp11::mp_transform
    <
        boost::mp11::mp_list,
        boost::mp11::mp_iota<boost::mp11::mp_size<L>>,
        L
    >;

template <typename L> using strip_index =
    boost::mp11::mp_transform<boost::mp11::mp_second, L>;

template
<
    typename Map,
    typename Key,
    typename Contains = boost::mp11::mp_map_contains<Map, Key>
>
struct val_or_empty_list
{
    using type = boost::mp11::mp_second<boost::mp11::mp_map_find<Map, Key>>;
};

template
<
    typename Map,
    typename Key
>
struct val_or_empty_list<Map, Key, boost::mp11::mp_false>
{
    using type = boost::mp11::mp_list<>;
};

}} // namespace detail::generic_robust_predicates

}} // namespace boost::geometry

#endif // BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_STATIC_UTIL_HPP


#ifndef __XFTP__MESSAGE_H__
#define __XFTP__MESSAGE_H__
#include <xercesc/dom/DOM.hpp>
#include "libstreamcon/commons.h++"
#include "libstreamcon/threads.h++"
#include <queue>
#include <xercesc/util/XMLUniDefs.hpp>
#include "xercesstrings.h++"
#include <boost/mpl/for_each.hpp>
#include "callbackfunction.h++"
#include "boost/type_traits/is_pointer.hpp"
#include "boost/type_traits/remove_pointer.hpp"
#include "boost/type_traits/add_reference.hpp"
#include "servercontrol.h++"
#include "clientcontrol.h++"
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
namespace xftp {

	class ControlThread;
	class ServerMessage;
	class ClientMessage;

	class ServerControl;
	class ClientControl;

	/*!
	  Class representing a deserialized XML message.
	*/
	class Message
	{
		friend class XMLStream;
	public:
		typedef
		boost::function<void (ControlThread*, Message&) > ProcessImplBaseType;
		typedef
		CallbackFunctionBase<ProcessImplBaseType> ProcessImplType;

		Message(size_t _ID, ProcessImplType *_PI);
		//Message(size_t _ID, _PI);
		/*!
		  Returns XML tag name of specific message (this will be used
		  as DOMelement name while serializing message.
		 */
		virtual XMLCh * GetName() = 0;

		/*!
		  Returns message ID used while while serializing message. this
		  is unique identifier of message, and will be used by server while
		  referencing this message.
		 */
		size_t GetID();

		/*!
		  Process the message and modify ControlThread
		  accordingly.
		 */
		void Process(ControlThread&);

		/*!
		  Each message is serialized to DOM tree, which
		  is processed by XMLStream::PostMessage
		 */
		typedef xercesc::DOMElement *DOMSerializedMessage;

		/*!
		  Transform Message into DOM tree form, which will later be transformed
		  into textual XML form.
		 */
		virtual	DOMSerializedMessage Serialize(
				xercesc::DOMDocument & document) = 0;
		virtual ~Message();
	private:
		//! function adaptor, that casts arguments
		template <class T>
		class CustomProcessImplT
		{
			T f;
		public:
			CustomProcessImplT(T f_): f(f_) {}
			void operator()(ControlThread* c, Message& m)
				{
					f(reinterpret_cast<typename T::first_argument_type >(c),
					  reinterpret_cast<typename T::second_argument_type >(m));
				}
		};

		//! set function directly
		template <typename T>
		ProcessImplBaseType SetProcessImplReal(T i,
											   boost::mpl::bool_<true>
											   ThisVersionForGenericImpl)
			{
				return ProcessImpl->SetFunction(i);

			}

		//! set function through CustomProcessImplT
		template <typename T>
		ProcessImplBaseType SetProcessImplReal(T i,
											   boost::mpl::bool_<false>
											   ThisVersionForCustomImpl)
			{
				return ProcessImpl->SetFunction(
					SetProcessImpl(
 						ProcessImplBaseType(
 							CustomProcessImplT<T>(i)
 							)
						)
					);

			}

	public:

		//! replace implementation of Process function
		template <typename T>
		ProcessImplBaseType SetProcessImpl(T i)
			{

				typename
				boost::mpl::if_<
				boost::is_same<T,ProcessImplBaseType>,
				boost::mpl::bool_<true>,
				boost::mpl::bool_<false>
					>::type Version;
				return SetProcessImplReal(i,Version);
			}

		ProcessImplBaseType GetProcessImpl();

	protected:

		DOMSerializedMessage InitializeSerialization(
				xercesc::DOMDocument & document);

		std::auto_ptr<ProcessImplType > ProcessImpl;

		//! Casts ControlThread to ClientControl
		template<typename TAG>
		class DefaultServerMessageProcessRoutine
		{
		public:
			void operator()(ControlThread* c, Message& m)
			{
			reinterpret_cast<typename boost::add_reference<typename
					boost::remove_pointer<TAG>::type>::type>(m)
				.DefaultProcessImpl(dynamic_cast<ClientControl&>(*c));
			}
		};

		//! Casts ControlThread to ServerControl
		template<typename TAG>
		class DefaultClientMessageProcessRoutine
		{
		public:
			void operator()(ControlThread* c, Message& m)
			{
				// no dynamic cast needed as one true type is enforced.
			reinterpret_cast<typename boost::add_reference<typename
					boost::remove_pointer<TAG>::type>::type>(m)
				.DefaultProcessImpl(dynamic_cast<ServerControl&>(*c));
			}
		};

		//! TAG is typename of pointer to specific message
		template<typename TAG>
		class DefaultProcessRoutine: public boost::mpl::if_<
						 boost::is_base_of<ClientMessage,
						typename boost::remove_pointer<TAG>::type >
						   , DefaultClientMessageProcessRoutine<TAG>
						    , DefaultServerMessageProcessRoutine<TAG>
															>::type
		{
			BOOST_STATIC_ASSERT( (boost::is_base_of<Message,
			typename boost::remove_pointer<TAG>::type>::value) );
		};

		static streamcon::Mutex GlobalSetupLock;

		//! Get single message processing routine
		//! \param elem is pointer to specific message type. It does not have to be
		//!  initialized or even valid as only typename matters here.
		template<typename TAG>
		Message::ProcessImplType * ProcessImplDefault(TAG elem)
		{
			//! assure apropriate type.
			BOOST_STATIC_ASSERT( (boost::is_base_of<Message,
			typename boost::remove_pointer<TAG>::type>::value) );
			ProcessImplType * result =
			new  CallbackFunction<Message::ProcessImplBaseType,TAG>;
			if (result->GetFunction().empty())
			{
				// setup only if not yet initialized
				streamcon::ScopedLock L(GlobalSetupLock);
				result->SetFunction(DefaultProcessRoutine<TAG>());
			}
			return result;
		}

	private:

		size_t ID; // message ID
	};

	class ClientControl;
	/*!
	  Class representing a deserialized server specific
	  XML message.
	 */
	class ServerMessage : public Message
	{
	public:
		ServerMessage(size_t ID, ProcessImplType *_PI);
		//virtual void Process(ControlThread& control);
		//virtual void DefaultProcessImpl(ClientControl& control) = 0;
	};

	class ServerControl;
	/*!
	  Class representing a deserialized client specific
	  XML message.
	 */
	class ClientMessage : public Message
	{
	public:
		ClientMessage(size_t ID, ProcessImplType *_PI);
		//virtual void Process(ControlThread& control);
		//virtual void DefaultProcessImpl(ServerControl& control) = 0;
	};
}

#endif