<commit_before>//  (C) Copyright Gennadiy Rozental 2001-2005.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER

// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/test/test_observer.hpp>

// Boost
#include <boost/shared_ptr.hpp>

// STL
#include <string>   // for std::string
#include <list>     // for std::list
#include <vector>   // for std::vector

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************                   test_unit                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit {
public:
    enum { type = tut_any };

    // Constructor
    test_unit( const_string tu_name, test_unit_type t );

    // dependencies management
    void    depends_on( test_unit* tu );
    bool    check_dependencies() const;

    // Public r/o properties
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl))  id_t;
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite))      parent_id_t;
    readonly_property<test_unit_type>   p_type;                 // type for this test unit
    readonly_property<const_string>     p_type_name;            // "case"/"suite"
    id_t                                p_id;                   // unique id for this test unit
    parent_id_t                         p_parent_id;            // parent test suite id

    // Public r/w properties
    readwrite_property<std::string>     p_name;                 // name for this test unit
    readwrite_property<unsigned>        p_timeout;              // timeout for the test unit execution
    readwrite_property<counter_t>       p_expected_failures;    // number of expected failures in this test unit
    mutable readwrite_property<bool>    p_enabled;              // enabled status for this unit

    void                                increase_exp_fail( unsigned num );

private:
    // Data members
    std::list<test_unit_id>             m_dependencies;
};

// ************************************************************************** //
// **************              test_case_generator             ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit_generator {
public:
    virtual test_unit*  next() const = 0;

protected:
    BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
};

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_case : public test_unit {
public:
    enum { type = tut_case };

    // Constructor
    test_case( const_string tc_name, callback0<> const& test_func );

    // Access methods
    callback0<> const&  test_func() const { return m_test_func; }

private:
    friend class framework_impl;
    ~test_case() {}

    // BOOST_MSVC <= 1200 have problems with callback as property
    // Data members
    callback0<> m_test_func;
};

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_suite : public test_unit {
public:
    enum { type = tut_suite };

    // Constructor
    explicit        test_suite( const_string ts_name );

    // test unit list management
    void            add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
    void            add( test_unit_generator const& gen, unsigned timeout = 0 );
    void            remove( test_unit_id id );

    // access methods
    test_unit_id    get( const_string tu_name ) const;
    std::size_t     size() const { return m_members.size(); }

protected:
    friend BOOST_TEST_DECL
    void        traverse_test_tree( test_suite const&, test_tree_visitor& );
    friend class framework_impl;
    virtual     ~test_suite() {}

    // Data members
    std::vector<test_unit_id> m_members;
};

// ************************************************************************** //
// **************               master_test_suite              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL master_test_suite_t : public test_suite {
public:
    master_test_suite_t() : test_suite( "Master Test Suite" )
    , argc( 0 )
    , argv( 0 )
    {}

    // Data members
    int      argc;
    char**   argv;
};

// ************************************************************************** //
// **************               test_tree_visitor              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_tree_visitor {
public:
    // test tree visitor interface
    virtual void    visit( test_case const& )               {}
    virtual bool    test_suite_start( test_suite const& )   { return true; }
    virtual void    test_suite_finish( test_suite const& )  {}

protected:
    BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
};

// ************************************************************************** //
// **************               traverse_test_tree             ************** //
// ************************************************************************** //

BOOST_TEST_DECL void    traverse_test_tree( test_case const&, test_tree_visitor& );
BOOST_TEST_DECL void    traverse_test_tree( test_suite const&, test_tree_visitor& );
BOOST_TEST_DECL void    traverse_test_tree( test_unit_id     , test_tree_visitor& );

//____________________________________________________________________________//

inline void
traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
{
    if( tu.p_type == tut_case )
        traverse_test_tree( static_cast<test_case const&>( tu ), V );
    else
        traverse_test_tree( static_cast<test_suite const&>( tu ), V );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                test_case_counter             ************** //
// ************************************************************************** //

class test_case_counter : public test_tree_visitor {
public:
    // Constructor
    test_case_counter() : p_count( 0 ) {}

    BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
private:
    // test tree visitor interface
    virtual void    visit( test_case const& );
    virtual bool    test_suite_start( test_suite const& ts )    { return ts.p_enabled; }
};

// ************************************************************************** //
// **************               test_being_aborted             ************** //
// ************************************************************************** //

struct BOOST_TEST_DECL test_being_aborted {};

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

namespace ut_detail {

BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );

template<typename UserTestCase>
struct user_tc_method_invoker {
    typedef void (UserTestCase::*test_method )();

    user_tc_method_invoker( shared_ptr<UserTestCase> inst, test_method test_method )
    : m_inst( inst ), m_test_method( test_method ) {}

    void operator()() { ((*m_inst).*m_test_method)(); }

    shared_ptr<UserTestCase> m_inst;
    test_method              m_test_method;
};

} // namespace ut_detail

//____________________________________________________________________________//

inline test_case*
make_test_case( callback0<> const& test_func, const_string tc_name )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
}

//____________________________________________________________________________//

template<typename UserTestCase>
inline test_case*
make_test_case( void (UserTestCase::*test_method )(),
                  const_string tc_name,
                  boost::shared_ptr<UserTestCase> const& user_test_case )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ),
                          ut_detail::user_tc_method_invoker<UserTestCase>( user_test_case, test_method ) );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************           auto_test_unit_registrar           ************** //
// ************************************************************************** //

namespace ut_detail {

struct BOOST_TEST_DECL auto_test_unit_registrar
{
    // Constructors
                auto_test_unit_registrar( test_case* tc, counter_t exp_fail );
    explicit    auto_test_unit_registrar( const_string ts_name );
    explicit    auto_test_unit_registrar( test_unit_generator const& tc_gen );
    explicit    auto_test_unit_registrar( int );

private:
    static std::list<test_suite*>& curr_ts_store();
};

//____________________________________________________________________________//

template<typename T>
struct auto_tc_exp_fail {
    auto_tc_exp_fail() : m_value( 0 ) {}

    explicit    auto_tc_exp_fail( unsigned v )
    : m_value( v )
    {
        instance() = this;
    }

    static auto_tc_exp_fail*& instance()
    {
        static auto_tc_exp_fail     inst;
        static auto_tc_exp_fail*    inst_ptr = &inst;

        return inst_ptr;
    }

    unsigned    value() const { return m_value; }

private:
    // Data members
    unsigned    m_value;
};

//____________________________________________________________________________//

} // namespace ut_detail

// ************************************************************************** //
// **************                global_fixture                ************** //
// ************************************************************************** //

class BOOST_TEST_DECL global_fixture : public test_observer {
public:
    // Constructor
    global_fixture();
};

//____________________________________________________________________________//

namespace ut_detail {

template<typename F>
struct global_fixture_impl : public global_fixture {
    // Constructor
    global_fixture_impl(): m_fixure( 0 )    {}

    // test observer interface
    virtual void    test_start( counter_t ) { m_fixure = new F; }
    virtual void    test_finish()           { delete m_fixure; m_fixure = 0; }
    virtual void    test_aborted()          { delete m_fixure; m_fixure = 0; }

private:
    // Data members
    F*  m_fixure;
};

} // namespace ut_detail

} // unit_test

} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.2  2006/01/28 07:09:34  rogeeff
//  tm->test_method
//
//  Revision 1.1  2005/12/14 05:24:55  rogeeff
//  dll support introduced
//  split into 2 files
//
// ***************************************************************************

#endif // BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER

<commit_msg>issue with class base test cases addressed<commit_after>//  (C) Copyright Gennadiy Rozental 2001-2007.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER

// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/test/test_observer.hpp>

// Boost
#include <boost/shared_ptr.hpp>

// STL
#include <string>   // for std::string
#include <list>     // for std::list
#include <vector>   // for std::vector

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************                   test_unit                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit {
public:
    enum { type = tut_any };

    // Constructor
    test_unit( const_string tu_name, test_unit_type t );

    // dependencies management
    void    depends_on( test_unit* tu );
    bool    check_dependencies() const;

    // Public r/o properties
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl))  id_t;
    typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite))      parent_id_t;
    readonly_property<test_unit_type>   p_type;                 // type for this test unit
    readonly_property<const_string>     p_type_name;            // "case"/"suite"
    id_t                                p_id;                   // unique id for this test unit
    parent_id_t                         p_parent_id;            // parent test suite id

    // Public r/w properties
    readwrite_property<std::string>     p_name;                 // name for this test unit
    readwrite_property<unsigned>        p_timeout;              // timeout for the test unit execution
    readwrite_property<counter_t>       p_expected_failures;    // number of expected failures in this test unit
    mutable readwrite_property<bool>    p_enabled;              // enabled status for this unit

    void                                increase_exp_fail( unsigned num );

private:
    // Data members
    std::list<test_unit_id>             m_dependencies;
};

// ************************************************************************** //
// **************              test_case_generator             ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_unit_generator {
public:
    virtual test_unit*  next() const = 0;

