text:
#include "fieldtrack/TargetInfoManager.h"
#include <boost/foreach.hpp>

#define MOTION_KEY "motion_mode"
#define ODOMETRY_KEY "odometry_topic"
#define DETECTION_KEY "detection_topic"
#define CAMERAGROUP_KEY "camera_groups"
#define CAMERAS_KEY "cameras"
#define FIDUCIALGROUP_KEY "fiducial_groups"
#define FIDUCIALS_KEY "fiducials"

namespace argus
{

TargetInfoManager::TargetInfoManager( LookupInterface& interface )
: InfoManager( interface )
{}

bool TargetInfoManager::ParseMemberInfo( const std::string& memberNamespace,
                                         TargetInfo& info )
{
	// Parse motion mode
	std::string motionString;
	std::string motionKey = memberNamespace + MOTION_KEY;
	if( !_nodeHandle.getParam( motionKey, motionString ) )
	{
		ROS_WARN_STREAM( "Could not find motion mode information at path " << motionKey );
		return false;
	}
	info.motionMode = StringToMotion( motionString );
	if( info.motionMode == MOTION_INVALID )
	{
		ROS_WARN_STREAM( "Read invalid motion mode string of: " << motionString
			<< " at path " << motionKey );
		return false;
	}

	// Parse odometry topic
	std::string odomTopic;
	if( _nodeHandle.getParam( memberNamespace + ODOMETRY_KEY, odomTopic ) )
	{
		if( odomTopic.front() == '/' ) { info.odometryTopic = odomTopic; }
		else { info.odometryTopic = memberNamespace + odomTopic; }
	}

	// Parse odometry topic
	std::string detTopic;
	if( _nodeHandle.getParam( memberNamespace + DETECTION_KEY, detTopic ) )
	{
		if( detTopic.front() == '/' ) { info.detectionTopic = detTopic; }
		else { info.detectionTopic = memberNamespace + detTopic; }
	}

	// Parse camera groups
	std::vector<std::string> cameraGroups;
	if( _nodeHandle.getParam( memberNamespace + CAMERAGROUP_KEY, cameraGroups ) )
	{
		BOOST_FOREACH( const std::string& group, cameraGroups )
		{
			CameraGroupInfo cginfo;
			if( !ParseCameraGroup( memberNamespace + group + "/", cginfo ) )
			{
				ROS_WARN_STREAM( "Could not parse camera group info for group: " << group );
				return false;
			}
			info.cameraGroups[ group ] = cginfo;
		}
	}

	// Parse fiducial groups
	std::vector<std::string> fiducialGroups;
	if( _nodeHandle.getParam( memberNamespace + FIDUCIALGROUP_KEY, fiducialGroups ) )
	{
		BOOST_FOREACH( const std::string& group, fiducialGroups )
		{
			FiducialGroupInfo fginfo;
			if( !ParseFiducialGroup( memberNamespace + group + "/", fginfo ) )
			{
				ROS_WARN_STREAM( "Could not parse fiducial group info for group: " << group );
				return false;
			}
			info.fiducialGroups[ group ] = fginfo;
		}
	}
	return true;
}

void TargetInfoManager::PopulateMemberInfo( const TargetInfo& info,
                                            const std::string& memberNamespace )
{
	_nodeHandle.setParam( memberNamespace + MOTION_KEY,
	                     MotionToString( info.motionMode ) );

	// TODO Write other parameters
}

bool TargetInfoManager::ParseCameraGroup( const std::string& ns,
                                          CameraGroupInfo& info )
{
	return _nodeHandle.getParam( ns + CAMERAS_KEY, info.cameras );
}

bool TargetInfoManager::ParseFiducialGroup( const std::string& ns,
                                            FiducialGroupInfo& info )
{
	return _nodeHandle.getParam( ns + FIDUCIALS_KEY, info.fiducials );
}

std::string MotionToString( MotionMode mode )
{
	switch( mode )
	{
		case MOTION_INDEPENDENT:
			return "independent";
		case MOTION_STATIC:
			return "static";
		case MOTION_MOVING:
			return "moving";
		default:
			return "invalid";
	}
}

MotionMode StringToMotion( const std::string& mode )
{
	if( mode == "independent" ) { return MOTION_INDEPENDENT; }
	if( mode == "static" ) { return MOTION_STATIC; }
	if( mode == "moving" ) { return MOTION_MOVING; }
	return MOTION_INVALID;
}

}

max_stars_repo_name: Humhu/fieldtrack

max_issues_repo_name: Humhu/fieldtrack

max_forks_repo_name: Humhu/fieldtrack


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

// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.

// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.

// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle

// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.

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

#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP

#include <boost/geometry/core/access.hpp>

#include <boost/geometry/strategies/distance.hpp>

#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/calculation_type.hpp>

namespace geofeatures_boost {} namespace boost = geofeatures_boost; namespace geofeatures_boost { namespace geometry
{

namespace strategy { namespace distance
{

#ifndef DOXYGEN_NO_DETAIL
namespace detail
{

template <std::size_t I>
struct compute_pythagoras_box_box
{
    template <typename Box1, typename Box2, typename T>
    static inline void apply(Box1 const& box1, Box2 const& box2, T& result)
    {
        T const b1_min_coord =
            geofeatures_boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box1));
        T const b1_max_coord =
            geofeatures_boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box1));

        T const b2_min_coord =
            geofeatures_boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box2));
        T const b2_max_coord =
            geofeatures_boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box2));

        if ( b1_max_coord < b2_min_coord )
        {
            T diff = b2_min_coord - b1_max_coord;
            result += diff * diff;
        }
        if ( b1_min_coord > b2_max_coord )
        {
            T diff = b1_min_coord - b2_max_coord;
            result += diff * diff;
        }

        compute_pythagoras_box_box<I-1>::apply(box1, box2, result);
    }
};

template <>
struct compute_pythagoras_box_box<0>
{
    template <typename Box1, typename Box2, typename T>
    static inline void apply(Box1 const&, Box2 const&, T&)
    {
    }
};

}
#endif // DOXYGEN_NO_DETAIL

namespace comparable
{

/*!
\brief Strategy to calculate comparable distance between two boxes
\ingroup strategies
\tparam Box1 \tparam_first_box
\tparam Box2 \tparam_second_box
\tparam CalculationType \tparam_calculation
*/
template <typename CalculationType = void>
class pythagoras_box_box
{
public :

    template <typename Box1, typename Box2>
    struct calculation_type
    {
        typedef typename util::calculation_type::geometric::binary
            <
                Box1,
                Box2,
                CalculationType
            >::type type;
    };

    template <typename Box1, typename Box2>
    static inline typename calculation_type<Box1, Box2>::type
    apply(Box1 const& box1, Box2 const& box2)
    {
        BOOST_CONCEPT_ASSERT
            ( (concept::ConstPoint<typename point_type<Box1>::type>) );
        BOOST_CONCEPT_ASSERT
            ( (concept::ConstPoint<typename point_type<Box2>::type>) );

        // Calculate distance using Pythagoras
        // (Leave comment above for Doxygen)

        assert_dimension_equal<Box1, Box2>();

        typename calculation_type<Box1, Box2>::type result(0);

        detail::compute_pythagoras_box_box
            <
                dimension<Box1>::value
            >::apply(box1, box2, result);

        return result;
    }
};

} // namespace comparable

/*!
\brief Strategy to calculate the distance between two boxes
\ingroup strategies
\tparam CalculationType \tparam_calculation

\qbk{
[heading Notes]
[note Can be used for boxes with two\, three or more dimensions]
[heading See also]
[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
}

*/
template
<
    typename CalculationType = void
>
class pythagoras_box_box
{
public :

    template <typename Box1, typename Box2>
    struct calculation_type
        : util::calculation_type::geometric::binary
          <
              Box1,
              Box2,
              CalculationType,
              double,
              double // promote integer to double
          >
    {};

    /*!
    \brief applies the distance calculation using pythagoras_box_box
    \return the calculated distance (including taking the square root)
    \param box1 first box
    \param box2 second box
    */
    template <typename Box1, typename Box2>
    static inline typename calculation_type<Box1, Box2>::type
    apply(Box1 const& box1, Box2 const& box2)
    {
        // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
        return math::sqrt
            (
                 geofeatures_boost::numeric_cast<typename calculation_type
                     <
                         Box1, Box2
                     >::type>
                    (
                        comparable::pythagoras_box_box
                            <
                                CalculationType
                            >::apply(box1, box2)
                    )
            );
    }
};

#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{

template <typename CalculationType>
struct tag<pythagoras_box_box<CalculationType> >
{
    typedef strategy_tag_distance_box_box type;
};

template <typename CalculationType, typename Box1, typename Box2>
struct return_type<distance::pythagoras_box_box<CalculationType>, Box1, Box2>
    : pythagoras_box_box<CalculationType>::template calculation_type<Box1, Box2>
{};

template <typename CalculationType>
struct comparable_type<pythagoras_box_box<CalculationType> >
{
    typedef comparable::pythagoras_box_box<CalculationType> type;
};

template <typename CalculationType>
struct get_comparable<pythagoras_box_box<CalculationType> >
{
    typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
public :
    static inline comparable_type
    apply(pythagoras_box_box<CalculationType> const& )
    {
        return comparable_type();
    }
};

template <typename CalculationType, typename Box1, typename Box2>
struct result_from_distance<pythagoras_box_box<CalculationType>, Box1, Box2>
{
private:
    typedef typename return_type
        <
            pythagoras_box_box<CalculationType>, Box1, Box2
        >::type return_type;
public:
    template <typename T>
    static inline return_type
    apply(pythagoras_box_box<CalculationType> const& , T const& value)
    {
        return return_type(value);
    }
};

// Specializations for comparable::pythagoras_box_box
template <typename CalculationType>
struct tag<comparable::pythagoras_box_box<CalculationType> >
{
    typedef strategy_tag_distance_box_box type;
};

template <typename CalculationType, typename Box1, typename Box2>
struct return_type<comparable::pythagoras_box_box<CalculationType>, Box1, Box2>
    : comparable::pythagoras_box_box
        <
            CalculationType
        >::template calculation_type<Box1, Box2>
{};

