text:
/**
 * @file   boost_python_headers.hpp
 * @author Paul Furgale <paul.furgale@gmail.com>
 * @date   Mon Dec 12 10:36:03 2011
 *
 * @brief  A header that specializes boost-python to work with fixed-sized Eigen types.
 *
 * The original version of this library did not include these specializations and this caused
 * assert failures when running on Ubuntu 10.04 32-bit. More information about fixed-size
 * vectorizable types in Eigen is available here:
 * http://eigen.tuxfamily.org/dox-devel/TopicFixedSizeVectorizable.html
 *
 * This code has been tested on Ubunutu 10.04 64 and 32 bit, OSX Snow Leopard and OSX Lion.
 *
 * This code is derived from boost/python/converter/arg_from_python.hpp
 * Copyright David Abrahams 2002.
 * Distributed under the Boost Software License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt)
 *
 */
#ifndef NUMPY_EIGEN_CONVERTERS_HPP
#define NUMPY_EIGEN_CONVERTERS_HPP

#include <Eigen/Core>
#include <boost/python.hpp>
#include <boost/python/converter/arg_from_python.hpp>
#include <boost/python/converter/rvalue_from_python_data.hpp>
#include <boost/python/detail/referent_storage.hpp>
#include <boost/python/tuple.hpp>

namespace boost {
namespace python {
namespace detail {
template <typename T>
struct referent_size;

// This bit of code makes sure we have 16 extra bytes to do the pointer alignment for fixed-sized Eigen types
template <typename T, int A, int B, int C, int D, int E>
struct referent_size<Eigen::Matrix<T, A, B, C, D, E>&> {
    // Add 16 bytes so we can get alignment
    BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(Eigen::Matrix<T, A, B, C, D, E>) + 16);
};

// This bit of code makes sure we have 16 extra bytes to do the pointer alignment for fixed-sized Eigen types
template <typename T, int A, int B, int C, int D, int E>
struct referent_size<Eigen::Matrix<T, A, B, C, D, E> const&> {
    // Add 16 bytes so we can get alignment
    BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(Eigen::Matrix<T, A, B, C, D, E>) + 16);
};

// This bit of code makes sure we have 16 extra bytes to do the pointer alignment for fixed-sized Eigen types
template <typename T, int A, int B, int C, int D, int E>
struct referent_size<Eigen::Matrix<T, A, B, C, D, E> > {
    // Add 16 bytes so we can get alignment
    BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(Eigen::Matrix<T, A, B, C, D, E>) + 16);
};

}  // namespace detail
}  // namespace python
}  // namespace boost

namespace boost {
namespace python {
namespace converter {

template <typename S, int A, int B, int C, int D, int E>
struct rvalue_from_python_data<Eigen::Matrix<S, A, B, C, D, E> const&>
    : rvalue_from_python_storage<Eigen::Matrix<S, A, B, C, D, E> const&> {
    typedef typename Eigen::Matrix<S, A, B, C, D, E> T;
#if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \
    (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) &&                                                     \
    !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */
    // This must always be a POD struct with m_data its first member.
    BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>, stage1) == 0);
#endif

    // The usual constructor
    rvalue_from_python_data(rvalue_from_python_stage1_data const& _stage1) { this->stage1 = _stage1; }

    // This constructor just sets m_convertible -- used by
    // implicitly_convertible<> to perform the final step of the
    // conversion, where the construct() function is already known.
    rvalue_from_python_data(void* convertible) { this->stage1.convertible = convertible; }

    // Destroys any object constructed in the storage.
    ~rvalue_from_python_data() {
        // Realign the pointer and destroy
        if (this->stage1.convertible == this->storage.bytes) {
            void* storage = reinterpret_cast<void*>(this->storage.bytes);
            T* aligned =
                reinterpret_cast<T*>(reinterpret_cast<void*>((reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16));

            // std::cout << "Destroying " << (void*)aligned << std::endl;
            aligned->T::~T();
        }
    }

  private:
    typedef typename add_reference<typename add_cv<T>::type>::type ref_type;
};

// Used when T is a plain value (non-pointer, non-reference) type or
// a (non-volatile) const reference to a plain value type.
template <typename S, int A, int B, int C, int D, int E>
struct arg_rvalue_from_python<Eigen::Matrix<S, A, B, C, D, E> > {
    typedef Eigen::Matrix<S, A, B, C, D, E> const& T;
    typedef typename boost::add_reference<T
                                          // We can't add_const here, or it would be impossible to pass
                                          // auto_ptr<U> args from Python to C++
                                          >::type result_type;

    arg_rvalue_from_python(PyObject* obj)
        : m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters)), m_source(obj) {}
    bool convertible() const { return m_data.stage1.convertible != 0; }

#if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
    typename arg_rvalue_from_python<T>::
#endif
        result_type
        operator()() {
        if (m_data.stage1.construct != 0) m_data.stage1.construct(m_source, &m_data.stage1);

        // Here is the magic...
        // Realign the pointer
        void* storage = reinterpret_cast<void*>(m_data.storage.bytes);
        void* aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);

        return python::detail::void_ptr_to_reference(aligned, (result_type(*)())0);
    }

  private:
    rvalue_from_python_data<result_type> m_data;
    PyObject* m_source;
};

// Used when T is a plain value (non-pointer, non-reference) type or
// a (non-volatile) const reference to a plain value type.
template <typename S, int A, int B, int C, int D, int E>
struct arg_rvalue_from_python<Eigen::Matrix<S, A, B, C, D, E> const&> {
    typedef Eigen::Matrix<S, A, B, C, D, E> const& T;
    typedef typename boost::add_reference<T
                                          // We can't add_const here, or it would be impossible to pass
                                          // auto_ptr<U> args from Python to C++
                                          >::type result_type;

    arg_rvalue_from_python(PyObject* obj)
        : m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters)), m_source(obj) {}
    bool convertible() const { return m_data.stage1.convertible != 0; }

#if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
    typename arg_rvalue_from_python<T>::
#endif
        result_type
        operator()() {
        if (m_data.stage1.construct != 0) m_data.stage1.construct(m_source, &m_data.stage1);

        // Here is the magic...
        // Realign the pointer
        void* storage = reinterpret_cast<void*>(m_data.storage.bytes);
        void* aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);

        return python::detail::void_ptr_to_reference(aligned, (result_type(*)())0);
    }

  private:
    rvalue_from_python_data<result_type> m_data;
    PyObject* m_source;
};

// Used when T is a plain value (non-pointer, non-reference) type or
// a (non-volatile) const reference to a plain value type.
template <typename S, int A, int B, int C, int D, int E>
struct arg_rvalue_from_python<Eigen::Matrix<S, A, B, C, D, E> const> {
    typedef Eigen::Matrix<S, A, B, C, D, E> const& T;
    typedef typename boost::add_reference<T
                                          // We can't add_const here, or it would be impossible to pass
                                          // auto_ptr<U> args from Python to C++
                                          >::type result_type;

    arg_rvalue_from_python(PyObject* obj)
        : m_data(converter::rvalue_from_python_stage1(obj, registered<T>::converters)), m_source(obj) {}
    bool convertible() const { return m_data.stage1.convertible != 0; }

#if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196
    typename arg_rvalue_from_python<T>::
#endif
        result_type
        operator()() {
        if (m_data.stage1.construct != 0) m_data.stage1.construct(m_source, &m_data.stage1);

        // Here is the magic...
        // Realign the pointer
        void* storage = reinterpret_cast<void*>(m_data.storage.bytes);
        void* aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16);

        return python::detail::void_ptr_to_reference(aligned, (result_type(*)())0);
    }

  private:
    rvalue_from_python_data<result_type> m_data;
    PyObject* m_source;
};

}  // namespace converter
}  // namespace python
}  // namespace boost

#endif /* NUMPY_EIGEN_CONVERTERS_HPP */

max_stars_repo_name: chengfzy/kalibr

max_issues_repo_name: chengfzy/kalibr

max_forks_repo_name: chengfzy/kalibr


text:
#pragma once

#include <xul/xio/net/url_handler_impl.hpp>
#include <xul/net/http/url_data_input_stream.hpp>
#include <xul/net/http/http_request.hpp>
#include <xul/util/log.hpp>
#include <boost/shared_ptr.hpp>
#include <list>
#include <stdint.h>
#include <stddef.h>

namespace xul {

class uri;
class http_request;
class http_response;
class http_content_range;

class stream_url_handler
    : public url_handler_impl
    , public url_data_input_stream_listener
{
public:
    explicit stream_url_handler(boost::shared_ptr<url_data_input_stream> stream)
        : m_stream(stream)
    {
        XUL_DEBUG("stream_url_handler construct " << this);
        //m_reading = false;
        m_sent_header = false;
        m_total_read_size = 0;
        m_stream->set_listener(this);
    }
    virtual ~stream_url_handler()
    {
        if (m_stream)
        {
            // cancel pending data callback
            m_stream->reset_listener();
        }

        XUL_DEBUG("stream_url_handler destruct " << this);
    }

    virtual void handle_request(io_session* session, message_decoder* decoder, const http_request& req)
    {
        m_session = session;
        m_client_request = req;
        m_request_range.clear();
        m_client_request.get_range(m_request_range);
        int64_t start_pos = m_request_range.get_real_start();
        //m_stats.set_start_position(start_pos);
        //m_stats.start_time.sync();
        m_sent_header = false;
        set_content_length(0);
        m_stream->open(session, req);
    }
    virtual void handle_data_sent(io_session* session, int bytes)
    {
        //url_handler::on_response_send(session, bytes);
        if (false == session->is_open())
        {
            XUL_WARN("on_response_send closed " << this);
            return;
        }
        XUL_DEBUG("on_response_send " << xul::make_tuple(bytes, session->get_writing_queue_size()));
        //update_stats();
        //send_data();
        int queue_size = session->get_writing_queue_size();
        int free_size = 20 - queue_size;
        for (int i = 0; i < free_size; ++i)
        {
            if (false == read_data())
                break;
        }
    }

    virtual void on_stream_open(url_data_input_stream*, const std::string& content_type, int64_t total_size)
    {
        XUL_DEBUG("on_stream_open " << xul::make_tuple(content_type, total_size));
        //assert(m_acca);
        //assert(m_stream);
        http_response resp;
        init_response(resp, m_request_range, total_size);
        resp.set_header("Server", "nginx/1.0.4");
        resp.set_content_type(content_type);
        if (m_request_range.is_valid())
        {
        }
        send_response(get_session(), resp, get_content_length());
        m_sent_header = true;
        if (get_content_length() > 0)
        {
            read_data();
        }
        //m_stream->read();
    }
    virtual void on_stream_read(url_data_input_stream* sender, const uint8_t* data, size_t size)
    {
        if (!get_session())
        {
            //assert(false);
            return;
        }
        //if (m_buffers.size() > 10)
        //    return;
        if (get_session()->get_writing_queue_size() > 40)
        {
            assert(false);
            return;
        }
        //update_stats();
        m_total_read_size += size;
        //assert(pos >= m_request_range.get_real_start());
        XUL_DEBUG("on_data_read " << xul::make_tuple(size, get_session()->get_writing_queue_size()));
        //if (false == m_reading)
        {
        //    assert(false);
        //    return;
        }
        //m_reading = false;
        if (0 == size)
            return;
        //if (errcode != 0)
        {
            //get_session()->close();
            //    retry_read();
            //    return;
        }
        get_session()->write_n(data, size);
#if 0
        buffer_ptr buf(new send_buffer_info);
        buf->data.assign(data, data + size);
        buf->position = 0;
        m_buffers.push_back(buf);
        send_data();
#endif
    }
    virtual void on_stream_read_failed( url_data_input_stream*, int errcode )
    {
        if (get_session())
        {
            get_session()->close();
        }
    }
    virtual void on_stream_open_failed( url_data_input_stream*, int errcode )
    {
        if (get_session())
        {
            if (errcode > 100 && errcode < 600)
            {
                send_error_response(get_session(), errcode);
                return;
            }
            get_session()->close();
        }
    }
    virtual void on_stream_finished(url_data_input_stream*)
    {
        if (get_to_send_size() < 0)
        {
            set_real_content_length(m_total_read_size);
            if (get_session() && get_session()->get_writing_queue_size() == 0)
                check_close_finished(get_session());
        }
    }

private:
    bool read_data()
    {
        if (!m_stream || !get_session())
            return false;
        XUL_DEBUG("read_data " << xul::make_tuple(m_stream, get_session()->get_writing_queue_size()));
        //if (m_reading)
        //    return;
        //if (m_buffers.size() > 2)
        //    return;
        if (false == get_session()->is_open())
            return false;
        if (get_session()->get_writing_queue_size() > 20)
            return false;
        //m_reading = true;
        //m_stream->async_read_n(readSize, this);
        return m_stream->read();
    }
#if 0
    void send_data()
    {
        if (!get_session() || false == get_session()->is_writable())
        {
            return;
        }
        if (m_buffers.empty())
        {
            read_data();
            return;
        }
        buffer_ptr buf = m_buffers.front();
        assert(get_session()->get_writing_queue_size() < 90);
        get_session()->write_n(&(buf->data)[0], buf->data.size());
        XUL_DEBUG("media send " << buf->data.size() << " bytes at position " << buf->position);
        //assert(buf->position >= m_request_range.get_real_start());
        m_buffers.pop_front();
        //read_data();
    }
#endif

private:
    class send_buffer_info
    {
    public:
        std::vector<uint8_t> data;
        int64_t position;
    };
    boost::shared_ptr<url_data_input_stream> m_stream;
    //bool m_reading;
    //typedef boost::shared_ptr<send_buffer_info> buffer_ptr;
    //std::list<buffer_ptr> m_buffers;

    http_request m_client_request;
    http_range m_request_range;
    bool m_sent_header;
    int64_t m_total_read_size;

    inet_socket_address m_local_address;
    inet_socket_address m_remote_address;
};

}