protected:
    BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
};

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_case : public test_unit {
public:
    enum { type = tut_case };

    // Constructor
    test_case( const_string tc_name, callback0<> const& test_func );

    // Access methods
    callback0<> const&  test_func() const { return m_test_func; }

private:
    friend class framework_impl;
    ~test_case() {}

    // BOOST_MSVC <= 1200 have problems with callback as property
    // Data members
    callback0<> m_test_func;
};

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_suite : public test_unit {
public:
    enum { type = tut_suite };

    // Constructor
    explicit        test_suite( const_string ts_name );

    // test unit list management
    void            add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
    void            add( test_unit_generator const& gen, unsigned timeout = 0 );
    void            remove( test_unit_id id );

    // access methods
    test_unit_id    get( const_string tu_name ) const;
    std::size_t     size() const { return m_members.size(); }

protected:
    friend BOOST_TEST_DECL
    void        traverse_test_tree( test_suite const&, test_tree_visitor& );
    friend class framework_impl;
    virtual     ~test_suite() {}

    // Data members
    std::vector<test_unit_id> m_members;
};

// ************************************************************************** //
// **************               master_test_suite              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL master_test_suite_t : public test_suite {
public:
    master_test_suite_t() : test_suite( "Master Test Suite" )
    , argc( 0 )
    , argv( 0 )
    {}

    // Data members
    int      argc;
    char**   argv;
};

// ************************************************************************** //
// **************               test_tree_visitor              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL test_tree_visitor {
public:
    // test tree visitor interface
    virtual void    visit( test_case const& )               {}
    virtual bool    test_suite_start( test_suite const& )   { return true; }
    virtual void    test_suite_finish( test_suite const& )  {}

protected:
    BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
};

// ************************************************************************** //
// **************               traverse_test_tree             ************** //
// ************************************************************************** //

BOOST_TEST_DECL void    traverse_test_tree( test_case const&, test_tree_visitor& );
BOOST_TEST_DECL void    traverse_test_tree( test_suite const&, test_tree_visitor& );
BOOST_TEST_DECL void    traverse_test_tree( test_unit_id     , test_tree_visitor& );

//____________________________________________________________________________//

inline void
traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
{
    if( tu.p_type == tut_case )
        traverse_test_tree( static_cast<test_case const&>( tu ), V );
    else
        traverse_test_tree( static_cast<test_suite const&>( tu ), V );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                test_case_counter             ************** //
// ************************************************************************** //

class test_case_counter : public test_tree_visitor {
public:
    // Constructor
    test_case_counter() : p_count( 0 ) {}

    BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
private:
    // test tree visitor interface
    virtual void    visit( test_case const& );
    virtual bool    test_suite_start( test_suite const& ts )    { return ts.p_enabled; }
};

// ************************************************************************** //
// **************               test_being_aborted             ************** //
// ************************************************************************** //

struct BOOST_TEST_DECL test_being_aborted {};

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

namespace ut_detail {

BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );

template<typename InstanceType,typename UserTestCase>
struct user_tc_method_invoker {
    typedef void (UserTestCase::*test_method )();

    user_tc_method_invoker( shared_ptr<InstanceType> inst, test_method test_method )
    : m_inst( inst ), m_test_method( test_method ) {}

    void operator()() { ((*m_inst).*m_test_method)(); }

    shared_ptr<InstanceType> m_inst;
    test_method              m_test_method;
};

} // namespace ut_detail

//____________________________________________________________________________//

inline test_case*
make_test_case( callback0<> const& test_func, const_string tc_name )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
}

//____________________________________________________________________________//

template<typename UserTestCase, typename InstanceType>
inline test_case*
make_test_case( void (UserTestCase::*           test_method )(),
                const_string                    tc_name,
                boost::shared_ptr<InstanceType> user_test_case )
{
    return new test_case( ut_detail::normalize_test_case_name( tc_name ),
                          ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************           auto_test_unit_registrar           ************** //
// ************************************************************************** //

namespace ut_detail {

struct BOOST_TEST_DECL auto_test_unit_registrar
{
    // Constructors
                auto_test_unit_registrar( test_case* tc, counter_t exp_fail );
    explicit    auto_test_unit_registrar( const_string ts_name );
    explicit    auto_test_unit_registrar( test_unit_generator const& tc_gen );
    explicit    auto_test_unit_registrar( int );

private:
    static std::list<test_suite*>& curr_ts_store();
};

//____________________________________________________________________________//

template<typename T>
struct auto_tc_exp_fail {
    auto_tc_exp_fail() : m_value( 0 ) {}

    explicit    auto_tc_exp_fail( unsigned v )
    : m_value( v )
    {
        instance() = this;
    }

    static auto_tc_exp_fail*& instance()
    {
        static auto_tc_exp_fail     inst;
        static auto_tc_exp_fail*    inst_ptr = &inst;

        return inst_ptr;
    }

    unsigned    value() const { return m_value; }

private:
    // Data members
    unsigned    m_value;
};

//____________________________________________________________________________//

} // namespace ut_detail

// ************************************************************************** //
// **************                global_fixture                ************** //
// ************************************************************************** //

class BOOST_TEST_DECL global_fixture : public test_observer {
public:
    // Constructor
    global_fixture();
};

//____________________________________________________________________________//

namespace ut_detail {

template<typename F>
struct global_fixture_impl : public global_fixture {
    // Constructor
    global_fixture_impl(): m_fixure( 0 )    {}

    // test observer interface
    virtual void    test_start( counter_t ) { m_fixure = new F; }
    virtual void    test_finish()           { delete m_fixure; m_fixure = 0; }
    virtual void    test_aborted()          { delete m_fixure; m_fixure = 0; }

private:
    // Data members
    F*  m_fixure;
};

} // namespace ut_detail

} // unit_test

} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER

<|endoftext|>


<commit_before>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/fitting/RenderingParameters.hpp
 *
 * Copyright 2016 Patrik Huber
 *
 * 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.
 */
#pragma once

#ifndef RENDERINGPARAMETERS_HPP_
#define RENDERINGPARAMETERS_HPP_

#include "eos/fitting/orthographic_camera_estimation_linear.hpp"
#include "eos/render/utils.hpp" // for to_mat()

//#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/quaternion.hpp"

#include "eos/fitting/detail/optional_cerealisation.hpp"
#include "cereal/cereal.hpp"
#include "cereal/archives/json.hpp"

#include "opencv2/core/core.hpp"

#include "boost/optional.hpp"

#include <string>
#include <fstream>
#include <stdexcept>

namespace eos {
	namespace fitting {

/**
 * @brief A class representing a camera viewing frustum. At the moment only
 * fully tested with orthographic camera.
 */
struct Frustum
{
//	float l, r, b, t;
	Frustum() {};
	Frustum(float l, float r, float b, float t) : l(l), r(r), b(b), t(t) {};
	//Frustum(float l, float r, float b, float t, float n, float f) : l(l), r(r), b(b), t(t), n(n), f(f) {};
	float l = -1.0f;
	float r = 1.0f;
	float b = -1.0f;
	float t = 1.0f;
	//boost::optional<float> n; // These are not needed yet but probably will in the future,
	//boost::optional<float> f; // and then it's good if the old serialised files stay compatible.

	friend class cereal::access;
	/**
	 * Serialises this class using cereal.
	 *
	 * @param[in] ar The archive to serialise to (or to serialise from).
	 */
	template<class Archive>
	void serialize(Archive& archive)
	{
		archive(CEREAL_NVP(l), CEREAL_NVP(r), CEREAL_NVP(b), CEREAL_NVP(t));
	};
};

enum class CameraType
{
	Orthographic,
	Perspective
};

/**
 * @brief Represents a set of estimated model parameters (rotation, translation) and
 * camera parameters (viewing frustum).
 *
 * The estimated rotation and translation transform the model from model-space to camera-space,
 * and, if one wishes to use OpenGL, can be used to build the model-view matrix.
 * The parameters are the inverse of the camera position in 3D space.
 *
 * The camera frustum describes the size of the viewing plane of the camera, and
 * can be used to build an OpenGL-conformant orthographic projection matrix.
 *
 * Together, these parameters fully describe the imaging process of a given model instance
 * (under an orthographic projection).
 *
 * The rotation values are given in radians and estimated using the RPY convention.
 * Yaw is applied first to the model, then pitch, then roll (R * P * Y * vertex).
 *
 * This should always represent all parameters necessary to render the model to an image, and be completely OpenGL compliant.
 */
struct RenderingParameters
{
	// Creates with default frustum...
	RenderingParameters() {};