template <typename CalculationType>
struct comparable_type<comparable::pythagoras_box_box<CalculationType> >
{
    typedef comparable::pythagoras_box_box<CalculationType> type;
};

template <typename CalculationType>
struct get_comparable<comparable::pythagoras_box_box<CalculationType> >
{
    typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
public :
    static inline comparable_type apply(comparable_type const& )
    {
        return comparable_type();
    }
};

template <typename CalculationType, typename Box1, typename Box2>
struct result_from_distance
    <
        comparable::pythagoras_box_box<CalculationType>, Box1, Box2
    >
{
private :
    typedef typename return_type
        <
            comparable::pythagoras_box_box<CalculationType>, Box1, Box2
        >::type return_type;
public :
    template <typename T>
    static inline return_type
    apply(comparable::pythagoras_box_box<CalculationType> const&,
          T const& value)
    {
        return_type const v = value;
        return v * v;
    }
};

template <typename BoxPoint1, typename BoxPoint2>
struct default_strategy
    <
        box_tag, box_tag, BoxPoint1, BoxPoint2, cartesian_tag, cartesian_tag
    >
{
    typedef pythagoras_box_box<> type;
};

} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

}} // namespace strategy::distance

}} // namespace geofeatures_boost::geometry

#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP

ext: hpp

max_stars_repo_name: xarvey/Yuuuuuge

max_issues_repo_name: xarvey/Yuuuuuge

max_forks_repo_name: xarvey/Yuuuuuge


text:
//---------------------------------------------------------------------------//
//!
//! \file   MonteCarlo_SimulationGeneralProperties.hpp
//! \author Alex Robinson, Luke Kersting
//! \brief  Simulation general properties class decl.
//!
//---------------------------------------------------------------------------//

#ifndef MONTE_CARLO_SIMULATION_GENERAL_PROPERTIES_HPP
#define MONTE_CARLO_SIMULATION_GENERAL_PROPERTIES_HPP

// Boost Includes
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/export.hpp>

// FRENSIE Includes
#include "MonteCarlo_ParticleModeType.hpp"
#include "Utility_QuantityTraits.hpp"
#include "Utility_ExplicitSerializationTemplateInstantiationMacros.hpp"

namespace MonteCarlo{

/*! The general simulation properties class
 *
 * Use this class in all parts of code that require runtime configuration.
 */
class SimulationGeneralProperties
{

public:

  //! Constructor
  SimulationGeneralProperties();

  //! Destructor
  virtual ~SimulationGeneralProperties()
  { /* ... */ }

  //! Set the particle mode
  void setParticleMode( const ParticleModeType particle_mode );

  //! Return the particle mode type
  ParticleModeType getParticleMode() const;

  //! Set the number of histories to run
  void setNumberOfHistories( const uint64_t histories );

  //! Return the number of histories to run
  uint64_t getNumberOfHistories() const;

  //! Set the minimum number of rendezvous per simulation
  void setMinNumberOfRendezvous( const uint64_t rendezvous );

  //! Return the mimimum number of rendezvous per simulation
  uint64_t getMinNumberOfRendezvous() const;

  //! Set the maximum rendezvous batch size
  void setMaxRendezvousBatchSize( const uint64_t max_batch_size );

  //! Get the maximum rendezvous batch size
  uint64_t getMaxRendezvousBatchSize() const;

  //! Set the minimum number of batches per rendezvous
  void setMinNumberOfBatchesPerRendezvous( const uint64_t batches );

  //! Get the minimum number of batches per rendezvous
  uint64_t getMinNumberOfBatchesPerRendezvous() const;

  //! Set the maximum batch size
  void setMaxBatchSize( const uint64_t max_batch_size );

  //! Get the maximum batch size
  uint64_t getMaxBatchSize() const;

  //! Set the number of batches for an MPI configuration
  void setNumberOfBatchesPerProcessor( const uint64_t batches_per_processor );

  //! Return the number of batches for an MPI configuration
  uint64_t getNumberOfBatchesPerProcessor() const;

  //! Set the number of snapshots per batch
  void setNumberOfSnapshotsPerBatch( const uint64_t snapshots_per_batch );

  //! Get the number of snapshots per batch
  uint64_t getNumberOfSnapshotsPerBatch() const;

  //! Set the history simulation wall time (s)
  void setSimulationWallTime( const double wall_time );

  //! Return the history simulation wall time (s)
  double getSimulationWallTime() const;

  //! Set implicit capture mode to on (off by default)
  void setImplicitCaptureModeOn();

  //! Set analogue capture mode to on (on by default)
  void setAnalogueCaptureModeOn();

  //! Return if implicit capture mode has been set
  bool isImplicitCaptureModeOn() const;

private:

  // Save the state to an archive
  template<typename Archive>
  void save( Archive& ar, const unsigned version ) const;

  // Load the state from an archive
  template<typename Archive>
  void load( Archive& ar, const unsigned version );

  BOOST_SERIALIZATION_SPLIT_MEMBER();

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

  // The particle mode
  ParticleModeType d_particle_mode;

  // The number of histories to run
  uint64_t d_number_of_histories;

  // The minimum number of rendezvous per simulation
  uint64_t d_min_number_of_rendezvous;

  // The maximum rendezvous batch size
  uint64_t d_max_rendezvous_batch_size;

  // The minimum number of batches per rendezvous
  uint64_t d_min_number_of_batches_per_rendezvous;

  // The maximum batch size
  uint64_t d_max_batch_size;

  // The number of batches to run for MPI configuration
  uint64_t d_number_of_batches_per_processor;

  // The number of snapshots per batch
  uint64_t d_number_of_snapshots_per_batch;

  // The simulation wall time
  double d_wall_time;

  // The capture mode (true = implicit, false = analogue - default)
  bool d_implicit_capture_mode_on;
};

// Save the state to an archive
template<typename Archive>
void SimulationGeneralProperties::save( Archive& ar, const unsigned version ) const
{
  ar & BOOST_SERIALIZATION_NVP( d_particle_mode );
  ar & BOOST_SERIALIZATION_NVP( d_number_of_histories );
  ar & BOOST_SERIALIZATION_NVP( d_min_number_of_rendezvous );
  ar & BOOST_SERIALIZATION_NVP( d_max_rendezvous_batch_size );
  ar & BOOST_SERIALIZATION_NVP( d_min_number_of_batches_per_rendezvous );
  ar & BOOST_SERIALIZATION_NVP( d_max_batch_size );
  ar & BOOST_SERIALIZATION_NVP( d_number_of_batches_per_processor );
  ar & BOOST_SERIALIZATION_NVP( d_number_of_snapshots_per_batch );

  // We cannot safely serialize inf to all archive types - create a flag that
  // records if the simulation wall time is inf
  const bool __inf_wall_time__ =
    (d_wall_time == Utility::QuantityTraits<double>::inf());

  ar & BOOST_SERIALIZATION_NVP( __inf_wall_time__ );

  if( __inf_wall_time__ )
  {
    double tmp_wall_time = Utility::QuantityTraits<double>::max();

    ar & boost::serialization::make_nvp( "d_wall_time", tmp_wall_time );
  }
  else
  {
    ar & BOOST_SERIALIZATION_NVP( d_wall_time );
  }

  ar & BOOST_SERIALIZATION_NVP( d_implicit_capture_mode_on );
}

// Load the state to an archive
template<typename Archive>
void SimulationGeneralProperties::load( Archive& ar, const unsigned version )
{
  ar & BOOST_SERIALIZATION_NVP( d_particle_mode );
  ar & BOOST_SERIALIZATION_NVP( d_number_of_histories );
  ar & BOOST_SERIALIZATION_NVP( d_min_number_of_rendezvous );
  ar & BOOST_SERIALIZATION_NVP( d_max_rendezvous_batch_size );
  ar & BOOST_SERIALIZATION_NVP( d_min_number_of_batches_per_rendezvous );
  ar & BOOST_SERIALIZATION_NVP( d_max_batch_size );
  ar & BOOST_SERIALIZATION_NVP( d_number_of_batches_per_processor );
  ar & BOOST_SERIALIZATION_NVP( d_number_of_snapshots_per_batch );

  // Load the wall time
  bool __inf_wall_time__;
  ar & BOOST_SERIALIZATION_NVP( __inf_wall_time__ );
  ar & BOOST_SERIALIZATION_NVP( d_wall_time );

  if( __inf_wall_time__ )
    d_wall_time = Utility::QuantityTraits<double>::inf();

  ar & BOOST_SERIALIZATION_NVP( d_implicit_capture_mode_on );
}

} // end MonteCarlo namespace

#if !defined SWIG

BOOST_CLASS_VERSION( MonteCarlo::SimulationGeneralProperties, 0 );
BOOST_CLASS_EXPORT_KEY2( MonteCarlo::SimulationGeneralProperties, "SimulationGeneralProperties" );
EXTERN_EXPLICIT_CLASS_SERIALIZE_INST( MonteCarlo, SimulationGeneralProperties );

#endif // end !defined SWIG

#endif // end MONTE_CARLO_SIMULATION_GENERAL_PROPERTIES_HPP

//---------------------------------------------------------------------------//
// end MonteCarlo_SimulationGeneralProperties.cpp
//---------------------------------------------------------------------------//


text:
///////////////////////////////////////////////////////////////////////////////
// keeper_matcher.hpp
//
//  Copyright 2004 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_KEEPER_MATCHER_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_KEEPER_MATCHER_HPP_EAN_10_04_2005

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <boost/mpl/bool.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/core/quant_style.hpp>
#include <boost/xpressive/detail/core/state.hpp>
#include <boost/xpressive/detail/static/is_pure.hpp>

namespace boost { namespace xpressive { namespace detail
{