ext: hpp

max_stars_repo_name: hindsights/xul

max_issues_repo_name: hindsights/xul

max_forks_repo_name: hindsights/xul


text:
#include <string>
#include <boost/functional/hash.hpp>
#include <llvm/IR/Constants.h>
#include "predicate_groups.hpp"
#include "FactGenerator.hpp"

using cclyzer::FactGenerator;
using llvm::cast;
using llvm::isa;
namespace pred = cclyzer::predicates;

//------------------------------------------------------------------------------
// Top-level method that records every kind of constant
//------------------------------------------------------------------------------

cclyzer::refmode_t
FactGenerator::writeConstant(const llvm::Constant &c)
{
    using namespace llvm;
    static boost::hash<std::string> string_hash;

    refmode_t id = refmode<llvm::Constant>(c);

    // Record constant entity with its type
    writeFact(pred::constant::id, id);
    writeFact(pred::constant::type, id, recordType(c.getType()));

    // Record constant value
    std::string rv;
    raw_string_ostream rso(rv);
    c.printAsOperand(rso, /* PrintType */ false);
    const std::string& val = rso.str();
    size_t hashCode = string_hash(val);

    writeFact(pred::constant::value, id, val);
    writeFact(pred::constant::hash, id, hashCode);

    if (isa<ConstantPointerNull>(c)) {
        writeFact(pred::nullptr_constant::id, id);
    }
    else if (isa<ConstantInt>(c)) {
        writeFact(pred::integer_constant::id, id);

        // Compute integer string representation
        std::string int_value = c.getUniqueInteger().toString(10, true);

        // Write constant to integer fact
        writeFact(pred::constant::to_integer, id, int_value);
    }
    else if (isa<ConstantFP>(c)) {
        writeFact(pred::fp_constant::id, id);
    }
    else if (isa<Function>(c)) {
        const Function &func = cast<Function>(c);
        const std::string funcname = "@" + func.getName().str();

        writeFact(pred::function_constant::id, id);
        writeFact(pred::function_constant::name, id, funcname);
    }
    else if (isa<GlobalVariable>(c)) {
        const GlobalVariable &global_var = cast<GlobalVariable>(c);
        const std::string varname = "@" + global_var.getName().str();

        writeFact(pred::global_variable_constant::id, id);
        writeFact(pred::global_variable_constant::name, id, varname);
    }
    else if (isa<ConstantExpr>(c)) {
        writeConstantExpr(cast<ConstantExpr>(c), id);
    }
    else if (isa<ConstantArray>(c)) {
        writeConstantArray(cast<ConstantArray>(c), id);
    }
    else if (isa<ConstantStruct>(c)) {
        writeConstantStruct(cast<ConstantStruct>(c), id);
    }
    else if (isa<ConstantVector>(c)) {
        writeConstantVector(cast<ConstantVector>(c), id);
    }

    return id;
}

//------------------------------------------------------------------------------
// Method that records every kind of constant expression
//------------------------------------------------------------------------------

void
FactGenerator::writeConstantExpr(const llvm::ConstantExpr &expr,
                                 const refmode_t &refmode)
{
    writeFact(pred::constant_expr::id, refmode);

    if (expr.isCast()) {
        refmode_t opref;

        switch (expr.getOpcode()) {
          case llvm::Instruction::BitCast:
              opref = writeConstant(*expr.getOperand(0));

              writeFact(pred::bitcast_constant_expr::id, refmode);
              writeFact(pred::bitcast_constant_expr::from_constant, refmode, opref);
              break;
          case llvm::Instruction::IntToPtr:
              opref = writeConstant(*expr.getOperand(0));

              writeFact(pred::inttoptr_constant_expr::id, refmode);
              writeFact(pred::inttoptr_constant_expr::from_int_constant, refmode, opref);
              break;
          case llvm::Instruction::PtrToInt:
              opref = writeConstant(*expr.getOperand(0));

              writeFact(pred::ptrtoint_constant_expr::id, refmode);
              writeFact(pred::ptrtoint_constant_expr::from_ptr_constant, refmode, opref);
              break;
        }
    }
    else if (expr.isGEPWithNoNotionalOverIndexing()) {
        unsigned nOperands = expr.getNumOperands();

        for (unsigned i = 0; i < nOperands; i++)
        {
            const llvm::Constant *c = cast<llvm::Constant>(expr.getOperand(i));

            refmode_t index_ref = writeConstant(*c);

            if (i > 0)
                writeFact(pred::gep_constant_expr::index, refmode, i - 1, index_ref);
            else
                writeFact(pred::gep_constant_expr::base, refmode, index_ref);
        }

        writeFact(pred::gep_constant_expr::nindices, refmode, nOperands - 1);
        writeFact(pred::gep_constant_expr::id, refmode);
    }
    else {
        // TODO
    }
}

//------------------------------------------------------------------------------
// Template Method for similar constant constructs
//------------------------------------------------------------------------------

template<typename PredGroup, class ConstantType> void
FactGenerator::writeConstantWithOperands(const ConstantType &base,
                                         const refmode_t &refmode)
{
    unsigned nOperands = base.getNumOperands();

    for (unsigned i = 0; i < nOperands; i++)
    {
        const llvm::Constant *c = base.getOperand(i);

        refmode_t index_ref = writeConstant(*c);
        writeFact(PredGroup::index, refmode, i, index_ref);
    }

    writeFact(PredGroup::size, refmode, nOperands);
    writeFact(PredGroup::id, refmode);
}

void FactGenerator::writeConstantArray(const llvm::ConstantArray &array,
                                       const refmode_t &refmode)
{
    writeConstantWithOperands<pred::constant_array>(array, refmode);
}

void FactGenerator::writeConstantStruct(const llvm::ConstantStruct &st,
                                        const refmode_t &refmode)
{
    writeConstantWithOperands<pred::constant_struct>(st, refmode);
}

void FactGenerator::writeConstantVector(const llvm::ConstantVector &v,
                                        const refmode_t &refmode)
{
    writeConstantWithOperands<pred::constant_vector>(v, refmode);
}

ext: cpp

max_stars_repo_name: plast-lab/cclyzer

max_issues_repo_name: plast-lab/cclyzer

max_forks_repo_name: plast-lab/cclyzer


text:
// #pragma GCC optimize ("O0")

#include <fstream>

#include <boost/log/trivial.hpp>

#include "rinexNavWrite.hpp"
#include "rinexObsWrite.hpp"
#include "rinexClkWrite.hpp"
#include "streamTrace.hpp"
#include "navigation.hpp"
#include "acsConfig.hpp"
#include "common.hpp"
#include "rinex.hpp"

struct RinexNavFileOutput
{
	map<E_Sys,	bool>	sysMap;
	map<SatSys, int>	last_iode;  ///< Used to track last ephemeris.
};

map<string, RinexNavFileOutput> filenameNavFileDataMap;

void outputNavRinexEph(
	Eph&	eph,
	Trace&	trace)
{
	string formatStr = "% 15.12fE%+03d";

	auto sys = eph.Sat.sys;

	double ep[6];
	if (sys != +E_Sys::BDS)	{		time2epoch(eph.toc,				ep);	}
	else					{		time2epoch(gpst2bdt(eph.toc),	ep); 	}	/* gpst -> bdt */

	tracepdeex(0, trace, "%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f", eph.Sat.id().c_str(), ep[0], ep[1], ep[2], ep[3], ep[4], ep[5]);

	traceFormatedFloat(trace, eph.f0,		formatStr);
	traceFormatedFloat(trace, eph.f1,		formatStr);
	traceFormatedFloat(trace, eph.f2,		formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, eph.iode,		formatStr); /* GPS/QZS: IODE, GAL: IODnav, BDS: AODE */
	traceFormatedFloat(trace, eph.crs,		formatStr);
	traceFormatedFloat(trace, eph.deln,		formatStr);
	traceFormatedFloat(trace, eph.M0,		formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, eph.cuc,		formatStr);
	traceFormatedFloat(trace, eph.e,		formatStr);
	traceFormatedFloat(trace, eph.cus,		formatStr);
	traceFormatedFloat(trace, sqrt(eph.A),	formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, eph.toes,		formatStr);
	traceFormatedFloat(trace, eph.cic,		formatStr);
	traceFormatedFloat(trace, eph.OMG0,		formatStr);
	traceFormatedFloat(trace, eph.cis,		formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, eph.i0,		formatStr);
	traceFormatedFloat(trace, eph.crc,		formatStr);
	traceFormatedFloat(trace, eph.omg,		formatStr);
	traceFormatedFloat(trace, eph.OMGd,		formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, eph.idot,		formatStr);
	traceFormatedFloat(trace, eph.code,		formatStr);
	traceFormatedFloat(trace, eph.week,		formatStr); /* GPS/QZS: GPS week, GAL: GAL week, BDS: BDT week */
	traceFormatedFloat(trace, eph.flag,		formatStr);
	trace << std::endl;

	trace << "    ";
	if (sys != +E_Sys::GAL)		{	traceFormatedFloat(trace, svaToUra(eph.sva),	formatStr);	}
	else						{	traceFormatedFloat(trace, svaToSisa(eph.sva),	formatStr);	}

	traceFormatedFloat(trace, eph.svh,		formatStr);
	traceFormatedFloat(trace, eph.tgd[0],	formatStr); /* GPS/QZS:TGD, GAL:BGD E5a/E1, BDS: TGD1 B1/B3 */

	if	(  sys == +E_Sys::GAL
		|| sys == +E_Sys::BDS)	{	traceFormatedFloat(trace, eph.tgd[1],	formatStr);	}	/* GAL:BGD E5b/E1, BDS: TGD2 B2/B3 */
	else						{	traceFormatedFloat(trace, eph.iodc,		formatStr);	}	/* GPS/QZS:IODC */
	trace << std::endl;

	trace << "    ";
	double ttr;
	int week;
	if (sys != +E_Sys::BDS)		{	ttr = time2gpst(eph.ttr,			&week);	}
	else 						{	ttr = time2bdt(gpst2bdt(eph.ttr),	&week);	} /* gpst -> bdt */
	traceFormatedFloat(trace, ttr + (week - eph.week) * 604800.0, formatStr);

	if		(  sys == +E_Sys::GPS
			|| sys == +E_Sys::QZS)	{		traceFormatedFloat(trace, eph.fit,	formatStr);	}
	else if (  sys == +E_Sys::BDS)	{		traceFormatedFloat(trace, eph.iodc,	formatStr);	}	/* AODC */
	else							{		traceFormatedFloat(trace, 0,		formatStr);	}	/* spare */
	trace << std::endl;
}