	// Initialisation for Eigen::LevMarq
	// This creates the correct rotation quaternion in the case the angles were estimated/given by R*P*Y*v.
	// Angles given in radian.
	// Note: If you subsequently use RP::get_rotation() and glm::eulerAngles() on it, the angles you get out will be slightly different from the ones you put in here.
	// But they will describe the same rotation! Just in a different order. (i.e. the rotation matrix or quaternion for both of these two sets of angles is identical.)
	RenderingParameters(CameraType camera_type, Frustum camera_frustum, float r_x, float r_y, float r_z, float tx, float ty, int screen_width, int screen_height) : camera_type(camera_type), frustum(camera_frustum), t_x(tx), t_y(ty), screen_width(screen_width), screen_height(screen_height) {
		auto rot_mtx_x = glm::rotate(glm::mat4(1.0f), r_x, glm::vec3{ 1.0f, 0.0f, 0.0f });
		auto rot_mtx_y = glm::rotate(glm::mat4(1.0f), r_y, glm::vec3{ 0.0f, 1.0f, 0.0f });
		auto rot_mtx_z = glm::rotate(glm::mat4(1.0f), r_z, glm::vec3{ 0.0f, 0.0f, 1.0f });
		auto zxy_rotation_matrix = rot_mtx_z * rot_mtx_x * rot_mtx_y;
		rotation = zxy_rotation_matrix;
	};

	// This assumes estimate_sop was run on points with OpenCV viewport! I.e. y flipped.
	RenderingParameters(ScaledOrthoProjectionParameters ortho_params, int image_width, int image_height) {
		camera_type = CameraType::Orthographic;
		rotation = ortho_params.R; // convert the rotation matrix to a quaternion
		t_x = ortho_params.tx;
		t_y = ortho_params.ty;
		const auto l = 0.0;
		const auto r = image_width / ortho_params.s;
		const auto b = 0.0; // The b and t values are not tested for what happens if the SOP parameters
		const auto t = image_height / ortho_params.s; // were estimated on a non-flipped viewport.
		frustum = Frustum(l, r, b, t);
	};

	glm::quat get_rotation() const {
		return rotation;
	};

	glm::mat4x4 get_modelview() const {
		// rot from quat, add transl., return 4x4.
		glm::mat4x4 modelview = glm::mat4_cast(rotation);
		modelview[3][0] = t_x;
		modelview[3][1] = t_y;
		return modelview;
	};

	glm::mat4x4 get_projection() const {
		if (camera_type == CameraType::Orthographic)
		{
			return glm::ortho<float>(frustum.l, frustum.r, frustum.b, frustum.t);
		}
		else {
			throw std::runtime_error("get_projection() for CameraType::Perspective is not implemented yet.");
		}
	};

	CameraType camera_type = CameraType::Orthographic;
	Frustum frustum; // Can construct a glm::ortho or glm::perspective matrix from this.

	// Todo: Get rid of the Euler angles and just use the quaternion.
	//float r_x; // Pitch.
	//float r_y; // Yaw. Positive means subject is looking left (we see her right cheek).
	//float r_z; // Roll. Positive means the subject's right eye is further down than the other one (he tilts his head to the right).
	glm::quat rotation;

	float t_x;
	float t_y;
	//boost::optional<float> t_z;
	//boost::optional<float> focal_length; // only for certain camera types. Should it go into Frustum?

	int screen_width; // (why) do we need these?
	int screen_height;

	friend class cereal::access;
	/**
	 * Serialises this class using cereal.
	 *
	 * @param[in] ar The archive to serialise to (or to serialise from).
	 */
	template<class Archive>
	void serialize(Archive& archive)
	{
		// TODO add the quaternion!
		archive(CEREAL_NVP(camera_type), CEREAL_NVP(frustum), CEREAL_NVP(t_x), CEREAL_NVP(t_y), CEREAL_NVP(screen_width), CEREAL_NVP(screen_height));
	};
};

/**
 * Saves the rendering parameters for an image to a json file.
 *
 * @param[in] rendering_parameters An instance of class RenderingParameters.
 * @param[in] filename The file to write.
 * @throws std::runtime_error if unable to open the given file for writing.
 */
void save_rendering_parameters(RenderingParameters rendering_parameters, std::string filename)
{
	std::ofstream file(filename);
	if (file.fail()) {
		throw std::runtime_error("Error opening file for writing: " + filename);
	}
	cereal::JSONOutputArchive output_archive(file);
	output_archive(cereal::make_nvp("rendering_parameters", rendering_parameters));
};

/**
 * @brief Returns a glm/OpenGL compatible viewport vector that flips y and
 * has the origin on the top-left, like in OpenCV.
 */
glm::vec4 get_opencv_viewport(int width, int height)
{
	return glm::vec4(0, height, width, -height);
};

/**
 * @brief Creates a 3x4 affine camera matrix from given fitting parameters. The
 * matrix transforms points directly from model-space to screen-space.
 *
 * This function is mainly used since the linear shape fitting fitting::fit_shape_to_landmarks_linear
 * expects one of these 3x4 affine camera matrices, as well as render::extract_texture.
 */
cv::Mat get_3x4_affine_camera_matrix(fitting::RenderingParameters params, int width, int height)
{
	auto view_model = render::to_mat(params.get_modelview());
	auto ortho_projection = render::to_mat(glm::ortho(params.frustum.l, params.frustum.r, params.frustum.b, params.frustum.t));
	cv::Mat mvp = ortho_projection * view_model;

	glm::vec4 viewport(0, height, width, -height); // flips y, origin top-left, like in OpenCV
	// equivalent to what glm::project's viewport does, but we don't change z and w:
	cv::Mat viewport_mat = (cv::Mat_<float>(4, 4) << viewport[2] / 2.0f, 0.0f,       0.0f, viewport[2] / 2.0f + viewport[0],
												     0.0f,               viewport[3] / 2.0f, 0.0f, viewport[3] / 2.0f + viewport[1],
													 0.0f,               0.0f,               1.0f, 0.0f,
													 0.0f,               0.0f,               0.0f, 1.0f);

	cv::Mat full_projection_4x4 = viewport_mat * mvp;
	cv::Mat full_projection_3x4 = full_projection_4x4.rowRange(0, 3); // we take the first 3 rows, but then set the last one to [0 0 0 1]
	full_projection_3x4.at<float>(2, 0) = 0.0f;
	full_projection_3x4.at<float>(2, 1) = 0.0f;
	full_projection_3x4.at<float>(2, 2) = 0.0f;
	full_projection_3x4.at<float>(2, 3) = 1.0f;

	return full_projection_3x4;
};

	} /* namespace fitting */
} /* namespace eos */

#endif /* RENDERINGPARAMETERS_HPP_ */
<commit_msg>Made RenderingParameters members private, updated doc<commit_after>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/fitting/RenderingParameters.hpp
 *
 * Copyright 2016 Patrik Huber
 *
 * 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.
 */
#pragma once

#ifndef RENDERINGPARAMETERS_HPP_
#define RENDERINGPARAMETERS_HPP_

#include "eos/fitting/orthographic_camera_estimation_linear.hpp"
#include "eos/render/utils.hpp" // for to_mat()

//#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/quaternion.hpp"

#include "eos/fitting/detail/optional_cerealisation.hpp"
#include "cereal/cereal.hpp"
#include "cereal/archives/json.hpp"

#include "opencv2/core/core.hpp"

#include "boost/optional.hpp"

#include <string>
#include <fstream>
#include <stdexcept>

namespace eos {
	namespace fitting {

/**
 * @brief A class representing a camera viewing frustum. At the moment only
 * fully tested with orthographic camera.
 */
struct Frustum
{
//	float l, r, b, t;
	Frustum() {};
	Frustum(float l, float r, float b, float t) : l(l), r(r), b(b), t(t) {};
	//Frustum(float l, float r, float b, float t, float n, float f) : l(l), r(r), b(b), t(t), n(n), f(f) {};
	float l = -1.0f;
	float r = 1.0f;
	float b = -1.0f;
	float t = 1.0f;
	//boost::optional<float> n; // These are not needed yet but probably will in the future,
	//boost::optional<float> f; // and then it's good if the old serialised files stay compatible.

	friend class cereal::access;
	/**
	 * Serialises this class using cereal.
	 *
	 * @param[in] ar The archive to serialise to (or to serialise from).
	 */
	template<class Archive>
	void serialize(Archive& archive)
	{
		archive(CEREAL_NVP(l), CEREAL_NVP(r), CEREAL_NVP(b), CEREAL_NVP(t));
	};
};

enum class CameraType
{
	Orthographic,
	Perspective
};

/**
 * @brief Represents a set of estimated model parameters (rotation, translation) and
 * camera parameters (viewing frustum).
 *
 * The estimated rotation and translation transform the model from model-space to camera-space,
 * and, if one wishes to use OpenGL, can be used to build the model-view matrix.
 * The parameters are the inverse of the camera position in 3D space.
 *
 * The camera frustum describes the size of the viewing plane of the camera, and
 * can be used to build an OpenGL-conformant orthographic projection matrix.
 *
 * Together, these parameters fully describe the imaging process of a given model instance
 * (under an orthographic projection).
 *
 * The rotation values are given in radians and estimated using the RPY convention.
 * Yaw is applied first to the model, then pitch, then roll (R * P * Y * vertex).
 * In general, the convention is as follows:
 * 	 r_x = Pitch
 *	 r_y = Yaw. Positive means subject is looking left (we see her right cheek).
 *	 r_z = Roll. Positive means the subject's right eye is further down than the other one (he tilts his head to the right).
 * However, we're using a quaternion now to represent the rotation, and glm::eulerAngles() will give
 * slightly different angles (according to a different (undocumented)) convention. However, the
 * rotation is exactly the same! (i.e. they are represented by the same quaternion / rotation matrix).
 *
 * This should always represent all parameters necessary to render the model to an image, and be completely OpenGL compliant.
 */
class RenderingParameters
{
public:
	// Creates with default frustum...
	RenderingParameters() {};