    ///////////////////////////////////////////////////////////////////////////////
    // keeper_matcher
    //       Xpr can be either a static_xpression, or a shared_ptr<matchable>
    template<typename Xpr>
    struct keeper_matcher
      : quant_style_auto<width_of<Xpr>, is_pure<Xpr> >
    {
        keeper_matcher(Xpr const &xpr, bool do_save = !is_pure<Xpr>::value)
          : xpr_(xpr)
          , do_save_(do_save)
        {
        }

        template<typename BidiIter, typename Next>
        bool match(state_type<BidiIter> &state, Next const &next) const
        {
            // Note that if is_pure<Xpr>::value is true, the compiler can tell which
            // branch to take.
            return is_pure<Xpr>::value || !this->do_save_
                ? this->match_(state, next, mpl::true_())
                : this->match_(state, next, mpl::false_());
        }

        template<typename BidiIter, typename Next>
        bool match_(state_type<BidiIter> &state, Next const &next, mpl::true_) const
        {
            BidiIter const tmp = state.cur_;

            // matching xpr is guaranteed to not produce side-effects, don't bother saving state
            if(!get_pointer(this->xpr_)->match(state))
            {
                return false;
            }
            else if(next.match(state))
            {
                return true;
            }

            state.cur_ = tmp;
            return false;
        }

        template<typename BidiIter, typename Next>
        bool match_(state_type<BidiIter> &state, Next const &next, mpl::false_) const
        {
            BidiIter const tmp = state.cur_;

            // matching xpr could produce side-effects, save state
            memento<BidiIter> mem = save_sub_matches(state);

            if(!get_pointer(this->xpr_)->match(state))
            {
                reclaim_sub_matches(mem, state);
                return false;
            }
            else if(next.match(state))
            {
                reclaim_sub_matches(mem, state);
                return true;
            }

            restore_sub_matches(mem, state);
            state.cur_ = tmp;
            return false;
        }

        Xpr xpr_;
        bool do_save_; // true if matching xpr_ could modify the sub-matches
    };

}}}

#endif


text:
#include <tiny.h>
#include <convex.h>

#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/test_tools.hpp>

// 2011-11-12 Kenny: Does these test depend on the order in which vertices are added to the simplex? We always use a,b,c

BOOST_AUTO_TEST_SUITE(convex_reduce_triangle);

BOOST_AUTO_TEST_CASE(case_by_case_test)
{
  typedef tiny::MathTypes<double>         math_types;
  typedef math_types::vector3_type        vector3_type;
  typedef math_types::real_type           real_type;

  typedef convex::Simplex<vector3_type>           simplex_type;

  // Inside face-region new simplex should be ABC
  {
    vector3_type const a = vector3_type::make(-1.0, -1.0, 0.0);
    vector3_type const b = vector3_type::make( 1.0, -1.0, 0.0);
    vector3_type const c = vector3_type::make( 0.5,  0.1, 0.0);

    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    for( size_t i=1u; i<10u; ++i)
      for( size_t j=1u; j<10u; ++j)
        for( size_t k=1u; k<10u; ++k)
        {
          real_type u = i*0.1;
          real_type v = j*0.1;
          real_type w = k*0.1;

          real_type lgh = u + v + w;
          u /= lgh;
          v /= lgh;
          w /= lgh;

          vector3_type const p = u*a + v*b + w*c;

          convex::reduce_triangle( p, S );

          BOOST_CHECK( convex::dimension( S ) == 3u );

          int bit_A    = 0;
          size_t idx_A = 0;
          int bit_B    = 0;
          size_t idx_B = 0;
          int bit_C    = 0;
          size_t idx_C = 0;
          convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B , idx_C, bit_C );

          BOOST_CHECK(S.m_bitmask == (bit_A | bit_B | bit_C));

          BOOST_CHECK(S.m_v[idx_A] == a);
          BOOST_CHECK(S.m_a[idx_A] == a);
          BOOST_CHECK(S.m_b[idx_A] == a);

          BOOST_CHECK(S.m_v[idx_B] == b);
          BOOST_CHECK(S.m_a[idx_B] == b);
          BOOST_CHECK(S.m_b[idx_B] == b);

          BOOST_CHECK(S.m_v[idx_C] == c);
          BOOST_CHECK(S.m_a[idx_C] == c);
          BOOST_CHECK(S.m_b[idx_C] == c);
          BOOST_CHECK_CLOSE(S.m_w[idx_A], u, 0.01);
          BOOST_CHECK_CLOSE(S.m_w[idx_B], v, 0.01);
          BOOST_CHECK_CLOSE(S.m_w[idx_C], w, 0.01);

        }
  }
  // First we create a simplex that represents an triangle
  vector3_type const a = vector3_type::make(-1.0, -1.0, 0.0);
  vector3_type const b = vector3_type::make( 1.0, -1.0, 0.0);
  vector3_type const c = vector3_type::make( 0.0,  1.0, 0.0);

  // Inside face-region new simplex should be ABC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( 0.0, 0.0,  0.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 3u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    int bit_C    = 0;
    size_t idx_C = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B , idx_C, bit_C );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B | bit_C));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == b);
    BOOST_CHECK(S.m_a[idx_B] == b);
    BOOST_CHECK(S.m_b[idx_B] == b);

    BOOST_CHECK(S.m_v[idx_C] == c);
    BOOST_CHECK(S.m_a[idx_C] == c);
    BOOST_CHECK(S.m_b[idx_C] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.25, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.25, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_C], 0.5, 0.01);
  }
  // Inside A voronoi region new simplex should be A
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( -2.0, -1.0,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 1u );

    int bit_A    = 0;
    size_t idx_A = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A );

    BOOST_CHECK(S.m_bitmask == bit_A);
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 1.0, 0.01);
  }
  // Inside B voronoi region new simplex should be B
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make(  2.0, -1.0,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 1u );

    int bit_A    = 0;
    size_t idx_A = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A );

    BOOST_CHECK(S.m_bitmask == bit_A);
    BOOST_CHECK(S.m_v[idx_A] == b);
    BOOST_CHECK(S.m_a[idx_A] == b);
    BOOST_CHECK(S.m_b[idx_A] == b);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 1.00, 0.01);
  }
  // Inside C voronoi region new simplex should be C
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make(  0.0, 2.0,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 1u );

    int bit_A    = 0;
    size_t idx_A = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A  );

    BOOST_CHECK(S.m_bitmask == bit_A);
    BOOST_CHECK(S.m_v[idx_A] == c);
    BOOST_CHECK(S.m_a[idx_A] == c);
    BOOST_CHECK(S.m_b[idx_A] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 1.0, 0.01);
  }
  // Inside AB voronoi region new simplex should be AB
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( 0.0, -2.0,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == b);
    BOOST_CHECK(S.m_a[idx_B] == b);
    BOOST_CHECK(S.m_b[idx_B] == b);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.5, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.5, 0.01);
  }
  // Inside BC voronoi region new simplex should be BC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( 1.5, 0.5,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == b);
    BOOST_CHECK(S.m_a[idx_A] == b);
    BOOST_CHECK(S.m_b[idx_A] == b);

    BOOST_CHECK(S.m_v[idx_B] == c);
    BOOST_CHECK(S.m_a[idx_B] == c);
    BOOST_CHECK(S.m_b[idx_B] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.5, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.5, 0.01);
  }
  // Inside AC voronoi region new simplex should be AC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( -1.5, 0.5,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == c);
    BOOST_CHECK(S.m_a[idx_B] == c);
    BOOST_CHECK(S.m_b[idx_B] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.5, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.5, 0.01);
  }
  // On vertex A new simplex should be A
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    convex::reduce_triangle( a, S );

    BOOST_CHECK( convex::dimension( S ) == 1u );

    int bit_A    = 0;
    size_t idx_A = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A );

    BOOST_CHECK(S.m_bitmask == bit_A);
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 1.0, 0.01);
  }
  // On vertex B new simplex should be B
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    convex::reduce_triangle( b, S );

    BOOST_CHECK( convex::dimension( S ) == 1u );

    int bit_A    = 0;
    size_t idx_A = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A );

    BOOST_CHECK(S.m_bitmask == bit_A);
    BOOST_CHECK(S.m_v[idx_A] == b);
    BOOST_CHECK(S.m_a[idx_A] == b);
    BOOST_CHECK(S.m_b[idx_A] == b);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 1.00, 0.01);
  }
  // On vertex C new simplex should be C
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    convex::reduce_triangle( c, S );

    BOOST_CHECK( convex::dimension( S ) == 1u );

    int bit_A    = 0;
    size_t idx_A = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A  );

    BOOST_CHECK(S.m_bitmask == bit_A);
    BOOST_CHECK(S.m_v[idx_A] == c);
    BOOST_CHECK(S.m_a[idx_A] == c);
    BOOST_CHECK(S.m_b[idx_A] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 1.0, 0.01);
  }
  // On edge AB new simplex should be AB
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( 0.0, -1.0,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == b);
    BOOST_CHECK(S.m_a[idx_B] == b);
    BOOST_CHECK(S.m_b[idx_B] == b);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.5, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.5, 0.01);
  }
  // On edge BC new simplex should be BC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( 0.5, 0.0,  1.0);// this point is inside the triangle?!

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == b);
    BOOST_CHECK(S.m_a[idx_A] == b);
    BOOST_CHECK(S.m_b[idx_A] == b);

    BOOST_CHECK(S.m_v[idx_B] == c);
    BOOST_CHECK(S.m_a[idx_B] == c);
    BOOST_CHECK(S.m_b[idx_B] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.5, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.5, 0.01);
  }
  // On edge AC new simplex should be AC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = vector3_type::make( -0.5, 0.0,  1.0);

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == c);
    BOOST_CHECK(S.m_a[idx_B] == c);
    BOOST_CHECK(S.m_b[idx_B] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.5, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.5, 0.01);
  }
  // Assymmetric test cases

  // New simplex should be AB
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = 0.4*a + 0.6*b;

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == b);
    BOOST_CHECK(S.m_a[idx_B] == b);
    BOOST_CHECK(S.m_b[idx_B] == b);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.4, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.6, 0.01);
  }
  // New simplex should be BC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = 0.4*b + 0.6*c;// point is inside triangle?!

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == b);
    BOOST_CHECK(S.m_a[idx_A] == b);
    BOOST_CHECK(S.m_b[idx_A] == b);

    BOOST_CHECK(S.m_v[idx_B] == c);
    BOOST_CHECK(S.m_a[idx_B] == c);
    BOOST_CHECK(S.m_b[idx_B] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.4, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.6, 0.01);
  }
  // New simplex should be AC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = 0.6*a + 0.4*c;

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 2u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B ));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == c);
    BOOST_CHECK(S.m_a[idx_B] == c);
    BOOST_CHECK(S.m_b[idx_B] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.6, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.4, 0.01);
  }
  // New simplex should be ABC
  {
    simplex_type S;

    convex::add_point_to_simplex( a, a, a, S);
    convex::add_point_to_simplex( b, b, b, S);
    convex::add_point_to_simplex( c, c, c, S);

    vector3_type const p = 0.1*a + 0.2*b + 0.7*c;

    convex::reduce_triangle( p, S );

    BOOST_CHECK( convex::dimension( S ) == 3u );

    int bit_A    = 0;
    size_t idx_A = 0;
    int bit_B    = 0;
    size_t idx_B = 0;
    int bit_C    = 0;
    size_t idx_C = 0;
    convex::get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B , idx_C, bit_C );

    BOOST_CHECK(S.m_bitmask == (bit_A | bit_B | bit_C));
    BOOST_CHECK(S.m_v[idx_A] == a);
    BOOST_CHECK(S.m_a[idx_A] == a);
    BOOST_CHECK(S.m_b[idx_A] == a);

    BOOST_CHECK(S.m_v[idx_B] == b);
    BOOST_CHECK(S.m_a[idx_B] == b);
    BOOST_CHECK(S.m_b[idx_B] == b);

    BOOST_CHECK(S.m_v[idx_C] == c);
    BOOST_CHECK(S.m_a[idx_C] == c);
    BOOST_CHECK(S.m_b[idx_C] == c);

    BOOST_CHECK_CLOSE(S.m_w[idx_A], 0.1, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_B], 0.2, 0.01);
    BOOST_CHECK_CLOSE(S.m_w[idx_C], 0.7, 0.01);
  }
}