void outputNavRinexGeph(
	Geph&	geph,
	Trace&	trace)
{
	string formatStr = "% 15.12fE%+03d";

	if (geph.Sat.sys != +E_Sys::GLO)
	{
		BOOST_LOG_TRIVIAL(error) << "Error output Geph to RINEX incorrect system type";
		return;
	}

	double tof = time2gpst(gpst2utc(geph.tof), nullptr);      /* v.3: tow in utc */

	double ep[6];
	GTime toe = gpst2utc(geph.toe); /* gpst -> utc */
	time2epoch(toe, ep);

	tracepdeex(0, trace, "%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f", geph.Sat.id().c_str(), ep[0], ep[1], ep[2], ep[3], ep[4], ep[5]);
	traceFormatedFloat(trace, geph.taun,	formatStr);
	traceFormatedFloat(trace, geph.gamn,	formatStr);
	traceFormatedFloat(trace, tof, formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, geph.pos[0] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.vel[0] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.acc[0] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.svh, formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, geph.pos[1] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.vel[1] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.acc[1] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.frq, formatStr);
	trace << std::endl;

	trace << "    ";
	traceFormatedFloat(trace, geph.pos[2] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.vel[2] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.acc[2] / 1E3, formatStr);
	traceFormatedFloat(trace, geph.age, formatStr);
	trace << std::endl;
}

void outputNavRinexBody(
	RinexNavFileOutput&	outFileData,
	Trace&				rinexStream)
{
	for (auto& [sys, output] : outFileData.sysMap)
	{
		if (output == false)
			continue;

		int idode = -1;
		for (auto& [satId, satNav] : nav.satNavMap)
		{
			SatSys sat;
			sat.fromHash(satId);

			if (sat.sys != sys)
				continue;

			if (sys == +E_Sys::GLO)
			{
				Geph* geph_ptr = seleph<Geph>(std::cout, tsync, sat, -1, nav);

				if (geph_ptr == nullptr)
					continue;

				if	( outFileData.last_iode.find(sat)	== outFileData.last_iode.end()
					||geph_ptr->iode					!= outFileData.last_iode[sat])
				{
					outFileData.last_iode[sat] = geph_ptr->iode;
					outputNavRinexGeph(*geph_ptr, rinexStream);
				}

				continue;
			}
			else
			{
				Eph* eph_ptr = seleph<Eph>(std::cout, tsync, sat, -1, nav);

				if (eph_ptr == nullptr)
					continue;

				// Note iode can be zero, checking the map makes a zero entry as well.
				if	(  outFileData.last_iode.find(sat)	== outFileData.last_iode.end()
					|| eph_ptr->iode					!= outFileData.last_iode[sat])
				{
					outFileData.last_iode[sat] = eph_ptr->iode;
					outputNavRinexEph(*eph_ptr, rinexStream);
				}

				continue;
			}
		}
	}
}

void rinexNavHeader(
	map<E_Sys, bool>&	sysMap,
	Trace&				rinexStream)
{
	double rnxver	= 3.05;
	string prog		= "PEA v1";
	string runby	= "Geoscience Australia";

	GTime now = utc2gpst(timeget());

	char tempStr[20];
	time2str(now, tempStr, 0);

	string timeDate(tempStr);
	boost::replace_all(timeDate, "/", "");
	boost::replace_all(timeDate, ":", "");
	timeDate += " UTC";

	string sysDesc;
	if (sysMap.size() == 1)	sysDesc = rinexSysDesc(sysMap.begin()->first);
	else					sysDesc = rinexSysDesc(E_Sys::COMB);

	tracepdeex(0, rinexStream, "%9.2f%-11s%-20s%-20s%-20s\n",
		rnxver,
		"",
		"N: GNSS NAV DATA",
		sysDesc.c_str(),
		"RINEX VERSION / TYPE");

	tracepdeex(0, rinexStream, "%-20.20s%-20.20s%-20.20s%-20s\n",
		prog.c_str(),
		runby.c_str(),
		timeDate.c_str(),
		"PGM / RUN BY / DATE");

	for (auto& [sys, output] : sysMap)
	{
		if (output == false)
		{
			continue;
		}

		double* ion_arr1 = nullptr;
		double* ion_arr2 = nullptr;
		string	ion_str1;
		string	ion_str2;
		switch (sys)
		{
			case E_Sys::GPS:	ion_arr1 = &nav.ion_gps[0];		ion_str1 = "GPSA";
								ion_arr2 = &nav.ion_gps[4];		ion_str2 = "GPSB";	break;

			case E_Sys::GAL:	ion_arr1 = &nav.ion_gal[0];		ion_str1 = "GAL ";	break;

			case E_Sys::QZS:	ion_arr1 = &nav.ion_qzs[0];		ion_str1 = "QZSA";
								ion_arr2 = &nav.ion_gps[4];		ion_str2 = "QZSB";	break;
			default:
				continue;
		}

		if (ion_arr1)
			tracepdeex(0, rinexStream, "%s %12.4E%12.4E%12.4E%12.4E%7s%-20s\n",
				ion_str1.c_str(),
				ion_arr1[0],
				ion_arr1[1],
				ion_arr1[2],
				ion_arr1[3], "", "IONOSPHERIC CORR");

		if (ion_arr2)
			tracepdeex(0, rinexStream, "%s %12.4E%12.4E%12.4E%12.4E%7s%-20s\n",
				ion_str2.c_str(),
				ion_arr2[0],
				ion_arr2[1],
				ion_arr2[2],
				ion_arr2[3], "", "IONOSPHERIC CORR");
	}

	for (auto& [sys, output] : sysMap)
	{
		if (output == false)
			continue;

		double*	tsys_arr = nullptr;
		string	tsys_str;

		switch (sys)
		{
			case E_Sys::GPS:	tsys_arr = nav.utc_gps;		tsys_str = "GPUT";			break;
			case E_Sys::GAL:	tsys_arr = nav.utc_gal;		tsys_str = "GAUT";			break;
			case E_Sys::QZS:	tsys_arr = nav.utc_qzs;		tsys_str = "QZUT";			break;
			case E_Sys::BDS:	tsys_arr = nav.utc_cmp;		tsys_str = "BDUT";			break;

			default:
				continue;
		}

		tracepdeex(0, rinexStream, "%s %17.10E%16.9E%7.0f%5.0f %-5s %-2s %-20s\n",
			tsys_str.c_str(),
			tsys_arr[0],
			tsys_arr[1],
			tsys_arr[2],
			tsys_arr[3], "", "", "TIME SYSTEM CORR");
	}

	tracepdeex(0, rinexStream, "%6d%54s%-20s\n", nav.leaps, "", 	"LEAP SECONDS");
	tracepdeex(0, rinexStream, "%60s%-20s\n", "",					"END OF HEADER");
}

void writeRinexNav()
{
	auto filenameSysMap = getSysOutputFilenames(acsConfig.rinex_nav_filename, tsync);

	for (auto [filename, sysMap] : filenameSysMap)
	{
		auto& fileData = filenameNavFileDataMap[filename];

		std::ofstream rinexStream(filename, std::ofstream::app);
		if (!rinexStream)
		{
			BOOST_LOG_TRIVIAL(error) << "Error opening " << filename << " for writing rinex nav";
		}

		if (rinexStream.tellp() == 0)
			rinexNavHeader(sysMap, rinexStream);

		fileData.sysMap = sysMap;

		outputNavRinexBody(fileData, rinexStream);
	}
}

max_stars_repo_name: HiTMonitor/ginan


text:
#ifndef CONCEPT_GAMMA_COMMANDS_HPP
#define CONCEPT_GAMMA_COMMANDS_HPP

#include <list>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/exception.hpp>
#include <boost/utility.hpp>

#include "utility/queue.hpp"

#include "frame/ipc/ipcconnectionuid.hpp"

#include "core/common.hpp"

#include "gammacommand.hpp"

namespace fs = boost::filesystem;
using boost::filesystem::path;
using boost::next;
using boost::prior;

using solid::uint16;

namespace solid{
namespace protocol{
struct Parameter;
}
}

namespace concept{
namespace gamma{

class Connection;
class Reader;
class Writer;

//! Basic alpha commands - with no parameters.
class Basic: public Command{
public:
	enum Types{
		Noop, Logout, Capability
	};
	Basic(Types _tp);
	~Basic();
	void initReader(Reader &);
	void execute(const uint _sid);
private:
	void execNoop(const uint _sid);
	void execLogout(const uint _sid);
	void execCapability(const uint _sid);
private:
	Types tp;
};

//! Alpha Login command
/*!
	Syntax:

	tag SP LOGIN SP astring = nume SP astring = password CRLF

*/
class Login: public Command{
public:
	Login();
	~Login();
	void initReader(Reader &);
	void execute(const uint _sid);
private:
	void contextData(ObjectUidT &);
	solid::String user,pass, ctx;
};

}//namespace gamma
}//namespace concept

#endif

max_stars_repo_name: joydit/solidframe

max_issues_repo_name: joydit/solidframe

max_forks_repo_name: joydit/solidframe


text:
/**
 * Copyright (c) 2009 Carnegie Mellon University.
 *     All rights reserved.
 *
 *  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.
 *
 * For more about this software visit:
 *
 *      http://www.graphlab.ml.cmu.edu
 *
 */

/**
 * Also contains code that is Copyright 2011 Yahoo! Inc.  All rights
 * reserved.
 *
 * Contributed under the iCLA for:
 *    Joseph Gonzalez (jegonzal@yahoo-inc.com)
 *
 */

#ifndef GRAPHLAB_DELTA_DHT_HPP
#define GRAPHLAB_DELTA_DHT_HPP

#include <boost/unordered_map.hpp>
#include <boost/functional/hash.hpp>

#include <graphlab/rpc/dc.hpp>
#include <graphlab/parallel/pthread_tools.hpp>
#include <graphlab/util/cache.hpp>

#include <graphlab/macros_def.hpp>
namespace graphlab {

  namespace delta_dht_impl {
    struct icache { virtual ~icache() { } };
    icache*& get_icache_ptr(const void* dht_ptr);
  }; // end of namespace delta_dht_impl

  namespace delta_predicate {
    template<typename ValueType, typename DeltaType>
    struct uses {
      size_t max_uses;
      uses(size_t max_uses = 100) : max_uses(max_uses) { }
      //! returns true if the predicate
      bool operator()(const ValueType& current,
                      const DeltaType& delta,
                      const size_t& uses) const {
        return uses < max_uses;
      }
    }; // end of uses

  }; // end of eviction predicates

  template<typename KeyType, typename ValueType,
           typename DeltaType = ValueType>
  class delta_dht {
  public:
    typedef KeyType   key_type;
    typedef ValueType value_type;
    typedef DeltaType delta_type;

    typedef size_t    size_type;

    typedef boost::unordered_map<key_type, value_type> data_map_type;

    struct cache_entry {
      value_type value;
      delta_type delta;
      size_t uses;
      cache_entry(const value_type& value = value_type()) :
        value(value), uses(0) { }
    };

    typedef cache::lru<key_type, cache_entry> cache_type;

  private:

    //! The remote procedure call manager
    mutable dc_dist_object<delta_dht> rpc;

    //! The data stored locally on this machine
    data_map_type  data_map;

    //! The lock for the data map
    mutex data_lock;

    //! The master cache
    cache_type cache;

    //! The master cash rw lock
    mutex cache_lock;

    //! The maximum cache size
    size_t max_cache_size;

    size_t max_uses;

    //! the hash function
    boost::hash<key_type> hash_function;

    //! cache hits and misses
    mutable atomic<size_t> local;
    mutable atomic<size_t> hits;
    mutable atomic<size_t> misses;
    mutable atomic<size_t> background_updates;

  public:

    delta_dht(distributed_control& dc,
              size_t max_cache_size = 2056) :
      rpc(dc, this),
      max_cache_size(max_cache_size), max_uses(10) {
      rpc.barrier();
    }

    ~delta_dht() { rpc.full_barrier(); }

    void set_max_uses(size_t max) { max_uses = max; }

    size_t cache_local() const { return local.value; }
    size_t cache_hits() const { return hits.value; }
    size_t cache_misses() const { return misses.value; }
    size_t background_syncs() const { return background_updates.value; }

    size_t cache_size() const {
      cache_lock.lock();
      const size_t ret_val = cache.size();
      cache_lock.unlock();
      return ret_val;
    }