	// Initialisation for Eigen::LevMarq
	// This creates the correct rotation quaternion in the case the angles were estimated/given by R*P*Y*v.
	// Angles given in radian.
	// Note: If you subsequently use RP::get_rotation() and glm::eulerAngles() on it, the angles you get out will be slightly different from the ones you put in here.
	// But they will describe the same rotation! Just in a different order. (i.e. the rotation matrix or quaternion for both of these two sets of angles is identical.)
	RenderingParameters(CameraType camera_type, Frustum camera_frustum, float r_x, float r_y, float r_z, float tx, float ty, int screen_width, int screen_height) : camera_type(camera_type), frustum(camera_frustum), t_x(tx), t_y(ty), screen_width(screen_width), screen_height(screen_height) {
		auto rot_mtx_x = glm::rotate(glm::mat4(1.0f), r_x, glm::vec3{ 1.0f, 0.0f, 0.0f });
		auto rot_mtx_y = glm::rotate(glm::mat4(1.0f), r_y, glm::vec3{ 0.0f, 1.0f, 0.0f });
		auto rot_mtx_z = glm::rotate(glm::mat4(1.0f), r_z, glm::vec3{ 0.0f, 0.0f, 1.0f });
		auto zxy_rotation_matrix = rot_mtx_z * rot_mtx_x * rot_mtx_y;
		rotation = zxy_rotation_matrix;
	};

	// This assumes estimate_sop was run on points with OpenCV viewport! I.e. y flipped.
	RenderingParameters(ScaledOrthoProjectionParameters ortho_params, int image_width, int image_height) {
		camera_type = CameraType::Orthographic;
		rotation = ortho_params.R; // convert the rotation matrix to a quaternion
		t_x = ortho_params.tx;
		t_y = ortho_params.ty;
		const auto l = 0.0;
		const auto r = image_width / ortho_params.s;
		const auto b = 0.0; // The b and t values are not tested for what happens if the SOP parameters
		const auto t = image_height / ortho_params.s; // were estimated on a non-flipped viewport.
		frustum = Frustum(l, r, b, t);
	};

	glm::quat get_rotation() const {
		return rotation;
	};

	glm::mat4x4 get_modelview() const {
		glm::mat4x4 modelview = glm::mat4_cast(rotation);
		modelview[3][0] = t_x;
		modelview[3][1] = t_y;
		return modelview;
	};

	glm::mat4x4 get_projection() const {
		if (camera_type == CameraType::Orthographic)
		{
			return glm::ortho<float>(frustum.l, frustum.r, frustum.b, frustum.t);
		}
		else {
			throw std::runtime_error("get_projection() for CameraType::Perspective is not implemented yet.");
		}
	};

private:
	CameraType camera_type = CameraType::Orthographic;
	Frustum frustum; // Can construct a glm::ortho or glm::perspective matrix from this.

	glm::quat rotation;

	float t_x;
	float t_y;
	//boost::optional<float> t_z;
	//boost::optional<float> focal_length; // only for certain camera types. Should it go into Frustum?

	int screen_width; // (why) do we need these?
	int screen_height;

	friend class cereal::access;
	/**
	 * Serialises this class using cereal.
	 *
	 * @param[in] ar The archive to serialise to (or to serialise from).
	 */
	template<class Archive>
	void serialize(Archive& archive)
	{
		// TODO add the quaternion!
		archive(CEREAL_NVP(camera_type), CEREAL_NVP(frustum), CEREAL_NVP(t_x), CEREAL_NVP(t_y), CEREAL_NVP(screen_width), CEREAL_NVP(screen_height));
	};
};

/**
 * Saves the rendering parameters for an image to a json file.
 *
 * @param[in] rendering_parameters An instance of class RenderingParameters.
 * @param[in] filename The file to write.
 * @throws std::runtime_error if unable to open the given file for writing.
 */
void save_rendering_parameters(RenderingParameters rendering_parameters, std::string filename)
{
	std::ofstream file(filename);
	if (file.fail()) {
		throw std::runtime_error("Error opening file for writing: " + filename);
	}
	cereal::JSONOutputArchive output_archive(file);
	output_archive(cereal::make_nvp("rendering_parameters", rendering_parameters));
};

/**
 * @brief Returns a glm/OpenGL compatible viewport vector that flips y and
 * has the origin on the top-left, like in OpenCV.
 */
glm::vec4 get_opencv_viewport(int width, int height)
{
	return glm::vec4(0, height, width, -height);
};

/**
 * @brief Creates a 3x4 affine camera matrix from given fitting parameters. The
 * matrix transforms points directly from model-space to screen-space.
 *
 * This function is mainly used since the linear shape fitting fitting::fit_shape_to_landmarks_linear
 * expects one of these 3x4 affine camera matrices, as well as render::extract_texture.
 */
cv::Mat get_3x4_affine_camera_matrix(fitting::RenderingParameters params, int width, int height)
{
	auto view_model = render::to_mat(params.get_modelview());
	auto ortho_projection = render::to_mat(params.get_projection());
	cv::Mat mvp = ortho_projection * view_model;

	glm::vec4 viewport(0, height, width, -height); // flips y, origin top-left, like in OpenCV
	// equivalent to what glm::project's viewport does, but we don't change z and w:
	cv::Mat viewport_mat = (cv::Mat_<float>(4, 4) << viewport[2] / 2.0f, 0.0f,       0.0f, viewport[2] / 2.0f + viewport[0],
												     0.0f,               viewport[3] / 2.0f, 0.0f, viewport[3] / 2.0f + viewport[1],
													 0.0f,               0.0f,               1.0f, 0.0f,
													 0.0f,               0.0f,               0.0f, 1.0f);

	cv::Mat full_projection_4x4 = viewport_mat * mvp;
	cv::Mat full_projection_3x4 = full_projection_4x4.rowRange(0, 3); // we take the first 3 rows, but then set the last one to [0 0 0 1]
	full_projection_3x4.at<float>(2, 0) = 0.0f;
	full_projection_3x4.at<float>(2, 1) = 0.0f;
	full_projection_3x4.at<float>(2, 2) = 0.0f;
	full_projection_3x4.at<float>(2, 3) = 1.0f;

	return full_projection_3x4;
};

	} /* namespace fitting */
} /* namespace eos */

#endif /* RENDERINGPARAMETERS_HPP_ */
<|endoftext|>


<commit_before>#ifndef HERMIT_SPIRIT_KARMA_MESSAGEPACK_HPP
#define HERMIT_SPIRIT_KARMA_MESSAGEPACK_HPP

#include <utility>
#include <string>
#include <vector>
#include <map>
#include <boost/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/optional.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/include/std_pair.hpp>

#include <hermit/messagepack.hpp>