BOOST_AUTO_TEST_SUITE_END();

ext: cpp

max_stars_repo_name: diku-dk/PROX

max_issues_repo_name: diku-dk/PROX

max_forks_repo_name: diku-dk/PROX


text: #include <boost/mpl/set/aux_/erase_key_impl.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*=============================================================================
    Copyright (c) 2003 Joel de Guzman
    Copyright (c) 2004 Peder Holt
    Copyright (c) 2005 Eric Niebler

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_SEQUENCE_CONS_HPP)
#define FUSION_SEQUENCE_CONS_HPP

#include <boost/call_traits.hpp>
#include <boost/spirit/fusion/detail/access.hpp>
#include <boost/spirit/fusion/sequence/begin.hpp>
#include <boost/spirit/fusion/sequence/end.hpp>
#include <boost/spirit/fusion/iterator/cons_iterator.hpp>
#include <boost/spirit/fusion/sequence/detail/cons_begin_end_traits.hpp>
#include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp>

namespace boost { namespace fusion
{
    struct void_t;

    struct cons_tag;

    struct nil : sequence_base<nil>
    {
        typedef cons_tag tag;
        typedef void_t car_type;
        typedef void_t cdr_type;
    };

    template <typename Car, typename Cdr = nil>
    struct cons : sequence_base<cons<Car,Cdr> >
    {
        typedef cons_tag tag;
        typedef typename call_traits<Car>::value_type car_type;
        typedef Cdr cdr_type;

        cons()
          : car(), cdr() {}

        explicit cons(
            typename call_traits<Car>::param_type car_
          , typename call_traits<Cdr>::param_type cdr_ = Cdr())
          : car(car_), cdr(cdr_) {}

        car_type car;
        cdr_type cdr;
    };

    template <typename Car>
    inline cons<Car>
    make_cons(Car const& car)
    {
        return cons<Car>(car);
    }

    template <typename Car, typename Cdr>
    inline cons<Car, Cdr>
    make_cons(Car const& car, Cdr const& cdr)
    {
        return cons<Car, Cdr>(car, cdr);
    }
}}

#endif

max_stars_repo_name: schinmayee/nimbus

max_issues_repo_name: schinmayee/nimbus

max_forks_repo_name: schinmayee/nimbus


text:
#pragma once

#include <arpa/inet.h>
#include <atomic>
#include <boost/context/continuation.hpp>
#include <chrono>
#include <iostream>
#include <thread>

namespace ctx = boost::context;

namespace li {

namespace http_benchmark_impl {

class timer {
public:
  void start() { start_ = std::chrono::high_resolution_clock::now(); }
  void end() { end_ = std::chrono::high_resolution_clock::now(); }

  unsigned long us() const {
    return std::chrono::duration_cast<std::chrono::microseconds>(end_ - start_).count();
  }

  unsigned long ms() const {
    return std::chrono::duration_cast<std::chrono::milliseconds>(end_ - start_).count();
  }

  unsigned long ns() const {
    return std::chrono::duration_cast<std::chrono::nanoseconds>(end_ - start_).count();
  }

private:
  std::chrono::time_point<std::chrono::high_resolution_clock> start_, end_;
};

void error(std::string msg) {
  perror(msg.c_str());
  exit(0);
}

} // namespace http_benchmark_impl

std::vector<int> http_benchmark_connect(int NCONNECTIONS, int port) {
  std::vector<int> sockets(NCONNECTIONS, 0);
  struct addrinfo hints, *serveraddr;

  /* socket: create the socket */
  for (int i = 0; i < sockets.size(); i++) {
    sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
    if (sockets[i] < 0)
      http_benchmark_impl::error("ERROR opening socket");
  }

  /* build the server's Internet address */
	struct sockaddr_in server;
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	server.sin_family = AF_INET;
	server.sin_port = htons( port );

  // Async connect.
  int epoll_fd = epoll_create1(0);

  auto epoll_ctl = [epoll_fd](int fd, int op, uint32_t flags) {
    epoll_event event;
    event.data.fd = fd;
    event.events = flags;
    ::epoll_ctl(epoll_fd, op, fd, &event);
    return true;
  };

  // Set sockets non blocking.
  for (int i = 0; i < sockets.size(); i++)
    fcntl(sockets[i], F_SETFL, fcntl(sockets[i], F_GETFL, 0) | O_NONBLOCK);

  for (int i = 0; i < sockets.size(); i++)
    epoll_ctl(sockets[i], EPOLL_CTL_ADD, EPOLLIN | EPOLLOUT | EPOLLET);

  /* connect: create a connection with the server */
  std::vector<bool> opened(sockets.size(), false);
  while (true) {
    for (int i = 0; i < sockets.size(); i++) {
      if (opened[i])
        continue;
      // int ret = connect(sockets[i], (const sockaddr*)serveraddr, sizeof(*serveraddr));
      int ret = connect(sockets[i], (const sockaddr*)&server, sizeof(server));
      if (ret == 0)
        opened[i] = true;
      else if (errno == EINPROGRESS || errno == EALREADY)
        continue;
      else
        http_benchmark_impl::error(std::string("Cannot connect to server: ") + strerror(errno));
    }

    int nopened = 0;
    for (int i = 0; i < sockets.size(); i++)
      nopened += opened[i];
    if (nopened == sockets.size())
      break;
  }

  close(epoll_fd);
  return sockets;
}

void http_benchmark_close(const std::vector<int>& sockets) {
  for (int i = 0; i < sockets.size(); i++)
    close(sockets[i]);
}

float http_benchmark(const std::vector<int>& sockets, int NTHREADS, int duration_in_ms,
                     std::string_view req) {

  int NCONNECTION_PER_THREAD = sockets.size() / NTHREADS;

  auto client_fn = [&](auto conn_handler, int i_start, int i_end) {
    int epoll_fd = epoll_create1(0);

    auto epoll_ctl = [epoll_fd](int fd, int op, uint32_t flags) {
      epoll_event event;
      event.data.fd = fd;
      event.events = flags;
      ::epoll_ctl(epoll_fd, op, fd, &event);
      return true;
    };

    for (int i = i_start; i < i_end; i++) {
      epoll_ctl(sockets[i], EPOLL_CTL_ADD, EPOLLIN | EPOLLOUT | EPOLLET);
    }

    const int MAXEVENTS = 64;
    std::vector<ctx::continuation> fibers;
    for (int i = i_start; i < i_end; i++) {
      int infd = sockets[i];
      if (int(fibers.size()) < infd + 1)
        fibers.resize(infd + 10);

      // std::cout << "start socket " << i << std::endl;
      fibers[infd] = ctx::callcc([fd = infd, &conn_handler, epoll_ctl](ctx::continuation&& sink) {
        auto read = [fd, &sink, epoll_ctl](char* buf, int max_size) {
          ssize_t count = ::recv(fd, buf, max_size, 0);
          while (count <= 0) {
            if ((count < 0 and errno != EAGAIN) or count == 0)
              return ssize_t(0);
            sink = sink.resume();
            count = ::recv(fd, buf, max_size, 0);
          }
          return count;
        };

        auto write = [fd, &sink, epoll_ctl](const char* buf, int size) {
          const char* end = buf + size;
          ssize_t count = ::send(fd, buf, end - buf, 0);
          if (count > 0)
            buf += count;
          while (buf != end) {
            if ((count < 0 and errno != EAGAIN) or count == 0)
              return false;
            sink = sink.resume();
            count = ::send(fd, buf, end - buf, 0);
            if (count > 0)
              buf += count;
          }
          return true;
        };
        conn_handler(fd, read, write);
        return std::move(sink);
      });
    }

    // Even loop.
    epoll_event events[MAXEVENTS];
    http_benchmark_impl::timer global_timer;
    global_timer.start();
    global_timer.end();
    while (global_timer.ms() < duration_in_ms) {
      // std::cout << global_timer.ms() << " " << duration_in_ms << std::endl;
      int n_events = epoll_wait(epoll_fd, events, MAXEVENTS, 1);
      for (int i = 0; i < n_events; i++) {
        if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP)) {
        } else // Data available on existing sockets. Wake up the fiber associated with
               // events[i].data.fd.
          fibers[events[i].data.fd] = fibers[events[i].data.fd].resume();
      }

      global_timer.end();
    }
  };

  std::atomic<int> nmessages = 0;

  auto bench_tcp = [&](int thread_id) {
    return [=, &nmessages]() {
      client_fn(
          [&](int fd, auto read, auto write) { // flood the server.
            while (true) {
              char buf_read[10000];
              write(req.data(), req.size());
              int rd = read(buf_read, sizeof(buf_read));
              nmessages++;
            }
          },
          thread_id * NCONNECTION_PER_THREAD, (thread_id+1) * NCONNECTION_PER_THREAD);
    };
  };

  int nthreads = NTHREADS;
  std::vector<std::thread> ths;
  for (int i = 0; i < nthreads; i++)
    ths.push_back(std::thread(bench_tcp(i)));
  for (auto& t : ths)
    t.join();
  return (1000. * nmessages / duration_in_ms);
}

} // namespace li