    bool is_cached(const key_type& key) const {
      cache_lock.lock();
      const bool ret_value = cache.contains(key);
      cache_lock.unlock();
      return ret_value;
    }

    value_type operator[](const key_type& key) {
      if(is_local(key)) {
        ++local;
        data_lock.lock();
        const value_type value = data_map[key];
        data_lock.unlock();
        return value;
      } else { // on a remote machine check the cache
        // test for the key in the cache
        cache_lock.lock();
        if(cache.contains(key)) {
          ++hits;
          const value_type ret_value = cache[key].value;
          cache_lock.unlock();
          return ret_value;
        } else { // need to create a cache entry
          ++misses;
          // Free space in the cache if necessary
          while(cache.size() + 1 > max_cache_size) {
            ASSERT_GT(cache.size(), 0);
            const std::pair<key_type, cache_entry> pair = cache.evict();
            const key_type& key                         = pair.first;
            const cache_entry& entry                    = pair.second;
            send_delta(key, entry.delta);
          }
          // get the new entry from the server
          const value_type ret_value = (cache[key].value = get_master(key));
          cache_lock.unlock();
          return ret_value;
        }
      }
    } // end of operator []

    void apply_delta(const key_type& key, const delta_type& delta) {
      if(is_local(key)) {
        data_lock.lock();
        data_map[key] += delta;
        data_lock.unlock();
      } else {
        // update the cache entry if availablable
        cache_lock.lock();
        if(cache.contains(key)) {
          cache_entry& entry = cache[key];
          entry.value += delta;
          entry.delta += delta;
          if( entry.uses > max_uses ) {
            const delta_type accum_delta = entry.delta;
            entry.delta = delta_type();
            entry.uses = 0;
            cache_lock.unlock();
            send_delta(key, accum_delta);
            return;
          }
        }
        cache_lock.unlock();
      }
    }

    //! empty the local cache
    void flush() {
      cache_lock.lock();
      while(cache.size() > 0) {
        const std::pair<key_type, cache_entry> pair = cache.evict();
        const key_type& key = pair.first;
        const cache_entry& entry = pair.second;
        send_delta(key, entry.delta);
      }
      cache_lock.unlock();
    }

    //! empty the local cache
    void barrier_flush() {
      flush();
      rpc.full_barrier();
    }

    void synchronize() {
      typedef typename cache_type::pair_type pair_type;
      cache_lock.lock();
      foreach(pair_type& pair, cache) {
        key_type& key = pair.first;
        cache_entry& entry = pair.second;
        if(entry.uses > 0) {
          const delta_type accum_delta = entry.delta;
          entry.delta = delta_type();
          entry.uses = 0;
          send_delta(key, accum_delta);
        }
      } // end of foreach
      cache_lock.unlock();
    }

    void synchronize(const key_type& key) {
      if(is_local(key)) return;
      cache_lock.lock();
      if(cache.contains(key)) {
        cache_entry& entry = cache[key];
        const delta_type accum_delta = entry.delta;
        entry.delta = delta_type();
        entry.uses = 0;
        cache_lock.unlock();
        send_delta(key, accum_delta);
      } else cache_lock.unlock();
    }

    size_t owning_cpu(const key_type& key) const {
      const size_t hash_value = hash_function(key);
      const size_t cpuid = hash_value % rpc.numprocs();
      return cpuid;
    }

    bool is_local(const key_type& key) const {
      return owning_cpu(key) == rpc.procid();
    } // end of is local

    delta_type delta(const key_type& key) const {
      if(!is_local(key)) {
        cache_lock.lock();
        if(cache.contains(key)) {
          const delta_type delta = cache[key].delta;
          cache_lock.unlock();
          return delta;
        }
        cache_lock.unlock();
      }
      return delta_type();
    }

    size_t local_size() const {
      data_lock.lock();
      const size_t result = data_map.size();
      data_lock.unlock();
      return result;
    }

    size_t size() const {
      size_t sum = 0;
      for(size_t i = 0; i < rpc.numprocs(); ++i) {
        if(i == rpc.procid()) sum += local_size();
        else sum += rpc.remote_request(i, &delta_dht::local_size);
      }
      return sum;
    }

    size_t numprocs() const { return rpc.num_procs(); }
    size_t procid() const { return rpc.procid(); }

    value_type get_master(const key_type& key) {
      // If the data is stored locally just read and return
      if(is_local(key)) {
        data_lock.lock();
        const value_type ret_value = data_map[key];
        data_lock.unlock();
        return ret_value;
      } else {
        return rpc.remote_request(owning_cpu(key),
                                  &delta_dht::get_master, key);
      }
    } // end of direct get

  private:

    void send_delta(const key_type& key, const delta_type& delta)  {
      // If the data is stored locally just read and return
      ASSERT_FALSE(is_local(key));
      const size_t calling_procid = procid();
      rpc.remote_call(owning_cpu(key),
                      &delta_dht::send_delta_rpc,
                      calling_procid, key, delta);

    } // end of send_delta

    void send_delta_rpc(const size_t& calling_procid,
                        const key_type& key, const delta_type& delta)  {
      // If the data is stored locally just read and return
      ASSERT_TRUE(is_local(key));
      data_lock.lock();
      const value_type ret_value = (data_map[key] += delta);
      data_lock.unlock();
      rpc.remote_call(calling_procid,
                      &delta_dht::send_delta_rpc_callback, key, ret_value);

    } // end of send_delta_rpc

    void send_delta_rpc_callback(const key_type& key, const value_type& new_value)  {
      // If the data is stored locally just read and return
      ASSERT_FALSE(is_local(key));
      cache_lock.lock();
      if(cache.contains(key)) {
        cache_entry& entry = cache[key];
        entry.value = new_value;
        entry.value += entry.delta;
      }
      ++background_updates;
      cache_lock.unlock();
    } // end of send_delta_rpc_callback

    // void synchronize(const key_type& key, cache_entry& entry)  {
    //   const value_type delta = entry.current - entry.old;
    //   entry.old = synchronize_rpc(key, delta);
    //   entry.current = entry.old;
    // } // end of synchronize

    // value_type synchronize_rpc(const key_type& key, const value_type& delta) {
    //   if(is_local(key)) {
    //     data_lock.lock();
    //     typename data_map_type::iterator iter = data_map.find(key);
    //     ASSERT_TRUE(iter != data_map.end());
    //     const value_type ret_value = (iter->second += delta);
    //     data_lock.unlock();
    //     return ret_value;
    //   } else {
    //     return rpc.remote_request(owning_cpu(key),
    //                               &delta_dht::synchronize_rpc,
    //                               key, delta);
    //   }
    // } // end of synchronize_rpc

  }; // end of delta_dht

}; // end of namespace graphlab
#include <graphlab/macros_undef.hpp>

#endif

max_issues_repo_name: HybridGraph/GraphLab-PowerGraph

max_forks_repo_name: HybridGraph/GraphLab-PowerGraph


text:
/*ckwg +29
 * Copyright 2015 by Kitware, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither name of Kitware, Inc. nor the names of any contributors may be used
 *    to endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * \file
 * \brief core essential matrix template implementations
 */

#include "essential_matrix.h"

#include <cmath>

#include <vital/exceptions/math.h>

#include <Eigen/SVD>

namespace kwiver {
namespace vital {

/// Compute the twisted pair rotation from the rotation and translation
rotation_d
essential_matrix
::twisted_rotation() const
{
  // The quaternion representation of a 180 degree rotation about
  // unit vector [X,Y,Z] is simply [X, Y, Z, 0]
  vector_3d t = this->translation();
  return rotation_d(vector_4d(t.x(), t.y(), t.z(), 0.0)) * this->rotation();
}

/// Construct from a provided matrix
template <typename T>
essential_matrix_<T>
::essential_matrix_( Eigen::Matrix<T,3,3> const &mat )
{
  const matrix_t W = (matrix_t() << T(0), T(-1), T(0),
                                    T(1), T( 0), T(0),
                                    T(0), T( 0), T(1)).finished();
  Eigen::JacobiSVD<matrix_t> svd(mat, Eigen::ComputeFullU |
                                      Eigen::ComputeFullV);
  const matrix_t& U = svd.matrixU();
  const matrix_t& V = svd.matrixV();
  trans_ = U.col(2);
  matrix_t R = U*W*V.transpose();
  if( R.determinant() < T(0) )
  {
    R *= T(-1);
  }
  rot_ = rotation_<T>(R);
}

/// Construct from a rotation and translation
template <typename T>
essential_matrix_<T>
::essential_matrix_( rotation_<T> const &rot,
                     vector_t const &trans )
  : rot_( rot ),
    trans_( trans.normalized() )
{
}

/// Conversion Copy constructor -- float specialization
template <>
template <>
essential_matrix_<float>
::essential_matrix_( essential_matrix_<float> const &other )
  : rot_( other.rot_ ),
    trans_( other.trans_ )
{
}

/// Conversion Copy constructor -- double specialization
template <>
template <>
essential_matrix_<double>
::essential_matrix_( essential_matrix_<double> const &other )
  : rot_( other.rot_ ),
    trans_( other.trans_ )
{
}

/// Construct from a generic essential_matrix
template <typename T>
essential_matrix_<T>
::essential_matrix_( essential_matrix const &base )
  : rot_( static_cast<rotation_<T> >(base.rotation()) ),
    trans_( base.translation().template cast<T>() )
{
}

/// Construct from a generic essential_matrix -- double specialization
template <>
essential_matrix_<double>
::essential_matrix_( essential_matrix const &base )
  : rot_( base.rotation() ),
    trans_( base.translation() )
{
}

/// Create a clone of outself as a shared pointer
template <typename T>
essential_matrix_sptr
essential_matrix_<T>
::clone() const
{
  return essential_matrix_sptr( new essential_matrix_<T>( *this ) );
}

/// Get a double-typed copy of the underlying matrix
template <typename T>
Eigen::Matrix<double,3,3>
essential_matrix_<T>
::matrix() const
{
  return this->compute_matrix().template cast<double>();
}

/// Specialization for matrices with native double type
template <>
Eigen::Matrix<double,3,3>
essential_matrix_<double>
::matrix() const
{
  return this->compute_matrix();
}

/// Return the one of two possible 3D rotations that can parameterize E
template <typename T>
rotation_d
essential_matrix_<T>
::rotation() const
{
  return static_cast<rotation_d>(this->rot_);
}

/// Return the second possible rotation that can parameterize E
template <typename T>
rotation_d
essential_matrix_<T>
::twisted_rotation() const
{
  return static_cast<rotation_d>(this->compute_twisted_rotation());
}

/// Return a unit translation vector (up to a sign) that parameterizes E
template <typename T>
vector_3d
essential_matrix_<T>
::translation() const
{
  return this->trans_.template cast<double>();
}

/// Get the underlying matrix
template <typename T>
typename essential_matrix_<T>::matrix_t
essential_matrix_<T>
::compute_matrix() const
{
  matrix_t t_cross;
  t_cross << T(0), -trans_[2], trans_[1],
             trans_[2], T(0), -trans_[0],
            -trans_[1], trans_[0], T(0);
  return t_cross * matrix_t(rot_.matrix());
}

/// Compute the twisted pair rotation from the rotation and translation
template <typename T>
rotation_<T>
essential_matrix_<T>
::compute_twisted_rotation() const
{
  typedef Eigen::Matrix<T,4,1> vector_4;
  // The quaternion representation of a 180 degree rotation about
  // unit vector [X,Y,Z] is simply [X, Y, Z, 0]
  const vector_t& t = trans_;
  return rotation_<T>(vector_4(t.x(), t.y(), t.z(), T(0))) * rot_;
}

/// Get a const reference to the underlying rotation
template <typename T>
rotation_<T> const&
essential_matrix_<T>
::get_rotation() const
{
  return rot_;
}

/// Get a const reference to the underlying translation
template <typename T>
typename essential_matrix_<T>::vector_t const&
essential_matrix_<T>
::get_translation() const
{
  return trans_;
}

// ===========================================================================
// Other Functions
// ---------------------------------------------------------------------------

/// essential_matrix_<T> output stream operator
template <typename T>
std::ostream&
operator<<( std::ostream &s, essential_matrix_<T> const &e )
{
  s << e.compute_matrix();
  return s;
}

/// Output stream operator for \p essential_matrix instances
std::ostream&
operator<<( std::ostream &s, essential_matrix const &e )
{
  s << e.matrix();
  return s;
}

// ===========================================================================
// Template class instantiation
// ---------------------------------------------------------------------------
/// \cond DoxygenSuppress
#define INSTANTIATE_ESSENTIAL_MATRIX(T)                                 \
  template class essential_matrix_<T>;                                  \
  template VITAL_EXPORT std::ostream& operator<<( std::ostream &,       \
                        essential_matrix_<T> const & )

INSTANTIATE_ESSENTIAL_MATRIX(float);
INSTANTIATE_ESSENTIAL_MATRIX(double);
#undef INSTANTIATE_ESSENTIAL_MATRIX
/// \endcond

} } // end vital namespace