namespace hermit {
  namespace spirit {
    namespace karma {
      template< typename Iterator >
      class messagepack :
        public boost::spirit::karma::grammar<
          Iterator,
          hermit::messagepack()
        > {
      public:
        messagepack() : messagepack::base_type( value_ ) {
          namespace karma = boost::spirit::karma;
          uint8_short = karma::byte_[
            karma::_pass = karma::_val <= 0x7F,
            karma::_1 = karma::_val
          ];
          uint8_long = ( karma::byte_( 0xcc ) << karma::byte_ );
          uint8_ = uint8_short|uint8_long;
          uint16_ = karma::byte_( 0xcd ) << karma::big_word;
          uint32_ = karma::byte_( 0xce ) << karma::big_dword;
          uint64_ = karma::byte_( 0xcf ) << karma::big_qword;
          int8_short = karma::byte_[
            karma::_pass = karma::_val < 0 && karma::_val > -32,
            karma::_1 = boost::phoenix::static_cast_<uint8_t>( karma::_val )
          ];
          int8_long = karma::byte_( 0xd0 ) << karma::byte_[
            karma::_1 = boost::phoenix::static_cast_<uint8_t>( karma::_val )
          ];
          int8_ = int8_short|int8_long;
          int16_ = karma::byte_( 0xd1 ) << karma::big_word[
            karma::_1 = boost::phoenix::static_cast_<uint16_t>( karma::_val )
          ];
          int32_ = karma::byte_( 0xd2 ) << karma::big_dword[
            karma::_1 = boost::phoenix::static_cast_<uint32_t>( karma::_val )
          ];
          int64_ = karma::byte_( 0xd3 ) << karma::big_qword[
            karma::_1 = boost::phoenix::static_cast_<uint64_t>( karma::_val )
          ];
          null_ = karma::byte_( 0xc0 );
          bool_ = karma::byte_( 0xc3 )[ karma::_pass = karma::_val ]|karma::byte_( 0xc2 );
          float_ = karma::byte_( 0xca ) << karma::big_bin_float;
          double_ = karma::byte_( 0xcb ) << karma::big_bin_double;
          raw_short = karma::byte_[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0x1F,
            karma::_1 = 0xC0|boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ karma::byte_ ][
            karma::_1 = karma::_val
          ];
          raw_16 = ( karma::byte_( 0xda ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ karma::byte_ ][
            karma::_1 = karma::_val
          ];
          raw_32 = ( karma::byte_( 0xdb ) << karma::big_dword )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ karma::byte_ ][
            karma::_1 = karma::_val
          ];
          raw = raw_short|raw_16|raw_32;
          array_short = karma::byte_[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0x0F,
            karma::_1 = 0x90|boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ value_ ][
            karma::_1 = karma::_val
          ];
          array_16 = ( karma::byte_( 0xdc ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ value_ ][
            karma::_1 = karma::_val
          ];
          array_32 = ( karma::byte_( 0xdd ) << karma::big_dword )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ value_ ][
            karma::_1 = karma::_val
          ];
          array = array_short|array_16|array_32;
          named_value = value_ << value_;
          map_short = karma::byte_[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0x0F,
            karma::_1 = 0x80|boost::phoenix::size( karma::_val )
          ];
          map_16 = ( karma::byte_( 0xde ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val )
          ];
          map_32 = ( karma::byte_( 0xdf ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val )
          ];
          map_data = karma::repeat( boost::phoenix::size( karma::_val ) )[ named_value ];
          map = ( ( map_short|map_16|map_32 ) << map_data )[ karma::_1 = karma::_val, karma::_2 = karma::_val ];
          /*<< karma::repeat( karma::_a )[ named_value ][
            karma::_1 = 1, karma::_2 = 2
          ];*/
/*          map_16 = ( karma::byte_( 0xde ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ named_value ][
            karma::_1 = karma::_val
          ];
          map_32 = ( karma::byte_( 0xdf ) << karma::big_dword )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val ),
            karma::_a = boost::phoenix::size( karma::_val )
          ] << karma::repeat( karma::_a )[ named_value ][
            karma::_1 = karma::_val
          ];*/
 //         map = map_short|map_16|map_32;
 //         value_ = uint8_|uint16_|uint32_|uint64_|int8_|int16_|int32_|int64_|null_|bool_|float_|double_|raw|array|map;
      }
      private:
        boost::spirit::karma::rule< Iterator, uint8_t() > uint8_short;
        boost::spirit::karma::rule< Iterator, uint8_t() > uint8_long;
        boost::spirit::karma::rule< Iterator, uint8_t() > uint8_;
        boost::spirit::karma::rule< Iterator, uint16_t() > uint16_;
        boost::spirit::karma::rule< Iterator, uint32_t() > uint32_;
        boost::spirit::karma::rule< Iterator, uint64_t() > uint64_;
        boost::spirit::karma::rule< Iterator, int8_t() > int8_short;
        boost::spirit::karma::rule< Iterator, int8_t() > int8_long;
        boost::spirit::karma::rule< Iterator, int8_t() > int8_;
        boost::spirit::karma::rule< Iterator, int16_t() > int16_;
        boost::spirit::karma::rule< Iterator, int32_t() > int32_;
        boost::spirit::karma::rule< Iterator, int64_t() > int64_;
        boost::spirit::karma::rule< Iterator, std::nullptr_t() > null_;
        boost::spirit::karma::rule< Iterator, bool() > bool_;
        boost::spirit::karma::rule< Iterator, float() > float_;
        boost::spirit::karma::rule< Iterator, double() > double_;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >(), boost::spirit::karma::locals< uint32_t > > raw_short;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >(), boost::spirit::karma::locals< uint32_t > > raw_16;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >(), boost::spirit::karma::locals< uint32_t > > raw_32;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >() > raw;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > array_short;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > array_16;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > array_32;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > array;
        boost::spirit::karma::rule< Iterator, std::pair< hermit::messagepack, hermit::messagepack >() > named_value;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > map_short;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > map_data;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > map_16;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > map_32;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >(), boost::spirit::karma::locals< uint32_t > > map;
        boost::spirit::karma::rule< Iterator, hermit::messagepack() > value_;
      };
    }
  }
}

#endif

<commit_msg>不要になったコードを削除<commit_after>#ifndef HERMIT_SPIRIT_KARMA_MESSAGEPACK_HPP
#define HERMIT_SPIRIT_KARMA_MESSAGEPACK_HPP

#include <utility>
#include <string>
#include <vector>
#include <map>
#include <boost/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/optional.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/include/std_pair.hpp>

#include <hermit/messagepack.hpp>

namespace hermit {
  namespace spirit {
    namespace karma {
      template< typename Iterator >
      class messagepack :
        public boost::spirit::karma::grammar<
          Iterator,
          hermit::messagepack()
        > {
      public:
        messagepack() : messagepack::base_type( value_ ) {
          namespace karma = boost::spirit::karma;
          uint8_short = karma::byte_[
            karma::_pass = karma::_val <= 0x7F,
            karma::_1 = karma::_val
          ];
          uint8_long = ( karma::byte_( 0xcc ) << karma::byte_ );
          uint8_ = uint8_short|uint8_long;
          uint16_ = karma::byte_( 0xcd ) << karma::big_word;
          uint32_ = karma::byte_( 0xce ) << karma::big_dword;
          uint64_ = karma::byte_( 0xcf ) << karma::big_qword;
          int8_short = karma::byte_[
            karma::_pass = karma::_val < 0 && karma::_val > -32,
            karma::_1 = boost::phoenix::static_cast_<uint8_t>( karma::_val )
          ];
          int8_long = karma::byte_( 0xd0 ) << karma::byte_[
            karma::_1 = boost::phoenix::static_cast_<uint8_t>( karma::_val )
          ];
          int8_ = int8_short|int8_long;
          int16_ = karma::byte_( 0xd1 ) << karma::big_word[
            karma::_1 = boost::phoenix::static_cast_<uint16_t>( karma::_val )
          ];
          int32_ = karma::byte_( 0xd2 ) << karma::big_dword[
            karma::_1 = boost::phoenix::static_cast_<uint32_t>( karma::_val )
          ];
          int64_ = karma::byte_( 0xd3 ) << karma::big_qword[
            karma::_1 = boost::phoenix::static_cast_<uint64_t>( karma::_val )
          ];
          null_ = karma::byte_( 0xc0 );
          bool_ = karma::byte_( 0xc3 )[ karma::_pass = karma::_val ]|karma::byte_( 0xc2 );
          float_ = karma::byte_( 0xca ) << karma::big_bin_float;
          double_ = karma::byte_( 0xcb ) << karma::big_bin_double;
          raw_short = karma::byte_[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0x1F,
            karma::_1 = 0xC0|boost::phoenix::size( karma::_val )
          ] << karma::repeat( boost::phoenix::size( karma::_val ) )[ karma::byte_ ][
            karma::_1 = karma::_val
          ];
          raw_16 = ( karma::byte_( 0xda ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val )
          ] << karma::repeat( boost::phoenix::size( karma::_val ) )[ karma::byte_ ][
            karma::_1 = karma::_val
          ];
          raw_32 = ( karma::byte_( 0xdb ) << karma::big_dword )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val )
          ] << karma::repeat( boost::phoenix::size( karma::_val ) )[ karma::byte_ ][
            karma::_1 = karma::_val
          ];
          raw = raw_short|raw_16|raw_32;
          array_short = karma::byte_[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0x0F,
            karma::_1 = 0x90|boost::phoenix::size( karma::_val )
          ] << karma::repeat( boost::phoenix::size( karma::_val ) )[ value_ ][
            karma::_1 = karma::_val
          ];
          array_16 = ( karma::byte_( 0xdc ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val )
          ] << karma::repeat( boost::phoenix::size( karma::_val ) )[ value_ ][
            karma::_1 = karma::_val
          ];
          array_32 = ( karma::byte_( 0xdd ) << karma::big_dword )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val )
          ] << karma::repeat( boost::phoenix::size( karma::_val ) )[ value_ ][
            karma::_1 = karma::_val
          ];
          array = array_short|array_16|array_32;
          named_value = value_ << value_;
          map_short = karma::byte_[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0x0F,
            karma::_1 = 0x80|boost::phoenix::size( karma::_val )
          ];
          map_16 = ( karma::byte_( 0xde ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFF,
            karma::_1 = boost::phoenix::size( karma::_val )
          ];
          map_32 = ( karma::byte_( 0xdf ) << karma::big_word )[
            karma::_pass = boost::phoenix::size( karma::_val ) <= 0xFFFFFFFFul,
            karma::_1 = boost::phoenix::size( karma::_val )
          ];
          map_data = karma::repeat( boost::phoenix::size( karma::_val ) )[ named_value ];
          map = ( ( map_short|map_16|map_32 ) << map_data )[ karma::_1 = karma::_val, karma::_2 = karma::_val ];
          value_ = uint8_|uint16_|uint32_|uint64_|int8_|int16_|int32_|int64_|null_|bool_|float_|double_|raw|array|map;
      }
      private:
        boost::spirit::karma::rule< Iterator, uint8_t() > uint8_short;
        boost::spirit::karma::rule< Iterator, uint8_t() > uint8_long;
        boost::spirit::karma::rule< Iterator, uint8_t() > uint8_;
        boost::spirit::karma::rule< Iterator, uint16_t() > uint16_;
        boost::spirit::karma::rule< Iterator, uint32_t() > uint32_;
        boost::spirit::karma::rule< Iterator, uint64_t() > uint64_;
        boost::spirit::karma::rule< Iterator, int8_t() > int8_short;
        boost::spirit::karma::rule< Iterator, int8_t() > int8_long;
        boost::spirit::karma::rule< Iterator, int8_t() > int8_;
        boost::spirit::karma::rule< Iterator, int16_t() > int16_;
        boost::spirit::karma::rule< Iterator, int32_t() > int32_;
        boost::spirit::karma::rule< Iterator, int64_t() > int64_;
        boost::spirit::karma::rule< Iterator, std::nullptr_t() > null_;
        boost::spirit::karma::rule< Iterator, bool() > bool_;
        boost::spirit::karma::rule< Iterator, float() > float_;
        boost::spirit::karma::rule< Iterator, double() > double_;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >() > raw_short;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >() > raw_16;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >() > raw_32;
        boost::spirit::karma::rule< Iterator, std::vector< uint8_t >() > raw;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >() > array_short;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >() > array_16;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >() > array_32;
        boost::spirit::karma::rule< Iterator, std::vector< hermit::messagepack >() > array;
        boost::spirit::karma::rule< Iterator, std::pair< hermit::messagepack, hermit::messagepack >() > named_value;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >() > map_short;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >() > map_data;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >() > map_16;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >() > map_32;
        boost::spirit::karma::rule< Iterator, std::map< hermit::messagepack, hermit::messagepack >() > map;
        boost::spirit::karma::rule< Iterator, hermit::messagepack() > value_;
      };
    }
  }
}