ext: hh

max_stars_repo_name: c-cesar/lithium

max_issues_repo_name: c-cesar/lithium

max_forks_repo_name: c-cesar/lithium


text:
#ifndef STAN_MATH_PRIM_MAT_PROB_CATEGORICAL_LOGIT_LPMF_HPP
#define STAN_MATH_PRIM_MAT_PROB_CATEGORICAL_LOGIT_LPMF_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/err/check_bounded.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/arr/fun/log_sum_exp.hpp>
#include <stan/math/prim/mat/fun/log_softmax.hpp>
#include <stan/math/prim/mat/fun/log_sum_exp.hpp>
#include <stan/math/prim/mat/fun/sum.hpp>
#include <boost/math/tools/promotion.hpp>
#include <vector>

namespace stan {
namespace math {

// CategoricalLog(n|theta)  [0 < n <= N, theta unconstrained], no checking
template <bool propto, typename T_prob>
return_type_t<T_prob> categorical_logit_lpmf(
    int n, const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& beta) {
  static const char* function = "categorical_logit_lpmf";

  check_bounded(function, "categorical outcome out of support", n, 1,
                beta.size());
  check_finite(function, "log odds parameter", beta);

  if (!include_summand<propto, T_prob>::value) {
    return 0.0;
  }

  // FIXME:  wasteful vs. creating term (n-1) if not vectorized
  return beta(n - 1) - log_sum_exp(beta);  // == log_softmax(beta)(n-1);
}

template <typename T_prob>
inline return_type_t<T_prob> categorical_logit_lpmf(
    int n, const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& beta) {
  return categorical_logit_lpmf<false>(n, beta);
}

template <bool propto, typename T_prob>
return_type_t<T_prob> categorical_logit_lpmf(
    const std::vector<int>& ns,
    const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& beta) {
  static const char* function = "categorical_logit_lpmf";

  for (const auto& x : ns) {
    check_bounded(function, "categorical outcome out of support", x, 1,
                  beta.size());
  }
  check_finite(function, "log odds parameter", beta);

  if (!include_summand<propto, T_prob>::value) {
    return 0.0;
  }

  if (ns.empty()) {
    return 0.0;
  }

  Eigen::Matrix<T_prob, Eigen::Dynamic, 1> log_softmax_beta = log_softmax(beta);

  // FIXME:  replace with more efficient sum()
  Eigen::Matrix<return_type_t<T_prob>, Eigen::Dynamic, 1> results(ns.size());
  for (size_t i = 0; i < ns.size(); ++i) {
    results[i] = log_softmax_beta(ns[i] - 1);
  }
  return sum(results);
}

template <typename T_prob>
inline return_type_t<T_prob> categorical_logit_lpmf(
    const std::vector<int>& ns,
    const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& beta) {
  return categorical_logit_lpmf<false>(ns, beta);
}

}  // namespace math
}  // namespace stan
#endif

max_stars_repo_name: PhilClemson/math

max_issues_repo_name: PhilClemson/math

max_forks_repo_name: PhilClemson/math


text:
/*
 * Copyright (c) 2011-2022, The DART development contributors
 * All rights reserved.
 *
 * The list of contributors can be found at:
 *   https://github.com/dartsim/dart/blob/master/LICENSE
 *
 * This file is provided under the following "BSD-style" License:
 *   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.
 *   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 HOLDER 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 DART_OPTIMIZER_PROBLEM_HPP_
#define DART_OPTIMIZER_PROBLEM_HPP_

#include <cstddef>
#include <vector>

#include <Eigen/Dense>

#include "dart/optimizer/Function.hpp"

namespace dart {
namespace optimizer {

/// \brief class Problem
class Problem
{
public:
  /// \brief Constructor
  explicit Problem(std::size_t _dim = 0);

  /// \brief Destructor
  virtual ~Problem() = default;

  //--------------------------- Problem Setting --------------------------------
  /// \brief Set dimension. Note: Changing the dimension will clear out the
  /// initial guess and any seeds that have been added.
  void setDimension(std::size_t _dim);

  /// \brief Get dimension
  std::size_t getDimension() const;

  /// \brief Set initial guess for opimization parameters
  void setInitialGuess(const Eigen::VectorXd& _initGuess);

  /// \brief Set initial guess for opimization parameters
  const Eigen::VectorXd& getInitialGuess() const;

  /// \brief Add a seed for the Solver to use as a hint for the neighborhood of
  /// the solution.
  void addSeed(const Eigen::VectorXd& _seed);

  /// \brief Get a mutable reference of the seed for the specified index. If an
  /// out-of-bounds index is provided a warning will print, and a reference to
  /// the initial guess will be returned instead.
  Eigen::VectorXd& getSeed(std::size_t _index);

  /// \brief An immutable version of getSeed(std::size_t)
  const Eigen::VectorXd& getSeed(std::size_t _index) const;

  /// \brief Get a mutable reference to the full vector of seeds that this
  /// Problem currently contains
  std::vector<Eigen::VectorXd>& getSeeds();

  /// \brief An immutable version of getSeeds()
  const std::vector<Eigen::VectorXd>& getSeeds() const;

  /// \brief Clear the seeds that this Problem currently contains
  void clearAllSeeds();

  /// \brief Set lower bounds for optimization parameters
  void setLowerBounds(const Eigen::VectorXd& _lb);

  /// \brief Get lower bounds for optimization parameters
  const Eigen::VectorXd& getLowerBounds() const;

  /// \brief Set upper bounds for optimization parameters
  void setUpperBounds(const Eigen::VectorXd& _ub);

  /// \brief Get upper bounds for optimization parameters
  const Eigen::VectorXd& getUpperBounds() const;

  /// \brief Set minimum objective function
  void setObjective(FunctionPtr _obj);

  /// \brief Get objective function
  FunctionPtr getObjective() const;

  /// \brief Add equality constraint
  void addEqConstraint(FunctionPtr _eqConst);

  /// \brief Add inequality constraint. Inequality constraints must evaluate
  /// to LESS THAN or equal to zero (within some tolerance) to be satisfied.
  void addIneqConstraint(FunctionPtr _ineqConst);

  /// \brief Get number of equality constraints
  std::size_t getNumEqConstraints() const;

  /// \brief Get number of inequality constraints
  std::size_t getNumIneqConstraints() const;

  /// \brief Get equality constraint
  FunctionPtr getEqConstraint(std::size_t _idx) const;

  /// \brief Get inequality constraint
  FunctionPtr getIneqConstraint(std::size_t _idx) const;

  /// \brief Remove equality constraint
  void removeEqConstraint(FunctionPtr _eqConst);

  /// \brief Remove inequality constraint
  void removeIneqConstraint(FunctionPtr _ineqConst);

  /// \brief Remove all equality constraints
  void removeAllEqConstraints();

  /// \brief Remove all inequality constraints
  void removeAllIneqConstraints();

  //------------------------------ Result --------------------------------------
  /// \brief Set optimum value of the objective function. This function called
  ///        by Solver.
  void setOptimumValue(double _val);

  /// \brief Get optimum value of the objective function
  double getOptimumValue() const;

  /// \brief Set optimal solution. This function called by Solver.
  void setOptimalSolution(const Eigen::VectorXd& _optParam);

  /// \brief Get optimal solution
  const Eigen::VectorXd& getOptimalSolution();

protected:
  /// \brief Dimension of this problem
  std::size_t mDimension;

  /// \brief Initial guess for optimization parameters
  Eigen::VectorXd mInitialGuess;

  /// \brief Additional guess hints for the Solver.
  std::vector<Eigen::VectorXd> mSeeds;

  /// \brief Lower bounds for optimization parameters
  Eigen::VectorXd mLowerBounds;

  /// \brief Upper bounds for optimization parameters
  Eigen::VectorXd mUpperBounds;

  /// \brief Objective function
  FunctionPtr mObjective;

  /// \brief Equality constraint functions
  std::vector<FunctionPtr> mEqConstraints;

  /// \brief Inequality constraint functions
  std::vector<FunctionPtr> mIneqConstraints;

  /// \brief Optimal objective value
  double mOptimumValue;

  /// \brief Optimal solution
  Eigen::VectorXd mOptimalSolution;
};

} // namespace optimizer
} // namespace dart

#endif // #ifndef DART_OPTIMIZER_PROBLEM_HPP_

max_stars_repo_name: ibrahiminfinite/dart

max_issues_repo_name: ibrahiminfinite/dart

max_forks_repo_name: ibrahiminfinite/dart


text:
/*
 *                   GridGain Community Edition Licensing
 *                   Copyright 2019 GridGain Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License") modified with Commons Clause
 * Restriction; 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.
 *
 * Commons Clause Restriction
 *
 * The Software is provided to you by the Licensor under the License, as defined below, subject to
 * the following condition.
 *
 * Without limiting other conditions in the License, the grant of rights under the License will not
 * include, and the License does not grant to you, the right to Sell the Software.
 * For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you
 * under the License to provide to third parties, for a fee or other consideration (including without
 * limitation fees for hosting or consulting/ support services related to the Software), a product or
 * service whose value derives, entirely or substantially, from the functionality of the Software.
 * Any license notice or attribution required by the License must also include this Commons Clause
 * License Condition notice.
 *
 * For purposes of the clause above, the “Licensor” is Copyright 2019 GridGain Systems, Inc.,
 * the “License” is the Apache License, Version 2.0, and the Software is the GridGain Community
 * Edition software provided with this notice.
 */