ext: cxx

max_stars_repo_name: neal-siekierski/kwiver

max_issues_repo_name: neal-siekierski/kwiver

max_forks_repo_name: neal-siekierski/kwiver


text:
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
#include "Optimize.h"

#include <boost/make_shared.hpp>
#include <caffe/net.hpp>
#include <caffe/syncedmem.hpp>
#include <folly/Format.h>
#include <folly/Memory.h>
#include <glog/stl_logging.h>
#include <unordered_map>

namespace caffe {
namespace fb {

namespace {

constexpr int64_t kNotDefined = 0;
constexpr int64_t kNotUsed = -1;
constexpr int64_t kAlwaysLive = 10000;
constexpr int64_t kMinimumCountForSharing = 10000;

struct LiveRange {
  int64_t defined{kNotDefined}, used{kNotUsed};
};

template<typename T>
using Analysis = std::unordered_map<SyncedMemory*, T>;
template<typename T>
using OrderedAnalysis = std::vector<std::pair<SyncedMemory*, T>>;
using SyncedMemoryRange = std::pair<SyncedMemory*, LiveRange>;
using Assignment = std::vector<SyncedMemoryRange>;
using Assignments = std::vector<Assignment>;

template <typename T>
T& findOrInsert(OrderedAnalysis<T>* analysis, SyncedMemory* needle) {
  for (auto& kv : *analysis) {
    if (kv.first == needle) {
      return kv.second;
    }
  }
  analysis->push_back({needle, T()});
  return analysis->back().second;
}

OrderedAnalysis<LiveRange> analyze(const caffe::Net<float>& net) {
  // Build up the liveness analysis by walking the SyncedMemory
  // pointers attached the the blobs in the network.
  const auto& bottoms = net.bottom_vecs();
  const auto& tops = net.top_vecs();
  OrderedAnalysis<LiveRange> analysis;
  for (int64_t i = 0; i < bottoms.size(); ++i) {
    for (const auto* bottom : bottoms[i]) {
      auto& range = findOrInsert(&analysis, bottom->data().get());
      if (range.used == kNotUsed) {
        range.used = i;
        continue;
      }
      range.used = std::max(range.used, i);
    }
  }
  for (int64_t i = 0; i < tops.size(); ++i) {
    for (const auto* top : tops[i]) {
      auto& range = findOrInsert(&analysis, top->data().get());
      if (range.defined == kNotDefined) {
        range.defined = i;
        continue;
      }
      range.defined = std::min(range.defined, i);
    }
  }
  for (const auto* input : net.input_blobs()) {
    findOrInsert(&analysis, input->data().get()).defined = -kAlwaysLive;
    findOrInsert(&analysis, input->data().get()).used = kAlwaysLive;
  }
  return analysis;
}

// Is the candidate range compatible with this assignment?
bool isCompatible(const SyncedMemoryRange& candidate,
                  const Assignment& assignment) {
  if (candidate.second.used == kNotUsed ||
      assignment.back().second.used == kNotUsed) {
    return false;
  }
  if (candidate.first->size() <= kMinimumCountForSharing) {
    return false;
  }
  CHECK_GE(assignment.size(), 1);
  return candidate.second.defined > assignment.back().second.used;
};

Analysis<std::vector<std::string>> blobNames(const caffe::Net<float>& net) {
  Analysis<std::vector<std::string>> names;
  const auto& blobs = net.blobs();
  for (auto i = 0; i < blobs.size(); ++i) {
    names[blobs[i]->data().get()].push_back(net.blob_names().at(i));
  }
  return names;
}

// Compute an assignment of blobs to non-overlapping blobs.
Assignments assign(const Net<float>& net, OrderedAnalysis<LiveRange> analysis) {
  const auto& names = blobNames(net);
  std::stable_sort(analysis.begin(),
                   analysis.end(),
                   [](const SyncedMemoryRange& a, const SyncedMemoryRange& b) {
                     return a.second.used < b.second.used;
                   });
  for (const auto& kv : analysis) {
    LOG(INFO) << names.at(kv.first)
              << folly::format(": {}->{}", kv.second.defined, kv.second.used);
  }

  Assignments assignments;
  for (const auto& candidate : analysis) {
    auto assigned = false;
    for (auto& assignment : assignments) {
      if (isCompatible(candidate, assignment)) {
        assignment.push_back(candidate);
        assigned = true;
        break;
      }
    }
    if (assigned) {
      continue;
    }
    assignments.push_back({candidate});
  }
  return assignments;
}

template <typename T>
void logAssignmentMetrics(const OrderedAnalysis<T>& analysis,
                          const Assignments& assignments) {
  size_t beforeTotalSize = 0;
  for (const auto& kv : analysis) {
    beforeTotalSize += kv.first->size();
  }
  size_t afterTotalSize = 0;
  for (const auto& assignment : assignments) {
    size_t assignmentMaxSize = 0;
    for (const auto& kv : assignment) {
      assignmentMaxSize = std::max(assignmentMaxSize, kv.first->size());
    }
    LOG(INFO) << "Assignment max size: " << assignmentMaxSize;
    afterTotalSize += assignmentMaxSize;
  }
  LOG(INFO)
      << folly::format("Before: {}, After: {}, Compression: {:.2f}%",
                       beforeTotalSize,
                       afterTotalSize,
                       100.0 * (1.0 - afterTotalSize * 1.0 / beforeTotalSize));
}

void applyAssignments(caffe::Net<float>* net, const Assignments& assignments) {
  const auto& names = blobNames(*net);
  Analysis<boost::shared_ptr<Blob<float>>> reusedBlobs;
  for (const auto& assignment : assignments) {
    auto reused = boost::make_shared<Blob<float>>(1, 1, 1, 1);
    // Instantiate so blob->data() is valid.
    reused->cpu_data();
    LOG(INFO) << "Assignment: ";
    for (const auto& kv : assignment) {
      LOG(INFO) << "Blob: " << names.at(kv.first);
      reusedBlobs[kv.first] = reused;
    }
  }

  using BV = std::vector<Blob<float>*>;
  using SBV = std::vector<boost::shared_ptr<Blob<float>>>;
  for (auto& blob : const_cast<BV&>(net->input_blobs())) {
    reusedBlobs.at(blob->data().get())->ReshapeLike(*blob);
    blob = reusedBlobs.at(blob->data().get()).get();
  }
  for (auto& blob : const_cast<BV&>(net->output_blobs())) {
    blob = reusedBlobs.at(blob->data().get()).get();
  }
  for (auto& vec : net->top_vecs()) {
    for (auto& blob : const_cast<BV&>(vec)) {
      blob = reusedBlobs.at(blob->data().get()).get();
    }
  }
  for (auto& vec : net->bottom_vecs()) {
    for (auto& blob : const_cast<BV&>(vec)) {
      blob = reusedBlobs.at(blob->data().get()).get();
    }
  }
  for (auto& blob : const_cast<SBV&>(net->blobs())) {
    auto reusedBlob = reusedBlobs.at(blob->data().get());
    blob = reusedBlob;
  }
}
}

void optimizeMemory(caffe::Net<float>* net) {
  net->Reshape();
  // If the net does sharing (e.g. SplitLayer), run a forward pass to
  // get the sharing setup so that it is indentified when we use the
  // SyncedMemory addresses as identifiers for def/use ranges.
  net->ForwardPrefilled();
  const auto& analysis = analyze(*net);
  const auto& assignments = assign(*net, analysis);
  logAssignmentMetrics(analysis, assignments);
  applyAssignments(net, assignments);
}
}
}

max_stars_repo_name: fakeNetflix/facebook-repo-fb-caffe-exts

max_issues_repo_name: fakeNetflix/facebook-repo-fb-caffe-exts

max_forks_repo_name: fakeNetflix/facebook-repo-fb-caffe-exts


text:
/*! \file 1d_full_layout.cpp
    \brief Example of 1 D plot of 3 different STL container types using several layout features.
    \details Creates file 1d_full_layout.svg
    \author Jacob Voytko
*/

// Copyright Jacob Voytko 2007
// Copyright Paul a. Bristow 2020

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

#include <boost/svg_plot/svg_1d_plot.hpp>
// for using namespace boost::svg; // Convenient to access colors and many other svg_plot items.
#include <boost/svg_plot/svg_color.hpp>
// for boost::svg::svg_plot::svg_color

#include <boost/svg_plot/show_1d_settings.hpp>

#include <array> //   using std::array;
#include <vector> // using std::vector;
#include <deque> // using std::deque;
#include <cmath> //  using std::sqrt;

// Some random functions to create the data to plot.
double f(double x)
{
  return std::sqrt(x);
}

double g(double x)
{
  return -2 + x*x;
}

double h(double x)
{
  return -1 + 2*x;
}

int main()
{
  using namespace boost::svg; // Convenient to access colors and many other svg_plot items.
  using boost::svg::svg_color; // Explicitly access SVG colors.
  using boost::svg::svg_1d_plot; // Explicitly access 1D SVG plot.

  try
  {
    // Three containers of different types (just for show):
    std::vector<double> data1;
    std::deque<double> data2;
    std::array<double, 10> data3;

    // Fill the three containers with some randomish data :
    int j = 0;
    for (double i = 0; i < 9.5; i += 1.)
    {
      data1.push_back(f(i));
      data2.push_front(g(i));
      data3[j++] = h(i);
    }

    svg_1d_plot my_plot;

    // Size/scale settings for the plot.
    my_plot.size(500, 200)
      .x_range(-3, 10);

    // Text settings (note chaining 2nd and 3rd settings).
    my_plot.title("Animal Lives")
      .title_font_size(29)
      .x_label_on(true) // Do want to show X-axis label text.
      .x_axis_label_color(white)
      .x_label("life-time (months)");

    // Commands.
    my_plot.legend_on(true) // Do want a legend box - see legend settings below.
      .plot_window_on(true) // Do want the plot in its own window.
      .x_major_labels_side(true);

    // Color settings.
    my_plot.background_color(gray) //
      // or .background_color(svg_color(47, 79, 79)) //  darkslategray in svg_color.hpp
      .legend_background_color(azure)
      .legend_border_color(gold)
      .plot_background_color(lightgoldenrodyellow)
      .title_color(white);

    // Axis settings.
    my_plot.x_major_interval(2)
      .x_major_tick_length(14)
      .x_major_tick_width(1)
      .x_minor_tick_length(7)
      .x_minor_tick_width(1)
      .x_num_minor_ticks(3);

    // Legend settings.
    my_plot.legend_title("Animal")
      .legend_title_font_size(15)
      ;

    // Add the data to the plot:
    my_plot.plot(data1, "Lions").stroke_color(blue);
    my_plot.plot(data2, "Tigers").stroke_color(orange);
    my_plot.plot(data3, "Bears").stroke_color(red);

    // Write the final plot in SVG format.
    my_plot.write("./1d_full_layout.svg");

    using boost::svg::show_1d_plot_settings;
    show_1d_plot_settings(my_plot);
  }
  catch (std::exception& ex)
  { // Report about any exceptions.
    std::cout << "std::exception thown " << ex.what() << std::endl;
  }
  return 0;
} // int main()

// 1d_full_layout.cpp


text:
#pragma once

#include <boost/asio/ssl.hpp>

namespace nexus {

namespace ssl = boost::asio::ssl;

} // namespace nexus

max_stars_repo_name: cbodley/nexus

max_issues_repo_name: cbodley/nexus

max_forks_repo_name: cbodley/nexus


text:
#include <Eigen/Dense>
#include <memory>
#include <iostream>
#include <limits>
#include "bpmfutils.h"
#include "sparsetensor.h"