#endif

<|endoftext|>


<commit_before>/*

Copyright (c) 2013, Arvid Norberg
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 the name of the author nor the names of its
      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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_PERFORMANCE_COUNTERS_HPP_INCLUDED
#define TORRENT_PERFORMANCE_COUNTERS_HPP_INCLUDED

#include <boost/cstdint.hpp>
#include <boost/atomic.hpp>
#include "libtorrent/config.hpp"

namespace libtorrent
{
	struct TORRENT_EXTRA_EXPORT counters
	{
		enum stats_counter_t
		{
			// the number of peers that were disconnected this
			// tick due to protocol error
			error_peers,
			disconnected_peers,
			eof_peers,
			connreset_peers,
			connrefused_peers,
			connaborted_peers,
			perm_peers,
			buffer_peers,
			unreachable_peers,
			broken_pipe_peers,
			addrinuse_peers,
			no_access_peers,
			invalid_arg_peers,
			aborted_peers,

			piece_requests,
			max_piece_requests,
			invalid_piece_requests,
			choked_piece_requests,
			cancelled_piece_requests,
			piece_rejects,
			error_incoming_peers,
			error_outgoing_peers,
			error_rc4_peers,
			error_encrypted_peers,
			error_tcp_peers,
			error_utp_peers,

			// the number of times the piece picker was
			// successfully invoked, split by the reason
			// it was invoked
			reject_piece_picks,
			unchoke_piece_picks,
			incoming_redundant_piece_picks,
			incoming_piece_picks,
			end_game_piece_picks,
			snubbed_piece_picks,
			interesting_piece_picks,
			hash_fail_piece_picks,

			// these counters indicate which parts
			// of the piece picker CPU is spent in
			piece_picker_partial_loops,
			piece_picker_suggest_loops,
			piece_picker_sequential_loops,
			piece_picker_reverse_rare_loops,
			piece_picker_rare_loops,
			piece_picker_rand_start_loops,
			piece_picker_rand_loops,
			piece_picker_busy_loops,

			// reasons to disconnect peers
			connect_timeouts,
			uninteresting_peers,
			timeout_peers,
			no_memory_peers,
			too_many_peers,
			transport_timeout_peers,
			num_banned_peers,
			banned_for_hash_failure,

			// connection attempts (not necessarily successful)
			connection_attempts,
			// the number of iterations over the peer list when finding
			// a connect candidate
			connection_attempt_loops,
			// successful incoming connections (not rejected for any reason)
			incoming_connections,

			// counts events where the network
			// thread wakes up
			on_read_counter,
			on_write_counter,
			on_tick_counter,
			on_lsd_counter,
			on_lsd_peer_counter,
			on_udp_counter,
			on_accept_counter,
			on_disk_queue_counter,
			on_disk_counter,

			torrent_evicted_counter,

			// bittorrent message counters
			// TODO: should keepalives be in here too?
			// how about dont-have, share-mode, upload-only
			num_incoming_choke,
			num_incoming_unchoke,
			num_incoming_interested,
			num_incoming_not_interested,
			num_incoming_have,
			num_incoming_bitfield,
			num_incoming_request,
			num_incoming_piece,
			num_incoming_cancel,
			num_incoming_dht_port,
			num_incoming_suggest,
			num_incoming_have_all,
			num_incoming_have_none,
			num_incoming_reject,
			num_incoming_allowed_fast,
			num_incoming_ext_handshake,
			num_incoming_pex,
			num_incoming_metadata,
			num_incoming_extended,

			num_outgoing_choke,
			num_outgoing_unchoke,
			num_outgoing_interested,
			num_outgoing_not_interested,
			num_outgoing_have,
			num_outgoing_bitfield,
			num_outgoing_request,
			num_outgoing_piece,
			num_outgoing_cancel,
			num_outgoing_dht_port,
			num_outgoing_suggest,
			num_outgoing_have_all,
			num_outgoing_have_none,
			num_outgoing_reject,
			num_outgoing_allowed_fast,
			num_outgoing_ext_handshake,
			num_outgoing_pex,
			num_outgoing_metadata,
			num_outgoing_extended,

			num_piece_passed,
			num_piece_failed,

			num_have_pieces,
			num_total_pieces_added,

			num_blocks_written,
			num_blocks_read,
			num_blocks_hashed,
			num_blocks_cache_hits,
			num_write_ops,
			num_read_ops,
			num_read_back,

			disk_read_time,
			disk_write_time,
			disk_hash_time,
			disk_job_time,

			waste_piece_timed_out,
			waste_piece_cancelled,
			waste_piece_unknown,
			waste_piece_seed,
			waste_piece_end_game,
			waste_piece_closing,

			sent_payload_bytes,
			sent_bytes,
			sent_ip_overhead_bytes,
			sent_tracker_bytes,
			recv_payload_bytes,
			recv_bytes,
			recv_ip_overhead_bytes,
			recv_tracker_bytes,

			recv_failed_bytes,
			recv_redundant_bytes,

			dht_messages_in,
			dht_messages_out,
			dht_messages_out_dropped,
			dht_bytes_in,
			dht_bytes_out,

			dht_ping_in,
			dht_ping_out,
			dht_find_node_in,
			dht_find_node_out,
			dht_get_peers_in,
			dht_get_peers_out,
			dht_announce_peer_in,
			dht_announce_peer_out,
			dht_get_in,
			dht_get_out,
			dht_put_in,
			dht_put_out,

			// uTP counters
			utp_packet_loss,
			utp_timeout,
			utp_packets_in,
			utp_packets_out,
			utp_fast_retransmit,
			utp_packet_resend,
			utp_samples_above_target,
			utp_samples_below_target,
			utp_payload_pkts_in,
			utp_payload_pkts_out,
			utp_invalid_pkts_in,
			utp_redundant_pkts_in,

			// the buffer sizes accepted by
			// socket send calls. The larger
			// the more efficient. The size is
			// 1 << n, where n is the number
			// at the end of the counter name

			// 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
			// 16384, 32768, 65536, 131072, 262144, 524288, 1048576
			socket_send_size3,
			socket_send_size4,
			socket_send_size5,
			socket_send_size6,
			socket_send_size7,
			socket_send_size8,
			socket_send_size9,
			socket_send_size10,
			socket_send_size11,
			socket_send_size12,
			socket_send_size13,
			socket_send_size14,
			socket_send_size15,
			socket_send_size16,
			socket_send_size17,
			socket_send_size18,
			socket_send_size19,
			socket_send_size20,

			// the buffer sizes returned by
			// socket recv calls. The larger
			// the more efficient. The size is
			// 1 << n, where n is the number
			// at the end of the counter name

			// 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
			// 16384, 32768, 65536, 131072, 262144, 524288, 1048576
			socket_recv_size3,
			socket_recv_size4,
			socket_recv_size5,
			socket_recv_size6,
			socket_recv_size7,
			socket_recv_size8,
			socket_recv_size9,
			socket_recv_size10,
			socket_recv_size11,
			socket_recv_size12,
			socket_recv_size13,
			socket_recv_size14,
			socket_recv_size15,
			socket_recv_size16,
			socket_recv_size17,
			socket_recv_size18,
			socket_recv_size19,
			socket_recv_size20,

			num_stats_counters
		};

		// it is important that all gauges have a higher index than counters.
		// This assumption is relied upon in other parts of the code
		enum stats_gauges_t
		{
			num_checking_torrents = num_stats_counters,
			num_stopped_torrents,
			// upload_only means finished
			num_upload_only_torrents,
			num_downloading_torrents,
			num_seeding_torrents,
			num_queued_seeding_torrents,
			num_queued_download_torrents,
			num_error_torrents,

			// the number of torrents that don't have the
			// IP filter applied to them.
			non_filter_torrents,

			// counters related to evicting torrents
			num_loaded_torrents,
			num_pinned_torrents,

			// these counter indices deliberatly
			// match the order of socket type IDs
			// defined in socket_type.hpp.
			num_tcp_peers,
			num_socks5_peers,
			num_http_proxy_peers,
			num_utp_peers,
			num_i2p_peers,
			num_ssl_peers,
			num_ssl_socks5_peers,
			num_ssl_http_proxy_peers,
			num_ssl_utp_peers,

			num_peers_half_open,
			num_peers_connected,
			num_peers_up_interested,
			num_peers_down_interested,
			num_peers_up_unchoked,
			num_peers_down_unchoked,
			num_peers_up_requests,
			num_peers_down_requests,
			num_peers_up_disk,
			num_peers_down_disk,
			num_peers_end_game,

			write_cache_blocks,
			read_cache_blocks,
			request_latency,
			pinned_blocks,
			disk_blocks_in_use,
			queued_disk_jobs,
			num_read_jobs,
			num_write_jobs,
			num_jobs,
			num_writing_threads,
			num_running_threads,
			blocked_disk_jobs,
			queued_write_bytes,
			num_unchoke_slots,

			arc_mru_size,
			arc_mru_ghost_size,
			arc_mfu_size,
			arc_mfu_ghost_size,
			arc_write_size,
			arc_volatile_size,

			dht_nodes,
			dht_node_cache,
			dht_torrents,
			dht_peers,
			dht_immutable_data,
			dht_mutable_data,
			dht_allocated_observers,

			has_incoming_connections,

			limiter_up_queue,
			limiter_down_queue,
			limiter_up_bytes,
			limiter_down_bytes,

			num_counters,
			num_gauge_counters = num_counters - num_stats_counters
		};

		counters();

		counters(counters const&);
		counters& operator=(counters const&);

		// returns the new value
		boost::int64_t inc_stats_counter(int c, boost::int64_t value = 1);
		boost::int64_t operator[](int i) const;

		void set_value(int c, boost::int64_t value);
		void blend_stats_counter(int c, boost::int64_t value, int ratio);

	private:

		// TODO: some space could be saved here by making gauges 32 bits
#if BOOST_ATOMIC_LLONG_LOCK_FREE == 2
		boost::atomic<boost::int64_t> m_stats_counter[num_counters];
#else
		// if the atomic type is't lock-free, use a single lock instead, for
		// the whole array
		mutex m_mutex;
		boost::int64_t m_stats_counter[num_counters];
#endif
	};
}

#endif

<commit_msg>comment<commit_after>/*

Copyright (c) 2013, Arvid Norberg
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 the name of the author nor the names of its
      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 COPYRIGHT OWNER 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.

*/