#ifndef _MSC_VER
#   define BOOST_TEST_DYN_LINK
#endif

#include <boost/test/unit_test.hpp>

#include "ignite/ignition.h"
#include "ignite/test_utils.h"

using namespace ignite;
using namespace ignite::transactions;
using namespace ignite::cache;
using namespace boost::unit_test;

/*
 * Test setup fixture.
 */
struct TransactionsTestSuiteFixture {
    Ignite grid;

    /*
     * Constructor.
     */
    TransactionsTestSuiteFixture()
    {
#ifdef IGNITE_TESTS_32
        grid = ignite_test::StartNode("cache-test-32.xml", "txTest");
#else
        grid = ignite_test::StartNode("cache-test.xml", "txTest");
#endif
    }

    /*
     * Destructor.
     */
    ~TransactionsTestSuiteFixture()
    {
        Ignition::Stop(grid.GetName(), true);

        grid = Ignite();
    }
};

BOOST_FIXTURE_TEST_SUITE(TransactionsTestSuite, TransactionsTestSuiteFixture)

BOOST_AUTO_TEST_CASE(TransactionsMetrics)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    Transactions transactions = grid.GetTransactions();

    TransactionMetrics metrics = transactions.GetMetrics();
    BOOST_REQUIRE(metrics.IsValid());

    BOOST_CHECK_EQUAL(0, metrics.GetCommits());
    BOOST_CHECK_EQUAL(0, metrics.GetRollbacks());
}