using namespace Eigen;

std::pair<double,double> eval_rmse_tensor(
		SparseMode & sparseMode,
		const int Nepoch,
		Eigen::VectorXd & predictions,
		Eigen::VectorXd & predictions_var,
		std::vector< std::unique_ptr<Eigen::MatrixXd> > & samples,
		double mean_value)
{
  auto& U = samples[0];

  const int nmodes = samples.size();
  const int num_latents = U->rows();

  const unsigned N = sparseMode.values.size();
  double se = 0.0, se_avg = 0.0;

  if (N == 0) {
    // No test data, returning NaN's
    return std::make_pair(std::numeric_limits<double>::quiet_NaN(),
                          std::numeric_limits<double>::quiet_NaN());
  }

  if (N != predictions.size()) {
    throw std::runtime_error("Ytest.size() and predictions.size() must be equal.");
  }
	if (sparseMode.row_ptr.size() - 1 != U->cols()) {
    throw std::runtime_error("U.cols() and sparseMode size must be equal.");
	}

#pragma omp parallel for schedule(dynamic, 2) reduction(+:se, se_avg)
  for (int n = 0; n < U->cols(); n++) {
    Eigen::VectorXd u = U->col(n);
    for (int j = sparseMode.row_ptr(n);
             j < sparseMode.row_ptr(n + 1);
             j++)
    {
      VectorXi idx = sparseMode.indices.row(j);
      double pred = mean_value;
      for (int d = 0; d < num_latents; d++) {
        double tmp = u(d);

        for (int m = 1; m < nmodes; m++) {
          tmp *= (*samples[m])(d, idx(m - 1));
        }
        pred += tmp;
      }

      double pred_avg;
      if (Nepoch == 0) {
        pred_avg = pred;
      } else {
        double delta = pred - predictions(j);
        pred_avg = (predictions(j) + delta / (Nepoch + 1));
        predictions_var(j) += delta * (pred - pred_avg);
      }
      se     += square(sparseMode.values(j) - pred);
      se_avg += square(sparseMode.values(j) - pred_avg);
      predictions(j) = pred_avg;
    }
  }
  const double rmse = sqrt(se / N);
  const double rmse_avg = sqrt(se_avg / N);
  return std::make_pair(rmse, rmse_avg);
}

max_stars_repo_name: edebrouwer/macau

max_issues_repo_name: edebrouwer/macau

max_forks_repo_name: edebrouwer/macau


text:
/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#include <eos/chain/exceptions.hpp>
#include <fc/io/raw.hpp>
#include <fc/bitutil.hpp>
#include <fc/smart_ref_impl.hpp>
#include <algorithm>

#include <boost/range/adaptor/transformed.hpp>

namespace eosio { namespace chain {

digest_type transaction_digest(const transaction& t) {
   digest_type::encoder enc;
   fc::raw::pack( enc, t );
   return enc.result();
}

void transaction_set_reference_block(transaction& t, const block_id_type& reference_block) {
   t.ref_block_num = fc::endian_reverse_u32(reference_block._hash[0]);
   t.ref_block_prefix = reference_block._hash[1];
}

bool transaction_verify_reference_block(const transaction& t, const block_id_type& reference_block) {
   return t.ref_block_num == (decltype(t.ref_block_num))fc::endian_reverse_u32(reference_block._hash[0]) &&
          t.ref_block_prefix == (decltype(t.ref_block_prefix))reference_block._hash[1];
}

digest_type signed_transaction::sig_digest( const chain_id_type& chain_id )const {
   digest_type::encoder enc;
   fc::raw::pack( enc, chain_id );
   fc::raw::pack( enc, static_cast<const types::transaction&>(*this) );
   return enc.result();
}

eosio::chain::transaction_id_type signed_transaction::id() const {
   auto h = transaction_digest(*this);
   transaction_id_type result;
   memcpy(result._hash, h._hash, std::min(sizeof(result), sizeof(h)));
   return result;
}

const signature_type& eosio::chain::signed_transaction::sign(const private_key_type& key, const chain_id_type& chain_id) {
   signatures.push_back(key.sign_compact(sig_digest(chain_id)));
   return signatures.back();
}

signature_type eosio::chain::signed_transaction::sign(const private_key_type& key, const chain_id_type& chain_id)const {
   return key.sign_compact(sig_digest(chain_id));
}

flat_set<public_key_type> signed_transaction::get_signature_keys( const chain_id_type& chain_id )const
{ try {
   using boost::adaptors::transformed;
   auto SigToKey = transformed([digest = sig_digest(chain_id)](const fc::ecc::compact_signature& signature) {
      return public_key_type(fc::ecc::public_key(signature, digest));
   });
   auto keyRange = signatures | SigToKey;
   return {keyRange.begin(), keyRange.end()};
   } FC_CAPTURE_AND_RETHROW() }

eosio::chain::digest_type signed_transaction::merkle_digest() const {
   digest_type::encoder enc;
   fc::raw::pack(enc, static_cast<const types::transaction&>(*this));
   return enc.result();
}

digest_type generated_transaction::merkle_digest() const {
   digest_type::encoder enc;
   fc::raw::pack(enc, *this);
   return enc.result();
}

} } // eosio::chain

max_stars_repo_name: teddyvgt/eos

max_issues_repo_name: teddyvgt/eos

max_forks_repo_name: teddyvgt/eos


text:
//---------------------------------------------------------------------------//
//!
//! \file   TestNuclearDataProperties.hpp
//! \author Alex Robinson
//! \brief  The data properties class implementation for testing
//!
//---------------------------------------------------------------------------//

#ifndef TEST_NUCLEAR_DATA_PROPERTIES_HPP
#define TEST_NUCLEAR_DATA_PROPERTIES_HPP

// Std Lib Includes
#include <string>

// Boost Includes
#include <boost/filesystem.hpp>

// FRENSIE Includes
#include "Data_NuclearDataProperties.hpp"
#include "Data_AdjointNuclearDataProperties.hpp"
#include "Data_ThermalNuclearDataProperties.hpp"
#include "Data_AdjointThermalNuclearDataProperties.hpp"
#include "Data_PhotonuclearDataProperties.hpp"
#include "Data_AdjointPhotonuclearDataProperties.hpp"
#include "Utility_PhysicalConstants.hpp"

namespace Data{

//! The nuclear data properties test class
template<typename BaseProperties>
class TestNuclearDataProperties : public BaseProperties
{

public:

  //! Default constructor
  TestNuclearDataProperties()
  { /* ... */ }

  //! Constructor
  TestNuclearDataProperties(
                  const Data::ZAID& zaid,
                  const double atomic_weight_ratio,
                  const typename BaseProperties::Energy evaluation_temperature,
                  const typename BaseProperties::FileType file_type,
                  const unsigned version )
    : d_zaid( zaid ),
      d_atomic_weight_ratio( atomic_weight_ratio ),
      d_evaluation_temperature( evaluation_temperature ),
      d_file_type( file_type ),
      d_version( version )
  { /* ... */ }

  //! Destructor
  ~TestNuclearDataProperties()
  { /* ... */ }

  //! Get the ZAID that the file specifies data for
  Data::ZAID zaid() const override
  { return d_zaid; }

  //! Get the atomic weight ratio of the nuclide that the file specifies data for
  double atomicWeightRatio() const override
  { return d_atomic_weight_ratio; }

  //! Get the nuclear data evaluation temperature (MeV)
  typename BaseProperties::Energy evaluationTemperatureInMeV() const override
  { return d_evaluation_temperature; }

  //! Get the nuclear data evaluation temperature (Kelvin)
  typename BaseProperties::Temperature evaluationTemperature() const
  { return d_evaluation_temperature/Utility::PhysicalConstants::boltzmann_constant_q; }

  //! Get the nuclear data file type
  typename BaseProperties::FileType fileType() const override
  { return d_file_type; }

  //! Get the nuclear data file path (relative to the data directory)
  boost::filesystem::path filePath() const override
  { return boost::filesystem::current_path(); }

  //! Get the nuclear data file start line
  size_t fileStartLine() const override
  { return 0; }

  //! Get the nuclear data file version
  unsigned fileVersion() const override
  { return d_version; }

  //! Get the nuclear data file major version
  unsigned fileMajorVersion() const
  { return d_version; }

  //! Get the nuclear data file table name
  std::string tableName() const override
  { return "test"; }

  //! Clone the properties
  TestNuclearDataProperties* clone() const override
  {
    return new TestNuclearDataProperties( d_zaid,
                                          d_atomic_weight_ratio,
                                          d_evaluation_temperature,
                                          d_file_type,
                                          d_version );
  }

private:

  // Save the properties to an archive
  template<typename Archive>
  void serialize( Archive& ar, const unsigned version )
  {
    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( BaseProperties );
    ar & BOOST_SERIALIZATION_NVP( d_zaid );
    ar & BOOST_SERIALIZATION_NVP( d_atomic_weight_ratio );
    ar & BOOST_SERIALIZATION_NVP( d_evaluation_temperature );
    ar & BOOST_SERIALIZATION_NVP( d_file_type );
    ar & BOOST_SERIALIZATION_NVP( d_version );
  }

  // Declare the boost serialization access object as a friend
  friend class boost::serialization::access;

  // The zaid
  Data::ZAID d_zaid;

  // The atomic weight ratio
  double d_atomic_weight_ratio;

  // The evaluation temperature
  typename BaseProperties::Energy d_evaluation_temperature;

  // The file type
  typename BaseProperties::FileType d_file_type;

  // The file version
  unsigned d_version;
};

} // end Data namespace

BOOST_SERIALIZATION_CLASS_VERSION( TestNuclearDataProperties<Data::NuclearDataProperties>, Data, 0 );
BOOST_SERIALIZATION_CLASS_EXPORT_STANDARD_KEY( TestNuclearDataProperties<Data::NuclearDataProperties>, Data );
BOOST_SERIALIZATION_CLASS_EXPORT_IMPLEMENT( TestNuclearDataProperties<Data::NuclearDataProperties>, Data );

BOOST_SERIALIZATION_CLASS_VERSION( TestNuclearDataProperties<Data::AdjointNuclearDataProperties>, Data, 0 );
BOOST_SERIALIZATION_CLASS_EXPORT_STANDARD_KEY( TestNuclearDataProperties<Data::AdjointNuclearDataProperties>, Data );
BOOST_SERIALIZATION_CLASS_EXPORT_IMPLEMENT( TestNuclearDataProperties<Data::AdjointNuclearDataProperties>, Data );

namespace Data{

//! The nuclear data properties test class
template<typename BaseProperties>
class TestThermalNuclearDataProperties : public BaseProperties
{

public:

  //! Default constructor
  TestThermalNuclearDataProperties()
  { /* ... */ }

  //! Constructor
  TestThermalNuclearDataProperties(
                  const std::string& name,
                  const std::set<Data::ZAID>& zaids,
                  const typename BaseProperties::Energy evaluation_temperature,
                  const typename BaseProperties::FileType file_type,
                  const unsigned version )
    : d_name( name ),
      d_zaids( zaids ),
      d_evaluation_temperature( evaluation_temperature ),
      d_file_type( file_type ),
      d_version( version )
  { /* ... */ }

  //! Destructor
  ~TestThermalNuclearDataProperties()
  { /* ... */ }

  //! Get the name of the properties
  std::string name() const override
  { return d_name; }

  //! Check if the file specifies data for the ZAID of interest
  bool hasDataForZAID( const Data::ZAID& zaid ) const override
  { return d_zaids.find( zaid ) != d_zaids.end(); }

  //! Get the ZAIDS that the file specifies data for
  std::set<Data::ZAID> zaids() const override
  { return d_zaids; }

  //! Get the nuclear data evaluation temperature (MeV)
  typename BaseProperties::Energy evaluationTemperatureInMeV() const override
  { return d_evaluation_temperature; }

  //! Get the nuclear data evaluation temperature (Kelvin)
  typename BaseProperties::Temperature evaluationTemperature() const
  { return d_evaluation_temperature/Utility::PhysicalConstants::boltzmann_constant_q; }

  //! Get the nuclear data file type
  typename BaseProperties::FileType fileType() const override
  { return d_file_type; }

  //! Get the nuclear data file path (relative to the data directory)
  boost::filesystem::path filePath() const override
  { return boost::filesystem::current_path(); }