#ifndef TORRENT_PERFORMANCE_COUNTERS_HPP_INCLUDED
#define TORRENT_PERFORMANCE_COUNTERS_HPP_INCLUDED

#include <boost/cstdint.hpp>
#include <boost/atomic.hpp>
#include "libtorrent/config.hpp"

namespace libtorrent
{
	struct TORRENT_EXTRA_EXPORT counters
	{
		enum stats_counter_t
		{
			// the number of peers that were disconnected this
			// tick due to protocol error
			error_peers,
			disconnected_peers,
			eof_peers,
			connreset_peers,
			connrefused_peers,
			connaborted_peers,
			perm_peers,
			buffer_peers,
			unreachable_peers,
			broken_pipe_peers,
			addrinuse_peers,
			no_access_peers,
			invalid_arg_peers,
			aborted_peers,

			piece_requests,
			max_piece_requests,
			invalid_piece_requests,
			choked_piece_requests,
			cancelled_piece_requests,
			piece_rejects,
			error_incoming_peers,
			error_outgoing_peers,
			error_rc4_peers,
			error_encrypted_peers,
			error_tcp_peers,
			error_utp_peers,

			// the number of times the piece picker was
			// successfully invoked, split by the reason
			// it was invoked
			reject_piece_picks,
			unchoke_piece_picks,
			incoming_redundant_piece_picks,
			incoming_piece_picks,
			end_game_piece_picks,
			snubbed_piece_picks,
			interesting_piece_picks,
			hash_fail_piece_picks,

			// these counters indicate which parts
			// of the piece picker CPU is spent in
			piece_picker_partial_loops,
			piece_picker_suggest_loops,
			piece_picker_sequential_loops,
			piece_picker_reverse_rare_loops,
			piece_picker_rare_loops,
			piece_picker_rand_start_loops,
			piece_picker_rand_loops,
			piece_picker_busy_loops,

			// reasons to disconnect peers
			connect_timeouts,
			uninteresting_peers,
			timeout_peers,
			no_memory_peers,
			too_many_peers,
			transport_timeout_peers,
			num_banned_peers,
			banned_for_hash_failure,

			// connection attempts (not necessarily successful)
			connection_attempts,
			// the number of iterations over the peer list when finding
			// a connect candidate
			connection_attempt_loops,
			// successful incoming connections (not rejected for any reason)
			incoming_connections,

			// counts events where the network
			// thread wakes up
			on_read_counter,
			on_write_counter,
			on_tick_counter,
			on_lsd_counter,
			on_lsd_peer_counter,
			on_udp_counter,
			on_accept_counter,
			on_disk_queue_counter,
			on_disk_counter,

			torrent_evicted_counter,

			// bittorrent message counters
			// TODO: should keepalives be in here too?
			// how about dont-have, share-mode, upload-only
			num_incoming_choke,
			num_incoming_unchoke,
			num_incoming_interested,
			num_incoming_not_interested,
			num_incoming_have,
			num_incoming_bitfield,
			num_incoming_request,
			num_incoming_piece,
			num_incoming_cancel,
			num_incoming_dht_port,
			num_incoming_suggest,
			num_incoming_have_all,
			num_incoming_have_none,
			num_incoming_reject,
			num_incoming_allowed_fast,
			num_incoming_ext_handshake,
			num_incoming_pex,
			num_incoming_metadata,
			num_incoming_extended,

			num_outgoing_choke,
			num_outgoing_unchoke,
			num_outgoing_interested,
			num_outgoing_not_interested,
			num_outgoing_have,
			num_outgoing_bitfield,
			num_outgoing_request,
			num_outgoing_piece,
			num_outgoing_cancel,
			num_outgoing_dht_port,
			num_outgoing_suggest,
			num_outgoing_have_all,
			num_outgoing_have_none,
			num_outgoing_reject,
			num_outgoing_allowed_fast,
			num_outgoing_ext_handshake,
			num_outgoing_pex,
			num_outgoing_metadata,
			num_outgoing_extended,

			num_piece_passed,
			num_piece_failed,

			num_have_pieces,
			num_total_pieces_added,

			num_blocks_written,
			num_blocks_read,
			num_blocks_hashed,
			num_blocks_cache_hits,
			num_write_ops,
			num_read_ops,
			num_read_back,

			disk_read_time,
			disk_write_time,
			disk_hash_time,
			disk_job_time,

			waste_piece_timed_out,
			waste_piece_cancelled,
			waste_piece_unknown,
			waste_piece_seed,
			waste_piece_end_game,
			waste_piece_closing,

			sent_payload_bytes,
			sent_bytes,
			sent_ip_overhead_bytes,
			sent_tracker_bytes,
			recv_payload_bytes,
			recv_bytes,
			recv_ip_overhead_bytes,
			recv_tracker_bytes,