BOOST_AUTO_TEST_CASE(TransactionCommit)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart();

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache.Put(1, 1);
    cache.Put(2, 2);

    tx.Commit();

    BOOST_CHECK_EQUAL(1, cache.Get(1));
    BOOST_CHECK_EQUAL(2, cache.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionRollback)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    cache.Put(1, 1);
    cache.Put(2, 2);

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart();

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache.Put(1, 10);
    cache.Put(2, 20);

    tx.Rollback();

    BOOST_CHECK_EQUAL(1, cache.Get(1));
    BOOST_CHECK_EQUAL(2, cache.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionClose)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    cache.Put(1, 1);
    cache.Put(2, 2);

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart();

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache.Put(1, 10);
    cache.Put(2, 20);

    tx.Close();

    BOOST_CHECK_EQUAL(1, cache.Get(1));
    BOOST_CHECK_EQUAL(2, cache.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionRollbackOnly)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    cache.Put(1, 1);
    cache.Put(2, 2);

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.TxStart();

    cache.Put(1, 10);
    cache.Put(2, 20);

    BOOST_CHECK(!tx.IsRollbackOnly());

    tx.SetRollbackOnly();

    BOOST_CHECK(tx.IsRollbackOnly());

    try
    {
        tx.Commit();

        BOOST_FAIL("Commit must fail for rollback-only transaction.");
    }
    catch (IgniteError& error)
    {
        // Expected exception.
        BOOST_CHECK(error.GetCode() != IgniteError::IGNITE_SUCCESS);
    }

    tx.Close();

    BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
    BOOST_CHECK(tx.IsRollbackOnly());

    BOOST_CHECK_EQUAL(1, cache.Get(1));
    BOOST_CHECK_EQUAL(2, cache.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionAttributes)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
        TransactionIsolation::SERIALIZABLE, 1000, 100);

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
    BOOST_CHECK_EQUAL(TransactionIsolation::SERIALIZABLE, tx.GetIsolation());
    BOOST_CHECK_EQUAL(1000, tx.GetTimeout());
    BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());

    tx.Commit();

    BOOST_CHECK_EQUAL(TransactionState::COMMITTED, tx.GetState());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());

    tx = transactions.TxStart(TransactionConcurrency::PESSIMISTIC,
        TransactionIsolation::READ_COMMITTED, 2000, 10);

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    BOOST_CHECK_EQUAL(TransactionConcurrency::PESSIMISTIC, tx.GetConcurrency());
    BOOST_CHECK_EQUAL(TransactionIsolation::READ_COMMITTED, tx.GetIsolation());
    BOOST_CHECK_EQUAL(2000, tx.GetTimeout());
    BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());

    tx.Rollback();

    BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());

    tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
        TransactionIsolation::REPEATABLE_READ, 3000, 0);

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
    BOOST_CHECK_EQUAL(TransactionIsolation::REPEATABLE_READ, tx.GetIsolation());
    BOOST_CHECK_EQUAL(3000, tx.GetTimeout());
    BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());

    tx.Close();

    BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(CrossCacheCommit)
{
    Cache<int, int> cache1 = grid.GetCache<int, int>("partitioned");
    Cache<int, int> cache2 = grid.GetCache<int, int>("partitioned2");

    cache1.Put(1, 1);
    cache1.Put(2, 1);

    cache2.Put(1, 2);
    cache2.Put(2, 2);

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart();

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache1.Put(1, 10);
    cache1.Put(2, 10);

    cache2.Put(1, 20);
    cache2.Put(2, 20);

    tx.Commit();

    BOOST_CHECK_EQUAL(10, cache1.Get(1));
    BOOST_CHECK_EQUAL(10, cache1.Get(2));

    BOOST_CHECK_EQUAL(20, cache2.Get(1));
    BOOST_CHECK_EQUAL(20, cache2.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(CrossCacheRollback)
{
    Cache<int, int> cache1 = grid.GetCache<int, int>("partitioned");
    Cache<int, int> cache2 = grid.GetCache<int, int>("partitioned2");

    cache1.Put(1, 1);
    cache1.Put(2, 1);

    cache2.Put(1, 2);
    cache2.Put(2, 2);

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart();

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache1.Put(1, 10);
    cache1.Put(2, 10);

    cache2.Put(1, 20);
    cache2.Put(2, 20);

    tx.Rollback();

    BOOST_CHECK_EQUAL(1, cache1.Get(1));
    BOOST_CHECK_EQUAL(1, cache1.Get(2));

    BOOST_CHECK_EQUAL(2, cache2.Get(1));
    BOOST_CHECK_EQUAL(2, cache2.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionsMetricsNe)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    Transactions transactions = grid.GetTransactions();

    IgniteError err;

    TransactionMetrics metrics = transactions.GetMetrics(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(metrics.IsValid());

    BOOST_CHECK_EQUAL(0, metrics.GetCommits());
    BOOST_CHECK_EQUAL(0, metrics.GetRollbacks());
}

BOOST_AUTO_TEST_CASE(TransactionCommitNe)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    Transactions transactions = grid.GetTransactions();

    IgniteError err;

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache.Put(1, 1, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    cache.Put(2, 2, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    tx.Commit(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(1, cache.Get(1, err));
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(2, cache.Get(2, err));
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionRollbackNe)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    IgniteError err;

    cache.Put(1, 1, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    cache.Put(2, 2, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache.Put(1, 10, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    cache.Put(2, 20, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    tx.Rollback(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(1, cache.Get(1, err));
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(2, cache.Get(2, err));
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionCloseNe)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    IgniteError err;

    cache.Put(1, 1, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    cache.Put(2, 2, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    cache.Put(1, 10, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    cache.Put(2, 20, err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    tx.Close(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(1, cache.Get(1, err));
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(2, cache.Get(2, err));
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionRollbackOnlyNe)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    IgniteError err;

    cache.Put(1, 1);
    cache.Put(2, 2);

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.TxStart();

    cache.Put(1, 10);
    cache.Put(2, 20);

    BOOST_CHECK(!tx.IsRollbackOnly());

    tx.SetRollbackOnly(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK(tx.IsRollbackOnly());

    tx.Commit(err);
    BOOST_REQUIRE(err.GetCode() != IgniteError::IGNITE_SUCCESS);

    tx.Close(err);
    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
    BOOST_CHECK(tx.IsRollbackOnly());

    BOOST_CHECK_EQUAL(1, cache.Get(1));
    BOOST_CHECK_EQUAL(2, cache.Get(2));

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_CASE(TransactionAttributesNe)
{
    Cache<int, int> cache = grid.GetCache<int, int>("partitioned");

    IgniteError err;

    Transactions transactions = grid.GetTransactions();

    Transaction tx = transactions.GetTx();
    BOOST_REQUIRE(!tx.IsValid());

    tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
        TransactionIsolation::SERIALIZABLE, 1000, 100, err);

    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
    BOOST_CHECK_EQUAL(TransactionIsolation::SERIALIZABLE, tx.GetIsolation());
    BOOST_CHECK_EQUAL(1000, tx.GetTimeout());
    BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());

    tx.Commit();

    BOOST_CHECK_EQUAL(TransactionState::COMMITTED, tx.GetState());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());

    tx = transactions.TxStart(TransactionConcurrency::PESSIMISTIC,
        TransactionIsolation::READ_COMMITTED, 2000, 10, err);

    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    BOOST_CHECK_EQUAL(TransactionConcurrency::PESSIMISTIC, tx.GetConcurrency());
    BOOST_CHECK_EQUAL(TransactionIsolation::READ_COMMITTED, tx.GetIsolation());
    BOOST_CHECK_EQUAL(2000, tx.GetTimeout());
    BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());

    tx.Rollback();

    BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());

    tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
        TransactionIsolation::REPEATABLE_READ, 3000, 0, err);

    if (!err.GetCode() == IgniteError::IGNITE_SUCCESS)
        BOOST_ERROR(err.GetText());

    BOOST_REQUIRE(transactions.GetTx().IsValid());

    BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
    BOOST_CHECK_EQUAL(TransactionIsolation::REPEATABLE_READ, tx.GetIsolation());
    BOOST_CHECK_EQUAL(3000, tx.GetTimeout());
    BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());

    tx.Close();

    BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());

    tx = transactions.GetTx();

    BOOST_CHECK(!tx.IsValid());
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: DirectXceriD/gridgain

max_issues_repo_name: DirectXceriD/gridgain

max_forks_repo_name: DirectXceriD/gridgain


text:
/********************************************************************************
 *
 * This file is part of the Geneva library collection. The following license
 * applies to this file:
 *
 * ------------------------------------------------------------------------------
 * 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.
 * ------------------------------------------------------------------------------
 *
 * Note that other files in the Geneva library collection may use a different
 * license. Please see the licensing information in each file.
 *
 ********************************************************************************
 *
 * Geneva was started by Dr. Rüdiger Berlich and was later maintained together
 * with Dr. Ariel Garcia under the auspices of Gemfony scientific. For further
 * information on Gemfony scientific, see http://www.gemfomy.eu .
 *
 * The majority of files in Geneva was released under the Apache license v2.0
 * in February 2020.
 *
 * See the NOTICE file in the top-level directory of the Geneva library
 * collection for a list of contributors and copyright information.
 *
 ********************************************************************************/

#pragma once

// Global checks, defines and includes needed for all of Geneva
#include "common/GGlobalDefines.hpp"

// Standard headers go here

#include <iostream>
#include <sstream>
#include <string>
#include <sstream>
#include <vector>
#include <chrono>
#include <atomic>

// Boost headers go here

#include <boost/utility.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/cast.hpp>
#include <boost/logic/tribool.hpp>

// Geneva headers go here
#include "common/GCommonEnums.hpp"
#include "common/GCommonHelperFunctions.hpp"
#include "common/GLogger.hpp"
#include "common/GExceptions.hpp"
#include "common/GErrorStreamer.hpp"

namespace Gem {
namespace Common {

/******************************************************************************/
/**
 * Converts a shared_ptr<T> into its string representation. This template function thus assumes that
 * T is serializable using the Boost.Serialization framework.
 *
 * @param gt_ptr A shared_ptr to the object to be serialized
 * @param sm The corresponding serialization mode
 * @return A string representation of gt_ptr
 */
template<typename T>
std::string sharedPtrToString(std::shared_ptr<T> gt_ptr, const Gem::Common::serializationMode &serMod) {
	std::ostringstream oarchive_stream;

	switch (serMod) {
		case Gem::Common::serializationMode::TEXT: {
			boost::archive::text_oarchive oa(oarchive_stream);
			oa << boost::serialization::make_nvp("classHierarchyFromT_ptr", gt_ptr);
		} // note: explicit scope here is essential so the oa-destructor gets called

			break;

		case Gem::Common::serializationMode::XML: {
			boost::archive::xml_oarchive oa(oarchive_stream);
			oa << boost::serialization::make_nvp("classHierarchyFromT_ptr", gt_ptr);
		}
			break;

		case Gem::Common::serializationMode::BINARY: {
			boost::archive::binary_oarchive oa(oarchive_stream);
			oa << boost::serialization::make_nvp("classHierarchyFromT_ptr", gt_ptr);
		}

			break;
	}

	return oarchive_stream.str();
}

/******************************************************************************/
/**
 * Loads a shared_ptr<T> from its string representation. This template function thus assumes that
 * T is de-serializable using the Boost.Serialization framework.
 *
 * @param gt_string A string representation of the object to be restored
 * @param sm The corresponding serialization mode
 * @return A shared_ptr to the restored object
 */
template<typename T>
std::shared_ptr<T> sharedPtrFromString(const std::string &gt_string, const Gem::Common::serializationMode &serMod) {
	std::istringstream istr(gt_string);
	std::shared_ptr<T> gt_ptr;

	try {
		switch (serMod) {
			case Gem::Common::serializationMode::TEXT: {
				boost::archive::text_iarchive ia(istr);
				ia >> boost::serialization::make_nvp("classHierarchyFromT_ptr", gt_ptr);
			} // note: explicit scope here is essential so the ia-destructor gets called

				break;

			case Gem::Common::serializationMode::XML: {
				boost::archive::xml_iarchive ia(istr);
				ia >> boost::serialization::make_nvp("classHierarchyFromT_ptr", gt_ptr);
			}

				break;

			case Gem::Common::serializationMode::BINARY: {
				boost::archive::binary_iarchive ia(istr);
				ia >> boost::serialization::make_nvp("classHierarchyFromT_ptr", gt_ptr);
			}
				break;
		}
	} catch (boost::archive::archive_exception &e) {
		glogger
		<< "In sharedPtrFromString(): Error!" << std::endl
		<< "Caught boost::archive::archive_exception" << std::endl
		<< "with message" << std::endl
		<< e.what() << std::endl
		<< "We will return an empty pointer." << std::endl
		<< GWARNING;

		return std::shared_ptr<T>();
	} catch (std::exception& e) {
		glogger
			<< "In sharedPtrFromString(): Error!" << std::endl
			<< "Caught std::exception with message" << std::endl
			<< e.what() << std::endl
			<< "We will return an empty pointer." << std::endl
			<< GWARNING;

		return std::shared_ptr<T>();
	} catch (...) {
		throw gemfony_exception(
			g_error_streamer(DO_LOG, time_and_place)
				<< "In sharedPtrFromString(): Error!" << std::endl
				<< "Caught unknown exception" << std::endl
		);
	}

	return gt_ptr;
}

/******************************************************************************/

} /* namespace Common */
} /* namespace Gem */

/******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
/******************************************************************************/

namespace boost {
namespace serialization {

/******************************************************************************/
/**
 * Saves a tribool variable to an archive
 */
template<typename Archive>
void save(
	Archive &ar
	, const boost::logic::tribool &val
	, unsigned int version
) {
	Gem::Common::triboolStates tbs = Gem::Common::triboolStates::TBS_FALSE;
	if (val == true)
		tbs = Gem::Common::triboolStates::TBS_TRUE;
	else if (boost::logic::indeterminate(val))
		tbs = Gem::Common::triboolStates::TBS_INDETERMINATE;

	ar &make_nvp("tbs", tbs);
}

/******************************************************************************/
/**
 * Loads a tribool variable from an archive
 */
template<typename Archive>
void load(
	Archive &ar
	, boost::logic::tribool &val
	, unsigned int version
) {
	Gem::Common::triboolStates tbs = Gem::Common::triboolStates::TBS_FALSE;
	ar &make_nvp("tbs", tbs);

	switch (tbs) {
		case Gem::Common::triboolStates::TBS_FALSE:
			val = false;
			break;

		case Gem::Common::triboolStates::TBS_TRUE:
			val = true;
			break;

		case Gem::Common::triboolStates::TBS_INDETERMINATE:
			val = boost::logic::indeterminate;
			break;
	};
}

/******************************************************************************/
/**
 * Saves a std::chrono::duration<double> variable to an archive
 */
template<typename Archive>
void save(
	Archive &ar
	, const std::chrono::duration<double> &val
	, unsigned int version
) {
	typename std::chrono::duration<double>::rep chrono_duration = val.count();
	ar & make_nvp("chrono_duration", chrono_duration);
}

/******************************************************************************/
/**
 * Loads a tribool variable from an archive
 */
template<typename Archive>
void load(
	Archive &ar
	, std::chrono::duration<double> &val
	, unsigned int version
) {
	typename std::chrono::duration<double>::rep chrono_duration;
	ar & make_nvp("chrono_duration", chrono_duration);
	val = std::chrono::duration<double>(chrono_duration);
}

/******************************************************************************/
/**
 * Loads a time point from an archive
 */
template<typename Archive>
void save(
	Archive& ar
	, std::chrono::high_resolution_clock::time_point const& val
	, unsigned int version
) {
	std::chrono::milliseconds::rep representation = Gem::Common::time_point_to_milliseconds(val);
	ar & make_nvp("timpoint_milliseconds", representation);;
}

/******************************************************************************/
/**
 * Saves a time point to an archive
 */
template<typename Archive>
void load(
	Archive& ar
	, std::chrono::high_resolution_clock::time_point& val
	, unsigned int version
) {
	std::chrono::milliseconds::rep representation;
	ar & make_nvp("timpoint_milliseconds", representation);
	val = Gem::Common::milliseconds_to_time_point(representation);
}

/******************************************************************************/
/**
 * Serialization of std::atomic<bool>
 */
template<typename Archive>
void save(
	Archive & ar
	, const std::atomic<bool>& b
	, unsigned int version
){
	bool value = b.load();
	ar & make_nvp("bool_val", value);
}

/******************************************************************************/
/**
 * Deserialization of std::atomic<bool>
 */
template<typename Archive>
void load(
	Archive & ar
	, std::atomic<bool>& b
	, unsigned int version
){
	bool value = false;
	ar & make_nvp("bool_val", value);
	b.store(value);
}

/******************************************************************************/

} /* namespace serialization */
} /* namespace boost */

/******************************************************************************/
/**
 * Needed so Boost.Serialization does not search for a serialize function
 */
BOOST_SERIALIZATION_SPLIT_FREE(boost::logic::tribool)
BOOST_SERIALIZATION_SPLIT_FREE(std::chrono::duration<double>)
BOOST_SERIALIZATION_SPLIT_FREE(std::chrono::high_resolution_clock::time_point)
BOOST_SERIALIZATION_SPLIT_FREE(std::atomic<bool>)

/*
template<typename Archive, typename clock_type>
inline void serialize(
	Archive & ar
	, std::chrono::time_point<clock_type>& time_point
	, unsigned int version
) {
	boost::serialization::split_free(ar, time_point, version);
}
 */

/******************************************************************************/

max_stars_repo_name: denisbertini/geneva

max_issues_repo_name: denisbertini/geneva

max_forks_repo_name: denisbertini/geneva


text: #include <boost/type_erasure/param.hpp>


text:
//==============================================================================
//         Copyright 2003 - 2011   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#define NT2_UNIT_MODULE "nt2::memory boost::array adaptation as a Buffer"

#ifdef _MSC_VER
#pragma warning(disable: 4996) // unsafe std::transform
#endif

#include <nt2/sdk/memory/array_buffer.hpp>

#include <string>
#include <algorithm>
#include <boost/array.hpp>
#include <boost/fusion/adapted/array.hpp>
#include <boost/fusion/include/vector_tie.hpp>
#include <boost/fusion/include/make_vector.hpp>

#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/basic.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>
#include <nt2/sdk/unit/tests/type_expr.hpp>
#include <nt2/sdk/unit/tests/exceptions.hpp>

#include "object.hpp"

//==============================================================================
// Test for default array_buffer ctor
//==============================================================================
NT2_TEST_CASE( array_buffer_default_ctor )
{
  using nt2::memory::array_buffer;

  array_buffer<nt2::object, boost::mpl::size_t<2> > b;

  NT2_TEST_EQUAL(b.size(), 2u );
  NT2_TEST_EQUAL(b.raw(),&b[0]);

  for(std::size_t i=0;i<b.size();++i)
  {
    NT2_TEST_EQUAL(b[i].s, std::string("default") );
  }
}

//==============================================================================
// Test for dynamic array_buffer copy ctor
//==============================================================================
NT2_TEST_CASE( array_buffer_data_ctor )
{
  using nt2::memory::array_buffer;

  array_buffer<nt2::object, boost::mpl::size_t<5> > b;

  for(std::size_t i=0;i<b.size();++i)
    NT2_TEST_EQUAL(b[i].s, std::string("default") );

  array_buffer<nt2::object, boost::mpl::size_t<5> > x(b);
  NT2_TEST_EQUAL(x.size() , 5u     );
  NT2_TEST_EQUAL(x.raw()  , &x[0] );

  for( std::size_t i = 0; i < 5; ++i )
    NT2_TEST_EQUAL(x[i].s, std::string("copied") );
}

//==============================================================================
// Test for array_buffer assignment
//==============================================================================
NT2_TEST_CASE(array_buffer_assignment )
{
  using nt2::memory::array_buffer;

  array_buffer<nt2::object, boost::mpl::size_t<5> > b;
  for(std::size_t i=0;i<b.size();++i)
    NT2_TEST_EQUAL(b[i].s, std::string("default") );

  array_buffer<nt2::object, boost::mpl::size_t<5> > x;
  x = b;

  NT2_TEST_EQUAL(x.size() , 5u     );
  NT2_TEST_EQUAL(x.raw()  , &x[0] );

  for(std::size_t i=0;i<b.size();++i)
    NT2_TEST_EQUAL(x[i].s, std::string("assigned") );
}

//==============================================================================
// Test for array_buffer swap
//==============================================================================
NT2_TEST_CASE(array_buffer_swap)
{
  using nt2::memory::array_buffer;

  array_buffer<nt2::object, boost::mpl::size_t<5> > b,x;
  for(std::size_t i=0;i<b.size();++i)
  {
    NT2_TEST_EQUAL(b[i].s, std::string("default") );
    NT2_TEST_EQUAL(x[i].s, std::string("default") );
  }

  swap(x,b);

  NT2_TEST_EQUAL(x.size() , 5u    );
  NT2_TEST_EQUAL(b.size() , 5u    );
  NT2_TEST_EQUAL(x.raw()  , &x[0] );
  NT2_TEST_EQUAL(b.raw()  , &b[0] );

  for( std::size_t i = 0; i < 5; ++i )
  {
    NT2_TEST_EQUAL(b[i].s, std::string("right swapped") );
    NT2_TEST_EQUAL(x[i].s, std::string("left swapped") );
  }

  swap(b,x);

  for( std::size_t i = 0; i < 5; ++i )
  {
    NT2_TEST_EQUAL(x[i].s, std::string("right swapped") );
    NT2_TEST_EQUAL(b[i].s, std::string("left swapped") );
  }
}

//==============================================================================
// array_buffer Range interface
//==============================================================================
struct f_
{
  template<class T> std::string operator()(T const&) const
  {
    return "transformed";
  }
};

NT2_TEST_CASE(array_buffer_iterator)
{
  using nt2::memory::array_buffer;

  array_buffer<nt2::object, boost::mpl::size_t<5> > x;
  for(std::size_t i=0;i<x.size();++i)
    NT2_TEST_EQUAL(x[i].s, std::string("default") );

  f_ f;

  array_buffer<nt2::object, boost::mpl::size_t<5> >::iterator b = x.begin();
  array_buffer<nt2::object, boost::mpl::size_t<5> >::iterator e = x.end();

  std::transform(b,e,b,f);

  for(std::size_t i=0;i<x.size();++i)
    NT2_TEST_EQUAL(x[i].s, std::string("transformed") );
}


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

#include "api_server.h"

#include <boost/range/irange.hpp>

#include "configuration.h"
#include "health_checker.h"
#include "http_common.h"
#include "logging.h"
#include "store.h"

namespace google {

MetadataApiServer::Dispatcher::Dispatcher(
    const HandlerMap& handlers, bool verbose)
    : handlers_(handlers), verbose_(verbose) {}

void MetadataApiServer::Dispatcher::operator()(
    const HttpServer::request& request,
    std::shared_ptr<HttpServer::connection> conn) const {
  if (verbose_) {
    LOG(INFO) << "Dispatcher called: " << request.method
              << " " << request.destination
              << " headers: " << request.headers
              << " body: " << request.body;
  }
  // Look for the longest match first. This means going backwards through
  // the map, since strings are sorted in lexicographical order.
  for (auto it = handlers_.crbegin(); it != handlers_.crend(); ++it) {
    const std::string& method = it->first.first;
    const std::string& prefix = it->first.second;
#ifdef VERBOSE
    LOG(DEBUG) << "Checking " << method << " " << prefix;
#endif
    if (request.method != method || request.destination.find(prefix) != 0) {
#ifdef VERBOSE
      LOG(DEBUG) << "No match; skipping " << method << " " << prefix;
#endif
      continue;
    }
#ifdef VERBOSE
    LOG(DEBUG) << "Handler found for " << request.method
               << " " << request.destination;
#endif
    const Handler& handler = it->second;
    handler(request, conn);
  }
}

void MetadataApiServer::Dispatcher::log(const HttpServer::string_type& info) const {
  LOG(ERROR) << info;
}

MetadataApiServer::MetadataApiServer(const Configuration& config,
                                     const HealthChecker* health_checker,
                                     const MetadataStore& store,
                                     int server_threads,
                                     const std::string& host, int port)
    : config_(config), health_checker_(health_checker), store_(store),
      dispatcher_({
        {{"GET", "/monitoredResource/"},
         [=](const HttpServer::request& request,
             std::shared_ptr<HttpServer::connection> conn) {
             HandleMonitoredResource(request, conn);
         }},
        {{"GET", "/healthz"},
         [=](const HttpServer::request& request,
             std::shared_ptr<HttpServer::connection> conn) {
             HandleHealthz(request, conn);
         }},
      }, config_.VerboseLogging()),
      server_(
          HttpServer::options(dispatcher_)
              .address(host)
              .port(std::to_string(port))
              .reuse_address(true)),
      server_pool_()
{
  for (int i : boost::irange(0, server_threads)) {
    server_pool_.emplace_back([=]() { server_.run(); });
  }
}

void MetadataApiServer::Stop() {
  server_.stop();
  LOG(INFO) << "API server stopped";
}

MetadataApiServer::~MetadataApiServer() {
  Stop();
  for (auto& thread : server_pool_) {
    thread.join();
  }
}

void MetadataApiServer::HandleMonitoredResource(
    const HttpServer::request& request,
    std::shared_ptr<HttpServer::connection> conn) {
  // The format for the local metadata API request is:
  //   {host}:{port}/monitoredResource/{id}
  static const std::string kPrefix = "/monitoredResource/";;
  const std::string id = request.destination.substr(kPrefix.size());
  if (config_.VerboseLogging()) {
    LOG(INFO) << "Handler called for " << id;
  }
  try {
    const MonitoredResource& resource = store_.LookupResource(id);
    if (config_.VerboseLogging()) {
      LOG(INFO) << "Found resource for " << id << ": " << resource;
    }
    conn->set_status(HttpServer::connection::ok);

    std::string response = resource.ToJSON()->ToString();

    conn->set_headers(std::map<std::string, std::string>({
      {"Connection", "close"},
      {"Content-Length", std::to_string(response.size())},
      {"Content-Type", "application/json"},
    }));
    conn->write(response);
  } catch (const std::out_of_range& e) {
    // TODO: This could be considered log spam.
    // As we add more resource mappings, these will become less and less
    // frequent, and could be promoted to ERROR.
    if (config_.VerboseLogging()) {
      LOG(WARNING) << "No matching resource for " << id;
    }
    conn->set_status(HttpServer::connection::not_found);
    json::value json_response = json::object({
      {"status_code", json::number(404)},
      {"error", json::string("Not found")},
    });

    std::string response = json_response->ToString();

    conn->set_headers(std::map<std::string, std::string>({
      {"Connection", "close"},
      {"Content-Length", std::to_string(response.size())},
      {"Content-Type", "application/json"},
    }));
    conn->write(response);
  }
}

void MetadataApiServer::HandleHealthz(
    const HttpServer::request& request,
    std::shared_ptr<HttpServer::connection> conn) {
  std::set<std::string> unhealthy_components;
  if (health_checker_ != nullptr) {
    unhealthy_components = health_checker_->UnhealthyComponents();
  }
  if (unhealthy_components.empty()) {
    if (config_.VerboseLogging()) {
      LOG(INFO) << "/healthz returning 200";
    }
    conn->set_status(HttpServer::connection::ok);

    std::string response = "healthy";

    conn->set_headers(std::map<std::string, std::string>({
      {"Connection", "close"},
      {"Content-Length", std::to_string(response.size())},
      {"Content-Type", "text/plain"},
    }));
    conn->write(response);
  } else {
    LOG(WARNING) << "/healthz returning 500; unhealthy components: "
                 << boost::algorithm::join(unhealthy_components, ", ");
    conn->set_status(HttpServer::connection::internal_server_error);

    std::ostringstream response_stream("unhealthy components:\n");
    for (const auto& component : unhealthy_components) {
      response_stream << component << "\n";
    }

    std::string response = response_stream.str();

    conn->set_headers(std::map<std::string, std::string>({
      {"Connection", "close"},
      {"Content-Length", std::to_string(response.size())},
      {"Content-Type", "text/plain"},
    }));
    conn->write(response);
  }
}

}

ext: cc

max_stars_repo_name: StevenYCChou/metadata-agent

max_issues_repo_name: Stackdriver/metadata-agent

max_forks_repo_name: StevenYCChou/metadata-agent