  //! Get the nuclear data file start line
  size_t fileStartLine() const override
  { return 0; }

  //! Get the nuclear data file version
  unsigned fileVersion() const override
  { return d_version; }

  //! Get the nuclear data file table name
  std::string tableName() const override
  { return "test"; }

  //! Clone the properties
  TestThermalNuclearDataProperties* clone() const override
  {
    return new TestThermalNuclearDataProperties( d_name,
                                                 d_zaids,
                                                 d_evaluation_temperature,
                                                 d_file_type,
                                                 d_version );
  }

private:

  // Save the properties to an archive
  template<typename Archive>
  void serialize( Archive& ar, const unsigned version )
  {
    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( BaseProperties );
    ar & BOOST_SERIALIZATION_NVP( d_name );
    ar & BOOST_SERIALIZATION_NVP( d_zaids );
    ar & BOOST_SERIALIZATION_NVP( d_evaluation_temperature );
    ar & BOOST_SERIALIZATION_NVP( d_file_type );
    ar & BOOST_SERIALIZATION_NVP( d_version );
  }

  // Declare the boost serialization access object as a friend
  friend class boost::serialization::access;

  // The name
  std::string d_name;

  // The zaids
  std::set<Data::ZAID> d_zaids;

  // The evaluation temperature
  typename BaseProperties::Energy d_evaluation_temperature;

  // The file type
  typename BaseProperties::FileType d_file_type;

  // The file version
  unsigned d_version;
};

} // end Data namespace

BOOST_SERIALIZATION_CLASS_VERSION( TestThermalNuclearDataProperties<Data::ThermalNuclearDataProperties>, Data, 0 );
BOOST_SERIALIZATION_CLASS_EXPORT_STANDARD_KEY( TestThermalNuclearDataProperties<Data::ThermalNuclearDataProperties>, Data );
BOOST_SERIALIZATION_CLASS_EXPORT_IMPLEMENT( TestThermalNuclearDataProperties<Data::ThermalNuclearDataProperties>, Data );

BOOST_SERIALIZATION_CLASS_VERSION( TestThermalNuclearDataProperties<Data::AdjointThermalNuclearDataProperties>, Data, 0 );
BOOST_SERIALIZATION_CLASS_EXPORT_STANDARD_KEY( TestThermalNuclearDataProperties<Data::AdjointThermalNuclearDataProperties>, Data );
BOOST_SERIALIZATION_CLASS_EXPORT_IMPLEMENT( TestThermalNuclearDataProperties<Data::AdjointThermalNuclearDataProperties>, Data );

namespace Data{

//! The nuclear data properties test class
template<typename BaseProperties>
class TestPhotonuclearDataProperties : public BaseProperties
{

public:

  //! Default constructor
  TestPhotonuclearDataProperties()
  { /* ... */ }

  //! Constructor
  TestPhotonuclearDataProperties(
                  const Data::ZAID& zaid,
                  const double atomic_weight_ratio,
                  const typename BaseProperties::FileType file_type,
                  const unsigned version )
    : d_zaid( zaid ),
      d_atomic_weight_ratio( atomic_weight_ratio ),
      d_file_type( file_type ),
      d_version( version )
  { /* ... */ }

  //! Destructor
  ~TestPhotonuclearDataProperties()
  { /* ... */ }

  //! Get the ZAID that the file specifies data for
  Data::ZAID zaid() const override
  { return d_zaid; }

  //! Get the atomic weight of the nuclide that the file specifies data for
  typename BaseProperties::AtomicWeight atomicWeight() const override
  { return d_atomic_weight_ratio*Utility::PhysicalConstants::neutron_rest_mass_amu_q; }

  //! Get the nuclear data file type
  typename BaseProperties::FileType fileType() const override
  { return d_file_type; }

  //! Get the nuclear data file path (relative to the data directory)
  boost::filesystem::path filePath() const override
  { return boost::filesystem::current_path(); }

  //! Get the nuclear data file start line
  size_t fileStartLine() const override
  { return 0; }

  //! Get the nuclear data file version
  unsigned fileVersion() const override
  { return d_version; }

  //! Get the nuclear data file table name
  std::string tableName() const override
  { return "test"; }

  //! Clone the properties
  TestPhotonuclearDataProperties* clone() const override
  {
    return new TestPhotonuclearDataProperties( d_zaid,
                                               d_atomic_weight_ratio,
                                               d_file_type,
                                               d_version );
  }

private:

  // Save the properties to an archive
  template<typename Archive>
  void serialize( Archive& ar, const unsigned version )
  {
    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( BaseProperties );
    ar & BOOST_SERIALIZATION_NVP( d_zaid );
    ar & BOOST_SERIALIZATION_NVP( d_atomic_weight_ratio );
    ar & BOOST_SERIALIZATION_NVP( d_file_type );
    ar & BOOST_SERIALIZATION_NVP( d_version );
  }

  // Declare the boost serialization access object as a friend
  friend class boost::serialization::access;

  // The zaid
  Data::ZAID d_zaid;

  // The atomic weight ratio
  double d_atomic_weight_ratio;

  // The file type
  typename BaseProperties::FileType d_file_type;

  // The version
  unsigned d_version;
};

} // end Data namespace

BOOST_SERIALIZATION_CLASS_VERSION( TestPhotonuclearDataProperties<Data::PhotonuclearDataProperties>, Data, 0 );
BOOST_SERIALIZATION_CLASS_EXPORT_STANDARD_KEY( TestPhotonuclearDataProperties<Data::PhotonuclearDataProperties>, Data );
BOOST_SERIALIZATION_CLASS_EXPORT_IMPLEMENT( TestPhotonuclearDataProperties<Data::PhotonuclearDataProperties>, Data );

BOOST_SERIALIZATION_CLASS_VERSION( TestPhotonuclearDataProperties<Data::AdjointPhotonuclearDataProperties>, Data, 0 );
BOOST_SERIALIZATION_CLASS_EXPORT_STANDARD_KEY( TestPhotonuclearDataProperties<Data::AdjointPhotonuclearDataProperties>, Data );
BOOST_SERIALIZATION_CLASS_EXPORT_IMPLEMENT( TestPhotonuclearDataProperties<Data::AdjointPhotonuclearDataProperties>, Data );

#endif // end TEST_NUCLEAR_DATA_PROPERTIES_HPP

//---------------------------------------------------------------------------//
// end TestNuclearDataProperties.hpp
//---------------------------------------------------------------------------//


text:
#include "ZstStageSession.h"
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include "../core/transports/ZstStageTransport.h"

using namespace boost::uuids;
using namespace flatbuffers;