			recv_failed_bytes,
			recv_redundant_bytes,

			dht_messages_in,
			dht_messages_out,
			dht_messages_out_dropped,
			dht_bytes_in,
			dht_bytes_out,

			dht_ping_in,
			dht_ping_out,
			dht_find_node_in,
			dht_find_node_out,
			dht_get_peers_in,
			dht_get_peers_out,
			dht_announce_peer_in,
			dht_announce_peer_out,
			dht_get_in,
			dht_get_out,
			dht_put_in,
			dht_put_out,

			// uTP counters
			utp_packet_loss,
			utp_timeout,
			utp_packets_in,
			utp_packets_out,
			utp_fast_retransmit,
			utp_packet_resend,
			utp_samples_above_target,
			utp_samples_below_target,
			utp_payload_pkts_in,
			utp_payload_pkts_out,
			utp_invalid_pkts_in,
			utp_redundant_pkts_in,

			// the buffer sizes accepted by
			// socket send calls. The larger
			// the more efficient. The size is
			// 1 << n, where n is the number
			// at the end of the counter name

			// 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
			// 16384, 32768, 65536, 131072, 262144, 524288, 1048576
			socket_send_size3,
			socket_send_size4,
			socket_send_size5,
			socket_send_size6,
			socket_send_size7,
			socket_send_size8,
			socket_send_size9,
			socket_send_size10,
			socket_send_size11,
			socket_send_size12,
			socket_send_size13,
			socket_send_size14,
			socket_send_size15,
			socket_send_size16,
			socket_send_size17,
			socket_send_size18,
			socket_send_size19,
			socket_send_size20,

			// the buffer sizes returned by
			// socket recv calls. The larger
			// the more efficient. The size is
			// 1 << n, where n is the number
			// at the end of the counter name

			// 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
			// 16384, 32768, 65536, 131072, 262144, 524288, 1048576
			socket_recv_size3,
			socket_recv_size4,
			socket_recv_size5,
			socket_recv_size6,
			socket_recv_size7,
			socket_recv_size8,
			socket_recv_size9,
			socket_recv_size10,
			socket_recv_size11,
			socket_recv_size12,
			socket_recv_size13,
			socket_recv_size14,
			socket_recv_size15,
			socket_recv_size16,
			socket_recv_size17,
			socket_recv_size18,
			socket_recv_size19,
			socket_recv_size20,

			num_stats_counters
		};

		// it is important that all gauges have a higher index than counters.
		// This assumption is relied upon in other parts of the code
		enum stats_gauges_t
		{
			num_checking_torrents = num_stats_counters,
			num_stopped_torrents,
			// upload_only means finished
			num_upload_only_torrents,
			num_downloading_torrents,
			num_seeding_torrents,
			num_queued_seeding_torrents,
			num_queued_download_torrents,
			num_error_torrents,

			// the number of torrents that don't have the
			// IP filter applied to them.
			non_filter_torrents,

			// counters related to evicting torrents
			num_loaded_torrents,
			num_pinned_torrents,

			// these counter indices deliberatly
			// match the order of socket type IDs
			// defined in socket_type.hpp.
			num_tcp_peers,
			num_socks5_peers,
			num_http_proxy_peers,
			num_utp_peers,
			num_i2p_peers,
			num_ssl_peers,
			num_ssl_socks5_peers,
			num_ssl_http_proxy_peers,
			num_ssl_utp_peers,

			num_peers_half_open,
			num_peers_connected,
			num_peers_up_interested,
			num_peers_down_interested,
			num_peers_up_unchoked,
			num_peers_down_unchoked,
			num_peers_up_requests,
			num_peers_down_requests,
			num_peers_up_disk,
			num_peers_down_disk,
			num_peers_end_game,

			write_cache_blocks,
			read_cache_blocks,
			request_latency,
			pinned_blocks,
			disk_blocks_in_use,
			queued_disk_jobs,
			num_read_jobs,
			num_write_jobs,
			num_jobs,
			num_writing_threads,
			num_running_threads,
			blocked_disk_jobs,
			queued_write_bytes,
			num_unchoke_slots,

			arc_mru_size,
			arc_mru_ghost_size,
			arc_mfu_size,
			arc_mfu_ghost_size,
			arc_write_size,
			arc_volatile_size,

			dht_nodes,
			dht_node_cache,
			dht_torrents,
			dht_peers,
			dht_immutable_data,
			dht_mutable_data,
			dht_allocated_observers,

			has_incoming_connections,

			limiter_up_queue,
			limiter_down_queue,
			limiter_up_bytes,
			limiter_down_bytes,

			num_counters,
			num_gauge_counters = num_counters - num_stats_counters
		};

		counters();

		counters(counters const&);
		counters& operator=(counters const&);

		// returns the new value
		boost::int64_t inc_stats_counter(int c, boost::int64_t value = 1);
		boost::int64_t operator[](int i) const;

		void set_value(int c, boost::int64_t value);
		void blend_stats_counter(int c, boost::int64_t value, int ratio);

	private:

		// TODO: some space could be saved here by making gauges 32 bits
		// TODO: restore these to regular integers. Instead have one copy
		// of the counters per thread and collect them at convenient
		// synchronization points
#if BOOST_ATOMIC_LLONG_LOCK_FREE == 2
		boost::atomic<boost::int64_t> m_stats_counter[num_counters];
#else
		// if the atomic type is't lock-free, use a single lock instead, for
		// the whole array
		mutex m_mutex;
		boost::int64_t m_stats_counter[num_counters];
#endif
	};
}

#endif

<|endoftext|>


<commit_before>//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2015 KONDO Takatoshi
//
//    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.
//
#ifndef MSGPACK_TYPE_VECTOR_BOOL_FWD_HPP
#define MSGPACK_TYPE_VECTOR_BOOL_FWD_HPP

#include "msgpack/versioning.hpp"
#include "msgpack/object_fwd.hpp"

namespace msgpack {

MSGPACK_API_VERSION_NAMESPACE(v1) {

object const& operator>> (object const& o, std::vector<bool>& v);

}  // MSGPACK_API_VERSION_NAMESPACE(v1)

}  // namespace msgpack

#endif // MSGPACK_TYPE_VECTOR_BOOL_FWD_HPP
<commit_msg>Included vector header.<commit_after>//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2015 KONDO Takatoshi
//
//    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.
//
#ifndef MSGPACK_TYPE_VECTOR_BOOL_FWD_HPP
#define MSGPACK_TYPE_VECTOR_BOOL_FWD_HPP

#include "msgpack/versioning.hpp"
#include "msgpack/object_fwd.hpp"
#include <vector>

namespace msgpack {

MSGPACK_API_VERSION_NAMESPACE(v1) {

object const& operator>> (object const& o, std::vector<bool>& v);

}  // MSGPACK_API_VERSION_NAMESPACE(v1)

}  // namespace msgpack

#endif // MSGPACK_TYPE_VECTOR_BOOL_FWD_HPP
<|endoftext|>


<commit_before>#pragma once
// mathlib.hpp: definition of mathematical functions for the classic cfloats
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include <universal/number/cfloat/math/classify.hpp>
#include <universal/number/cfloat/math/complex.hpp>
#include <universal/number/cfloat/math/error_and_gamma.hpp>
#include <universal/number/cfloat/math/exponent.hpp>
#include <universal/number/cfloat/math/fractional.hpp>
#include <universal/number/cfloat/math/hyperbolic.hpp>
#include <universal/number/cfloat/math/hypot.hpp>
#include <universal/number/cfloat/math/logarithm.hpp>
#include <universal/number/cfloat/math/minmax.hpp>
#include <universal/number/cfloat/math/next.hpp>
#include <universal/number/cfloat/math/pow.hpp>
#include <universal/number/cfloat/math/sqrt.hpp>
#include <universal/number/cfloat/math/trigonometry.hpp>
#include <universal/number/cfloat/math/truncate.hpp>

<commit_msg>updating copyright date<commit_after>#pragma once
// mathlib.hpp: definition of mathematical functions for the classic cfloats
//
// Copyright (C) 2017-2022 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include <universal/number/cfloat/math/classify.hpp>
#include <universal/number/cfloat/math/complex.hpp>
#include <universal/number/cfloat/math/error_and_gamma.hpp>
#include <universal/number/cfloat/math/exponent.hpp>
#include <universal/number/cfloat/math/fractional.hpp>
#include <universal/number/cfloat/math/hyperbolic.hpp>
#include <universal/number/cfloat/math/hypot.hpp>
#include <universal/number/cfloat/math/logarithm.hpp>
#include <universal/number/cfloat/math/minmax.hpp>
#include <universal/number/cfloat/math/next.hpp>
#include <universal/number/cfloat/math/pow.hpp>
#include <universal/number/cfloat/math/sqrt.hpp>
#include <universal/number/cfloat/math/trigonometry.hpp>
#include <universal/number/cfloat/math/truncate.hpp>

<|endoftext|>