namespace showtime {

ZstStageSession::ZstStageSession() : m_hierarchy(std::make_shared<ZstStageHierarchy>())
{
}

ZstStageSession::~ZstStageSession()
{
	//ZstCableBundle bundle;
	//for (auto cable : get_cables(bundle)) {
	//	destroy_cable(cable);
	//}
}

void ZstStageSession::process_events()
{
	ZstSession::process_events();
	ZstStageModule::process_events();
	hierarchy()->process_events();
}

void ZstStageSession::set_wake_condition(std::shared_ptr<ZstSemaphore>& condition)
{
	ZstStageModule::set_wake_condition(condition);
	m_hierarchy->set_wake_condition(condition);
	session_events()->set_wake_condition(condition);
	synchronisable_events()->set_wake_condition(condition);
}

void ZstStageSession::on_receive_msg(const std::shared_ptr<ZstStageMessage>& msg)
{
	Signal response = Signal_EMPTY;
	ZstPerformerStageProxy* sender = m_hierarchy->get_client_from_endpoint_UUID(msg->origin_endpoint_UUID());

	//Check client hasn't finished joining yet
	if (!sender)
		return;

	switch (msg->type()) {
	case Content_SignalMessage:
		response = signal_handler(msg, sender);
		break;
	case Content_CableCreateRequest:
		response = create_cable_handler(msg, sender);
		break;
	case Content_CableDestroyRequest:
		response = destroy_cable_handler(msg);
		break;
	case Content_EntityObserveRequest:
		response = observe_entity_handler(msg, sender);
		break;
	case Content_EntityTakeOwnershipRequest:
		response = aquire_entity_ownership_handler(msg, sender);
		break;
	default:
		break;
	}

	//Return response to sender
	if (response != Signal_EMPTY) {
		ZstTransportArgs args;
		args.target_endpoint_UUID = msg->origin_endpoint_UUID();
		args.msg_ID = msg->id();
		auto builder = std::make_shared< FlatBufferBuilder>();
		auto signal_offset = CreateSignalMessage(*builder, response);
		if (auto transport = std::dynamic_pointer_cast<ZstStageTransport>(msg->owning_transport()))
			transport->send_msg(Content_SignalMessage, signal_offset.Union(), builder, args);
	}
}

Signal ZstStageSession::signal_handler(const std::shared_ptr<ZstStageMessage>& msg, ZstPerformerStageProxy* sender)
{
	auto request = msg->buffer()->content_as_SignalMessage();

	if (!sender) {
		return Signal_ERR_STAGE_PERFORMER_NOT_FOUND;
	}

	switch (request->signal()) {
	case Signal_CLIENT_SYNC:
		return synchronise_client_graph_handler(sender);
		break;
	}

	return Signal_EMPTY;
}

Signal ZstStageSession::synchronise_client_graph_handler(ZstPerformerStageProxy* sender)
{
	Log::server(Log::Level::notification, "Sending graph snapshot to {}", sender->URI().path());

	// For serialisation later
	auto builder = std::make_shared<FlatBufferBuilder>();
	std::vector< flatbuffers::Offset<void> > entity_vec;
	std::vector< uint8_t> entity_types_vec;

	ZstEntityBundle entity_bundle;
	ZstEntityBundle performer_bundle;
	hierarchy()->get_performers(performer_bundle);

	// Pack all entities
	for (auto performer : performer_bundle) {
		//Only pack performers that aren't the destination client
		if (performer->URI() != sender->URI()) {
			performer->get_child_entities(&entity_bundle, true, true);
		}
	}

	if (entity_bundle.size()) {
		for (auto entity : entity_bundle) {
			auto batch_entity_offset = CreateEntityCreateRequest(*builder, entity->serialized_entity_type(), entity->serialize(*builder));
			stage_hierarchy()->whisper(sender, Content_EntityCreateRequest, batch_entity_offset.Union(), builder, ZstTransportArgs());
		}
	}

	// Pack all cables
	// Create a new buffer builder
	if (m_cables.size()) {
		builder = std::make_shared<FlatBufferBuilder>();
		for (auto const& cable : m_cables) {
			auto batch_cable_offset = CreateCableCreateRequest(*builder, cable->get_address().serialize(*builder));
			stage_hierarchy()->whisper(sender, Content_CableCreateRequest, batch_cable_offset.Union(), builder, ZstTransportArgs());
		}

	}
	return Signal_OK;
}

Signal ZstStageSession::create_cable_handler(const std::shared_ptr<ZstStageMessage>& msg, ZstPerformerStageProxy* sender)
{
	auto request = msg->buffer();
	auto cable_request = request->content_as_CableCreateRequest();

	//Unpack cable from message
	auto input_path = ZstURI(cable_request->cable()->address()->input_URI()->c_str(), cable_request->cable()->address()->input_URI()->size());
	auto output_path = ZstURI(cable_request->cable()->address()->output_URI()->c_str(), cable_request->cable()->address()->output_URI()->size());
	auto cable_path = ZstCableAddress(input_path, output_path);
	Log::server(Log::Level::notification, "Received connect cable request for In:{} and Out:{}", cable_path.get_input_URI().path(), cable_path.get_output_URI().path());

	//Make sure cable doesn't already exist
	if (find_cable(cable_path)) {
		Log::server(Log::Level::warn, "Cable {}<-{} already exists", input_path.path(), output_path.path());
		return Signal_ERR_STAGE_BAD_CABLE_CONNECT_REQUEST;
	}

	//Verify plugs will accept cable
	ZstInputPlug* input = dynamic_cast<ZstInputPlug*>(hierarchy()->find_entity(input_path));
	ZstOutputPlug* output = dynamic_cast<ZstOutputPlug*>(hierarchy()->find_entity(output_path));
	if (!input || !output) {
		return Signal_ERR_CABLE_PLUGS_NOT_FOUND;
	}

	//Unplug existing cables if we hit max cables in an input plug
	if (input->num_cables() >= input->max_connected_cables()) {
		Log::server(Log::Level::warn, "Too many cables in plug. Disconnecting existing cables");
		ZstCableBundle bundle;
		input->get_child_cables(&bundle);
		for (auto cable : bundle) {
			destroy_cable(cable);
		}
	}

	//Create our local cable ptr
	auto cable_ptr = create_cable(input, output);
	if (!cable_ptr) {
		return Signal_ERR_STAGE_BAD_CABLE_CONNECT_REQUEST;
	}

	//Start the client connection
	auto input_perf = dynamic_cast<ZstPerformerStageProxy*>(hierarchy()->find_entity(input->URI().first()));
	auto output_perf = dynamic_cast<ZstPerformerStageProxy*>(hierarchy()->find_entity(output->URI().first()));

	auto connect_finished_cb = [this, cable_ptr, sender, id = msg->id()](Signal signal) {
		if (signal == Signal_OK) {
			Log::server(Log::Level::notification, "Client connection complete. Publishing cable {}", cable_ptr->get_address().to_string());
			ZstTransportArgs args;
			auto builder = std::make_shared<FlatBufferBuilder>();

			// Publish cable
			auto cable_create_offset = CreateCableCreateRequest(*builder, cable_ptr->get_address().serialize(*builder));
			stage_hierarchy()->broadcast(Content_CableCreateRequest, cable_create_offset.Union(), builder, args);
		}

		// Let original requestor know the request was completed
		stage_hierarchy()->reply_with_signal(sender, signal, id);
	};

	auto connect_response_cb = [this, cable_ptr, sender, id = msg->id(), connect_finished_cb](ZstMessageResponse response) {
		connect_finished_cb(ZstStageTransport::get_signal(response.response));
	};

	// If both the input and output performer are the same then messages will be routed internally for that client
	if (output_perf->URI() == input_perf->URI())
		connect_finished_cb(Signal_OK);
	else
		connect_clients(output_perf, input_perf, connect_response_cb);

	return Signal_EMPTY;
}

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

Signal ZstStageSession::observe_entity_handler(const std::shared_ptr<ZstStageMessage>& msg, ZstPerformerStageProxy* sender)
{
	//Get target performer
	auto request = msg->buffer();
	auto observe_request = request->content_as_EntityObserveRequest();
	auto performer_path = ZstURI(observe_request->URI()->c_str(), observe_request->URI()->size());
	ZstPerformerStageProxy* observed_performer = dynamic_cast<ZstPerformerStageProxy*>(hierarchy()->find_entity(performer_path.first()));
	if (!observed_performer) {
		return Signal_ERR_STAGE_PERFORMER_NOT_FOUND;
	}

	Log::server(Log::Level::notification, "Received observation request. Requestor: {}, Observed: {}", sender->URI().path(), observed_performer->URI().path());
	if (sender == observed_performer) {
		Log::server(Log::Level::warn, "Client attempting to observe itself");
		return Signal_ERR_STAGE_PERFORMER_ALREADY_CONNECTED;
	}

	//Check to see if one client is already connected to the other
	if (observed_performer->has_connected_subscriber(sender)) {
		Log::server(Log::Level::warn, "Client {} already observing {}", sender->URI().path(), observed_performer->URI().path());
		return Signal_ERR_STAGE_PERFORMER_ALREADY_CONNECTED;
	}

	//Check to see if one client is already connected to the other
	if (!observed_performer->has_connected_subscriber(sender)) {
		//Start the client connection
		connect_clients(observed_performer, sender, [this, sender, response_id = msg->id()](ZstMessageResponse response) {
			auto signal = ZstStageTransport::get_signal(response.response);
			stage_hierarchy()->reply_with_signal(sender, signal, response_id);
		});
		return Signal_EMPTY;
	}

	return Signal_OK;
}

Signal ZstStageSession::aquire_entity_ownership_handler(const std::shared_ptr<ZstStageMessage>& msg, ZstPerformerStageProxy* sender)
{
	auto request = msg->buffer()->content_as_EntityTakeOwnershipRequest();
	auto entity_path = ZstURI(request->URI()->c_str(), request->URI()->size());
	ZstEntityBase* entity = hierarchy()->find_entity(entity_path);

	if (!entity) {
		Log::server(Log::Level::warn, "Could not aquire entity ownership - entity {}, not found", entity_path.path());
		return Signal_ERR_ENTITY_NOT_FOUND;
	}

	ZstURI new_owner_path;
	ZstPerformerStageProxy* new_owner = NULL;

	// An empty owner means we return ownership back to the original owner
	if (!request->new_owner()->size()){
		entity_set_owner(entity, "");
	}
	else {
		new_owner_path = ZstURI(request->new_owner()->c_str(), request->new_owner()->size());
		new_owner = dynamic_cast<ZstPerformerStageProxy*>(hierarchy()->find_entity(new_owner_path));
		if (!new_owner) {
			Log::server(Log::Level::warn, "Could not aquire entity ownership - could not find new owner {}", new_owner_path.path());
			return Signal_ERR_STAGE_PERFORMER_NOT_FOUND;
		}

		Log::server(Log::Level::notification, "Received entity ownership aquistion request - {} wants to control {}", new_owner_path.path(), entity->URI().path());

		//Set owner
		entity_set_owner(entity, new_owner->URI());
	}

	// We need to connect downstream plugs to the new sender
	ZstCableBundle bundle;
	get_cables(bundle);

	//Find all performers that have input connections to this output plug
	std::unordered_map<ZstURI, ZstPerformerStageProxy*, ZstURIHash> performers;
	for (auto c : bundle) {
		if (c->get_output()->URI() == entity->URI()) {
			auto receiver = dynamic_cast<ZstPerformerStageProxy*>(hierarchy()->find_entity(c->get_input()->URI().first()));
			performers[receiver->URI()] = receiver;
		}
	}

	//Connect performers together that will have to update their subscriptions
	for (auto receiver : performers) {
		if (!new_owner_path.is_empty()) {
			connect_clients(receiver.second, new_owner);
		}
	}

	//Broadcast change in plug fire control
	Log::server(Log::Level::notification, "Broadcasting entity ownership - {} controls {}", new_owner_path.path(), entity->URI().path());
	ZstTransportArgs args;
	auto builder = std::make_shared<FlatBufferBuilder>();
	auto ownership_offset = CreateEntityTakeOwnershipRequest(*builder, builder->CreateString(entity->URI().path()), builder->CreateString(new_owner_path.path()));
	stage_hierarchy()->broadcast(Content_EntityTakeOwnershipRequest, ownership_offset.Union(), builder, args);

	return Signal_OK;
}

Signal ZstStageSession::destroy_cable_handler(const std::shared_ptr<ZstStageMessage>& msg)
{
	auto request = msg->buffer()->content_as_CableDestroyRequest();

	auto cable_path = ZstCableAddress(request->cable());
	Log::server(Log::Level::notification, "Received destroy cable connection request");

	ZstCable* cable_ptr = find_cable(cable_path);
	destroy_cable(cable_ptr);

	return Signal_OK;
}

void ZstStageSession::on_performer_leaving(const ZstURI& performer_path)
{
	disconnect_cables(m_hierarchy->find_entity(performer_path));
}

void ZstStageSession::on_entity_leaving(const ZstURI& entity_path)
{
	disconnect_cables(m_hierarchy->find_entity(entity_path));
}

void ZstStageSession::disconnect_cables(ZstEntityBase* entity)
{
	if (!entity)
		return;

	ZstCableBundle bundle;
 	entity->get_child_cables(&bundle);
	for (auto cable : bundle) {
		destroy_cable(cable);
	}
}

void ZstStageSession::destroy_cable(ZstCable* cable) {
	if (!cable)
		return;

	Log::server(Log::Level::notification, "Destroying cable {}", cable->get_address().to_string());

	//Update rest of network
	ZstTransportArgs args;
	auto builder = std::make_shared<FlatBufferBuilder>();
	auto destroy_cable_data_offset = CreateCableData(*builder, builder->CreateString(cable->get_address().get_input_URI().path()), builder->CreateString(cable->get_address().get_output_URI().path()));
	auto destroy_cable_offset = CreateCableDestroyRequest(*builder, CreateCable(*builder, destroy_cable_data_offset));
	stage_hierarchy()->broadcast(Content_CableDestroyRequest, destroy_cable_offset.Union(), builder, args);

	//Remove cable
	ZstSession::destroy_cable_complete(cable);
}

void ZstStageSession::connect_clients(ZstPerformerStageProxy* output_client, ZstPerformerStageProxy* input_client)
{
	connect_clients(output_client, input_client, [](ZstMessageResponse response) {});
}

void ZstStageSession::connect_clients(ZstPerformerStageProxy* output_client, ZstPerformerStageProxy* input_client, const ZstMessageReceivedAction& on_msg_received)
{
	Log::server(Log::Level::notification, "Sending P2P subscribe request to {}", input_client->URI().path());

	//Check to see if one client is already connected to the other
	if (output_client->has_connected_subscriber(input_client)) {
		return;
	}

	//If the output and input clients are the same, then plug messages will be routed internally
	if (output_client->URI() == input_client->URI()) {
		return;
	}

	//Create request for receiver
	auto output_address = output_client->URI();
	auto input_address = input_client->URI();
	ZstTransportArgs receiver_args;
	receiver_args.msg_send_behaviour = ZstTransportRequestBehaviour::ASYNC_REPLY;
	receiver_args.on_recv_response = [this, output_client, output_address, input_client, input_address, on_msg_received](ZstMessageResponse response) {
		if (ZstStageTransport::verify_signal(response.response, Signal_OK, fmt::format("P2P client connection ({} --> {})", output_address.path(), input_address.path()))) {
			complete_client_connection(output_client, input_client);
			on_msg_received(response);
		}
	};

	auto builder = std::make_shared<FlatBufferBuilder>();
	auto subscribe_offset = CreateClientGraphHandshakeListen(*builder, builder->CreateString(output_client->URI().path()), builder->CreateString(output_client->reliable_address()));

	Log::net(Log::Level::debug, "Sending Content_ClientGraphHandshakeListen whisper to {}", input_client->URI().path());
	stage_hierarchy()->whisper(input_client, Content_ClientGraphHandshakeListen, subscribe_offset.Union(), builder, receiver_args);

	//Create request for broadcaster - needs a new buffer builder
	auto broadcaster_builder = std::make_shared<FlatBufferBuilder>();
	auto broadcast_offset = CreateClientGraphHandshakeStart(
		*broadcaster_builder,
		broadcaster_builder->CreateString(input_client->URI().path(), input_client->URI().full_size()),
		broadcaster_builder->CreateString(input_client->reliable_address())
	);
	ZstTransportArgs broadcaster_args;
	stage_hierarchy()->whisper(output_client, Content_ClientGraphHandshakeStart, broadcast_offset.Union(), broadcaster_builder, broadcaster_args);
}

Signal ZstStageSession::complete_client_connection(ZstPerformerStageProxy* output_client, ZstPerformerStageProxy* input_client)
{
	Log::server(Log::Level::notification, "Completing client handshake. Pub: {}, Sub: {}", output_client->URI().path(), input_client->URI().path());

	//Keep a record of which clients are connected to each other
	output_client->add_subscriber(input_client);

	//Let the broadcaster know it can stop publishing messages
	Log::server(Log::Level::notification, "Stopping P2P handshake broadcast from client {}", output_client->URI().path());
	ZstTransportArgs args;
	auto builder = std::make_shared<FlatBufferBuilder>();
	auto stop_offset = CreateClientGraphHandshakeStop(*builder, builder->CreateString(input_client->URI().path()) );
	stage_hierarchy()->whisper(output_client, Content_ClientGraphHandshakeStop, stop_offset.Union(), builder, args);

	return Signal_OK;
}

std::shared_ptr<ZstHierarchy> ZstStageSession::hierarchy()
{
	return m_hierarchy;
}

std::shared_ptr<ZstStageHierarchy> ZstStageSession::stage_hierarchy()
{
	return m_hierarchy;
}

}

max_stars_repo_name: Mystfit/Showtime-Cpp

max_issues_repo_name: Mystfit/Showtime-Cpp

max_forks_repo_name: Mystfit/Showtime-Cpp