<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/multiphysics_sys.h"

// GRINS
#include "grins/assembly_context.h"

// libMesh
#include "libmesh/composite_function.h"
#include "libmesh/getpot.h"

namespace GRINS
{

  MultiphysicsSystem::MultiphysicsSystem( libMesh::EquationSystems& es,
					  const std::string& name,
					  const unsigned int number )
    : FEMSystem(es, name, number),
      _use_numerical_jacobians_only(false)
  {
    return;
  }

  MultiphysicsSystem::~MultiphysicsSystem()
  {
    return;
  }

  void MultiphysicsSystem::attach_physics_list( PhysicsList physics_list )
  {
    _physics_list = physics_list;
    return;
  }

  void MultiphysicsSystem::read_input_options( const GetPot& input )
  {
    // Read options for MultiphysicsSystem first
    this->verify_analytic_jacobians = input("linear-nonlinear-solver/verify_analytic_jacobians", 0.0 );
    this->print_solution_norms = input("screen-options/print_solution_norms", false );
    this->print_solutions = input("screen-options/print_solutions", false );
    this->print_residual_norms = input("screen-options/print_residual_norms", false );

    // backwards compatibility with old config files.
    /*! \todo Remove old print_residual nomenclature */
    this->print_residuals = input("screen-options/print_residual", false );
    if (this->print_residuals)
      libmesh_deprecated();

    this->print_residuals = input("screen-options/print_residuals", this->print_residuals );
    this->print_jacobian_norms = input("screen-options/print_jacobian_norms", false );
    this->print_jacobians = input("screen-options/print_jacobians", false );
    this->print_element_solutions = input("screen-options/print_element_solutions", false );
    this->print_element_residuals = input("screen-options/print_element_residuals", false );
    this->print_element_jacobians = input("screen-options/print_element_jacobians", false );

    _use_numerical_jacobians_only = input("linear-nonlinear-solver/use_numerical_jacobians_only", false );

    numerical_jacobian_h =
      input("linear-nonlinear-solver/numerical_jacobian_h",
            numerical_jacobian_h);
  }

  void MultiphysicsSystem::init_data()
  {
    // Need this to be true because of our overloading of the
    // mass_residual function.
    // This is data in FEMSystem. MUST be set before FEMSystem::init_data.
    use_fixed_solution = true;

    // Initalize all the variables. We pass this pointer for the system.
    /* NOTE: We CANNOT fuse this loop with the others. This loop
       MUST complete first. */
    /*! \todo Figure out how to tell compilers not to fuse this loop when
      they want to be aggressive. */
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->init_variables( this );
      }

    // Now set time_evolving variables
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->set_time_evolving_vars( this );
      }

    // Set whether the problem we're solving is steady or not
    // Since the variable is static, just call one Physics class
    {
      (_physics_list.begin()->second)->set_is_steady((this->time_solver)->is_steady());
    }

    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	// Initialize builtin BC's for each physics
	(physics_iter->second)->init_bcs( this );
      }

    // Next, call parent init_data function to intialize everything.
    libMesh::FEMSystem::init_data();

    // After solution has been initialized we can project initial
    // conditions to it
    libMesh::CompositeFunction<libMesh::Number> ic_function;
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	// Initialize builtin IC's for each physics
	(physics_iter->second)->init_ics( this, ic_function );
      }

    if (ic_function.n_subfunctions())
      {
        this->project_solution(&ic_function);
      }

    return;
  }

  libMesh::AutoPtr<libMesh::DiffContext> MultiphysicsSystem::build_context()
  {
    AssemblyContext* context = new AssemblyContext(*this);

    libMesh::AutoPtr<libMesh::DiffContext> ap(context);

    libMesh::DifferentiablePhysics* phys = libMesh::FEMSystem::get_physics();

    libmesh_assert(phys);

    // If we are solving a moving mesh problem, tell that to the Context
    context->set_mesh_system(phys->get_mesh_system());
    context->set_mesh_x_var(phys->get_mesh_x_var());
    context->set_mesh_y_var(phys->get_mesh_y_var());
    context->set_mesh_z_var(phys->get_mesh_z_var());

    ap->set_deltat_pointer( &deltat );

    // If we are solving the adjoint problem, tell that to the Context
    ap->is_adjoint() = this->get_time_solver().is_adjoint();

    return ap;
  }

  void MultiphysicsSystem::register_postprocessing_vars( const GetPot& input,
                                                         PostProcessedQuantities<libMesh::Real>& postprocessing )
  {
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
        (physics_iter->second)->register_postprocessing_vars( input, postprocessing );
      }

    return;
  }

  void MultiphysicsSystem::init_context( libMesh::DiffContext& context )
  {
    AssemblyContext& c = libMesh::libmesh_cast_ref<AssemblyContext&>(context);

    //Loop over each physics to initialize relevant variable structures for assembling system
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->init_context( c );
      }

    return;
  }

  bool MultiphysicsSystem::_general_residual( bool request_jacobian,
					      libMesh::DiffContext& context,
                                              ResFuncType resfunc,
                                              CacheFuncType cachefunc)
  {
    AssemblyContext& c = libMesh::libmesh_cast_ref<AssemblyContext&>(context);

    bool compute_jacobian = true;
    if( !request_jacobian || _use_numerical_jacobians_only ) compute_jacobian = false;

    CachedValues cache;

    // Now compute cache for this element
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
        // boost::shared_ptr gets confused by operator->*
	((*(physics_iter->second)).*cachefunc)( c, cache );
      }

    // Loop over each physics and compute their contributions
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
        if(c.has_elem())
          {
            if( (physics_iter->second)->enabled_on_elem( &c.get_elem() ) )
              {
                ((*(physics_iter->second)).*resfunc)( compute_jacobian, c, cache );
              }
          }
        else
          {
            ((*(physics_iter->second)).*resfunc)( compute_jacobian, c, cache );
          }
      }

    // TODO: Need to think about the implications of this because there might be some
    // TODO: jacobian terms we don't want to compute for efficiency reasons
    return compute_jacobian;
  }

  bool MultiphysicsSystem::element_time_derivative( bool request_jacobian,
						    libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::element_time_derivative,
       &GRINS::Physics::compute_element_time_derivative_cache);
  }

  bool MultiphysicsSystem::side_time_derivative( bool request_jacobian,
						 libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::side_time_derivative,
       &GRINS::Physics::compute_side_time_derivative_cache);
  }

  bool MultiphysicsSystem::nonlocal_time_derivative( bool request_jacobian,
						     libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::nonlocal_time_derivative,
       &GRINS::Physics::compute_nonlocal_time_derivative_cache);
  }

  bool MultiphysicsSystem::element_constraint( bool request_jacobian,
					       libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::element_constraint,
       &GRINS::Physics::compute_element_constraint_cache);
  }

  bool MultiphysicsSystem::side_constraint( bool request_jacobian,
					    libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::side_constraint,
       &GRINS::Physics::compute_side_constraint_cache);
  }

  bool MultiphysicsSystem::nonlocal_constraint( bool request_jacobian,
					        libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::nonlocal_constraint,
       &GRINS::Physics::compute_nonlocal_constraint_cache);
  }

  bool MultiphysicsSystem::mass_residual( bool request_jacobian,
					  libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::mass_residual,
       &GRINS::Physics::compute_mass_residual_cache);
  }

  bool MultiphysicsSystem::nonlocal_mass_residual( bool request_jacobian,
					           libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::nonlocal_mass_residual,
       &GRINS::Physics::compute_nonlocal_mass_residual_cache);
  }

  std::tr1::shared_ptr<Physics> MultiphysicsSystem::get_physics( const std::string physics_name )
  {
    if( _physics_list.find( physics_name ) == _physics_list.end() )
      {
	std::cerr << "Error: Could not find physics " << physics_name << std::endl;
	libmesh_error();
      }

    return _physics_list[physics_name];
  }

  bool MultiphysicsSystem::has_physics( const std::string physics_name ) const
  {
    bool has_physics = false;

    if( _physics_list.find(physics_name) != _physics_list.end() )
      has_physics = true;

    return has_physics;
  }

  void MultiphysicsSystem::compute_postprocessed_quantity( unsigned int quantity_index,
                                                           const AssemblyContext& context,
                                                           const libMesh::Point& point,
                                                           libMesh::Real& value )
  {
    for( PhysicsListIter physics_iter = _physics_list.begin();
         physics_iter != _physics_list.end();
         physics_iter++ )
      {
        // Only compute if physics is active on current subdomain or globally
        if( (physics_iter->second)->enabled_on_elem( &context.get_elem() ) )
          {
            (physics_iter->second)->compute_postprocessed_quantity( quantity_index, context, point, value );
          }
      }
    return;
  }

#ifdef GRINS_USE_GRVY_TIMERS
  void MultiphysicsSystem::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
  {
    _timer = grvy_timer;

    // Attach timers to each physics
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->attach_grvy_timer( grvy_timer );
      }

    return;
  }
#endif

} // namespace GRINS
<commit_msg>Have MultiphysicsSystem call Physics::auxiliary_init<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/multiphysics_sys.h"

// GRINS
#include "grins/assembly_context.h"

// libMesh
#include "libmesh/composite_function.h"
#include "libmesh/getpot.h"

namespace GRINS
{

  MultiphysicsSystem::MultiphysicsSystem( libMesh::EquationSystems& es,
					  const std::string& name,
					  const unsigned int number )
    : FEMSystem(es, name, number),
      _use_numerical_jacobians_only(false)
  {
    return;
  }

  MultiphysicsSystem::~MultiphysicsSystem()
  {
    return;
  }

  void MultiphysicsSystem::attach_physics_list( PhysicsList physics_list )
  {
    _physics_list = physics_list;
    return;
  }

  void MultiphysicsSystem::read_input_options( const GetPot& input )
  {
    // Read options for MultiphysicsSystem first
    this->verify_analytic_jacobians = input("linear-nonlinear-solver/verify_analytic_jacobians", 0.0 );
    this->print_solution_norms = input("screen-options/print_solution_norms", false );
    this->print_solutions = input("screen-options/print_solutions", false );
    this->print_residual_norms = input("screen-options/print_residual_norms", false );

    // backwards compatibility with old config files.
    /*! \todo Remove old print_residual nomenclature */
    this->print_residuals = input("screen-options/print_residual", false );
    if (this->print_residuals)
      libmesh_deprecated();

    this->print_residuals = input("screen-options/print_residuals", this->print_residuals );
    this->print_jacobian_norms = input("screen-options/print_jacobian_norms", false );
    this->print_jacobians = input("screen-options/print_jacobians", false );
    this->print_element_solutions = input("screen-options/print_element_solutions", false );
    this->print_element_residuals = input("screen-options/print_element_residuals", false );
    this->print_element_jacobians = input("screen-options/print_element_jacobians", false );

    _use_numerical_jacobians_only = input("linear-nonlinear-solver/use_numerical_jacobians_only", false );

    numerical_jacobian_h =
      input("linear-nonlinear-solver/numerical_jacobian_h",
            numerical_jacobian_h);
  }

  void MultiphysicsSystem::init_data()
  {
    // Need this to be true because of our overloading of the
    // mass_residual function.
    // This is data in FEMSystem. MUST be set before FEMSystem::init_data.
    use_fixed_solution = true;

    // Initalize all the variables. We pass this pointer for the system.
    /* NOTE: We CANNOT fuse this loop with the others. This loop
       MUST complete first. */
    /*! \todo Figure out how to tell compilers not to fuse this loop when
      they want to be aggressive. */
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->init_variables( this );
      }

    // Now set time_evolving variables
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->set_time_evolving_vars( this );
      }

    // Set whether the problem we're solving is steady or not
    // Since the variable is static, just call one Physics class
    {
      (_physics_list.begin()->second)->set_is_steady((this->time_solver)->is_steady());
    }

    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	// Initialize builtin BC's for each physics
	(physics_iter->second)->init_bcs( this );
      }

    // Next, call parent init_data function to intialize everything.
    libMesh::FEMSystem::init_data();

    // After solution has been initialized we can project initial
    // conditions to it
    libMesh::CompositeFunction<libMesh::Number> ic_function;
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	// Initialize builtin IC's for each physics
	(physics_iter->second)->init_ics( this, ic_function );
      }

    if (ic_function.n_subfunctions())
      {
        this->project_solution(&ic_function);
      }

    // Now do any auxillary initialization required by each Physics
    for( PhysicsListIter physics_iter = _physics_list.begin();
         physics_iter != _physics_list.end();
         physics_iter++ )
      {
        (physics_iter->second)->auxiliary_init( *this );
      }

    return;
  }

  libMesh::AutoPtr<libMesh::DiffContext> MultiphysicsSystem::build_context()
  {
    AssemblyContext* context = new AssemblyContext(*this);

    libMesh::AutoPtr<libMesh::DiffContext> ap(context);

    libMesh::DifferentiablePhysics* phys = libMesh::FEMSystem::get_physics();

    libmesh_assert(phys);

    // If we are solving a moving mesh problem, tell that to the Context
    context->set_mesh_system(phys->get_mesh_system());
    context->set_mesh_x_var(phys->get_mesh_x_var());
    context->set_mesh_y_var(phys->get_mesh_y_var());
    context->set_mesh_z_var(phys->get_mesh_z_var());

    ap->set_deltat_pointer( &deltat );

    // If we are solving the adjoint problem, tell that to the Context
    ap->is_adjoint() = this->get_time_solver().is_adjoint();

    return ap;
  }

  void MultiphysicsSystem::register_postprocessing_vars( const GetPot& input,
                                                         PostProcessedQuantities<libMesh::Real>& postprocessing )
  {
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
        (physics_iter->second)->register_postprocessing_vars( input, postprocessing );
      }

    return;
  }

  void MultiphysicsSystem::init_context( libMesh::DiffContext& context )
  {
    AssemblyContext& c = libMesh::libmesh_cast_ref<AssemblyContext&>(context);

    //Loop over each physics to initialize relevant variable structures for assembling system
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->init_context( c );
      }

    return;
  }

  bool MultiphysicsSystem::_general_residual( bool request_jacobian,
					      libMesh::DiffContext& context,
                                              ResFuncType resfunc,
                                              CacheFuncType cachefunc)
  {
    AssemblyContext& c = libMesh::libmesh_cast_ref<AssemblyContext&>(context);

    bool compute_jacobian = true;
    if( !request_jacobian || _use_numerical_jacobians_only ) compute_jacobian = false;

    CachedValues cache;

    // Now compute cache for this element
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
        // boost::shared_ptr gets confused by operator->*
	((*(physics_iter->second)).*cachefunc)( c, cache );
      }

    // Loop over each physics and compute their contributions
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
        if(c.has_elem())
          {
            if( (physics_iter->second)->enabled_on_elem( &c.get_elem() ) )
              {
                ((*(physics_iter->second)).*resfunc)( compute_jacobian, c, cache );
              }
          }
        else
          {
            ((*(physics_iter->second)).*resfunc)( compute_jacobian, c, cache );
          }
      }

    // TODO: Need to think about the implications of this because there might be some
    // TODO: jacobian terms we don't want to compute for efficiency reasons
    return compute_jacobian;
  }

  bool MultiphysicsSystem::element_time_derivative( bool request_jacobian,
						    libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::element_time_derivative,
       &GRINS::Physics::compute_element_time_derivative_cache);
  }

  bool MultiphysicsSystem::side_time_derivative( bool request_jacobian,
						 libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::side_time_derivative,
       &GRINS::Physics::compute_side_time_derivative_cache);
  }

  bool MultiphysicsSystem::nonlocal_time_derivative( bool request_jacobian,
						     libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::nonlocal_time_derivative,
       &GRINS::Physics::compute_nonlocal_time_derivative_cache);
  }

  bool MultiphysicsSystem::element_constraint( bool request_jacobian,
					       libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::element_constraint,
       &GRINS::Physics::compute_element_constraint_cache);
  }

  bool MultiphysicsSystem::side_constraint( bool request_jacobian,
					    libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::side_constraint,
       &GRINS::Physics::compute_side_constraint_cache);
  }

  bool MultiphysicsSystem::nonlocal_constraint( bool request_jacobian,
					        libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::nonlocal_constraint,
       &GRINS::Physics::compute_nonlocal_constraint_cache);
  }

  bool MultiphysicsSystem::mass_residual( bool request_jacobian,
					  libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::mass_residual,
       &GRINS::Physics::compute_mass_residual_cache);
  }

  bool MultiphysicsSystem::nonlocal_mass_residual( bool request_jacobian,
					           libMesh::DiffContext& context )
  {
    return this->_general_residual
      (request_jacobian,
       context,
       &GRINS::Physics::nonlocal_mass_residual,
       &GRINS::Physics::compute_nonlocal_mass_residual_cache);
  }

  std::tr1::shared_ptr<Physics> MultiphysicsSystem::get_physics( const std::string physics_name )
  {
    if( _physics_list.find( physics_name ) == _physics_list.end() )
      {
	std::cerr << "Error: Could not find physics " << physics_name << std::endl;
	libmesh_error();
      }

    return _physics_list[physics_name];
  }

  bool MultiphysicsSystem::has_physics( const std::string physics_name ) const
  {
    bool has_physics = false;

    if( _physics_list.find(physics_name) != _physics_list.end() )
      has_physics = true;

    return has_physics;
  }

  void MultiphysicsSystem::compute_postprocessed_quantity( unsigned int quantity_index,
                                                           const AssemblyContext& context,
                                                           const libMesh::Point& point,
                                                           libMesh::Real& value )
  {
    for( PhysicsListIter physics_iter = _physics_list.begin();
         physics_iter != _physics_list.end();
         physics_iter++ )
      {
        // Only compute if physics is active on current subdomain or globally
        if( (physics_iter->second)->enabled_on_elem( &context.get_elem() ) )
          {
            (physics_iter->second)->compute_postprocessed_quantity( quantity_index, context, point, value );
          }
      }
    return;
  }

#ifdef GRINS_USE_GRVY_TIMERS
  void MultiphysicsSystem::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
  {
    _timer = grvy_timer;

    // Attach timers to each physics
    for( PhysicsListIter physics_iter = _physics_list.begin();
	 physics_iter != _physics_list.end();
	 physics_iter++ )
      {
	(physics_iter->second)->attach_grvy_timer( grvy_timer );
      }

    return;
  }
#endif

} // namespace GRINS
<|endoftext|>


<commit_before>/**
 ** \file object/object.cc
 ** \brief Implementation of object::Object.
 */

#include <algorithm>

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include "libport/containers.hh"

#include "object/object.hh"
#include "object/atom.hh"
#include "object/urbi-exception.hh"

namespace object
{
  /*-------.
  | kind.  |
  `-------*/

  const char*
  Object::string_of (Object::kind_type k)
  {
    switch (k)
      {
#define CASE(What, Name) case kind_ ## What: return #Name; break;
	APPLY_ON_ALL_PRIMITIVES(CASE);
#undef CASE
      }
    pabort("unreachable");
  }

  /*--------.
  | Slots.  |
  `--------*/

  Object::locate_type
  Object::slot_locate (const key_type& k, Object::objects_type& os) const
  {
    /// Look in local slots.
    slots_type::const_iterator it = slots_.find (k);
    if (libport::mhas(slots_, k))
      return locate_type(true, rObject());

    /// Break recursive loops.
    if (libport::mhas(os, this))
      return locate_type(false, rObject());
    os.insert (this);

    /// Look in proto slots (depth first search).
    locate_type res;
    BOOST_FOREACH(rObject p, protos_)
      if ((res = p->slot_locate(k, os)).first)
	return res.second?res:locate_type(true, p);
    return locate_type(false, rObject());
  }

  rObject slot_locate(const rObject& ref, const Object::key_type& k)
  {
    Object::objects_type os;
    Object::locate_type l = ref->slot_locate(k, os);
    if (l.first)
      return l.second? l.second:ref;
    else
      return rObject();
  }

  Object*
  Object::slot_locate(const key_type& k) const
  {
    objects_type os;
    Object::locate_type l = slot_locate(k, os);
    if (l.first)
      return const_cast<Object*>(l.second?l.second.get():this);
    else
      return 0;
  }

  Object&
  Object::safe_slot_locate(const key_type& k) const
  {
    Object* r = slot_locate(k);
    if (!r)
      boost::throw_exception (LookupError(k));
    return *r;
  }

  const rObject&
  Object::slot_get (const key_type& k) const
  {
    Object& cont = safe_slot_locate(k);
    return cont.own_slot_get(k);
  }

  rObject&
  Object::slot_get (const key_type& k)
  {
    return const_cast<rObject&>(const_cast<const Object*>(this)->slot_get(k));
  }

  Object&
  Object::slot_set (const Object::key_type& k, rObject o)
  {
    if (libport::mhas(slots_, k))
      boost::throw_exception (RedefinitionError(k));
    slots_[k] = o;
    return *this;
  }

  Object&
  Object::slot_update (const Object::key_type& k, rObject o)
  {
    Object& l = safe_slot_locate(k);

    if (locals_ && l.locals_)  // Local scope writes local var: no copyonwrite.
      l.own_slot_get(k) = o;
    else if (locals_ && !l.locals_)
    {
      // Local->class: copyonwrite to "self".
      rObject self = slot_get(SYMBOL(self));
      assert(self);
      if (self.get() == this)
	slots_[k] = o;
      else
	self->slot_update(k, o);
    }
    else // Class->class: copy on write.
      slots_[k] = o;

    return *this;
  }

  /*-----------.
  | Printing.  |
  `-----------*/

  std::ostream&
  Object::special_slots_dump (std::ostream& o) const
  {
    return o;
  }

  bool
  Object::operator< (const Object& rhs) const
  {
    return this < &rhs;
  }

  std::ostream&
  Object::id_dump (std::ostream& o) const
  {
    try
    {
      // Should be an rString.
      o << slot_get(SYMBOL(type)).cast<String>()->value_get ();
    }
    catch (UrbiException&)
    {}
    return o << '_' << this;
  }

  std::ostream&
  Object::dump (std::ostream& o) const
  {
    id_dump (o);
    /// Use xalloc/iword to store our current depth within the stream object.
    static const long idx = o.xalloc();
    static const long depth_max = 3;
    long& current_depth = o.iword(idx);
    /// Stop recursion at depth_max.
    if (current_depth > depth_max)
      return o << " <...>";
    ++current_depth;
    o << " {" << libport::incendl;
    if (protos_.begin () != protos_.end ())
      {
	o << "protos = ";
	for (protos_type::const_iterator i = protos_.begin ();
	     i != protos_.end (); ++i)
	  {
	    if (i != protos_.begin())
	      o << ", ";
	    (*i)->id_dump (o);
	  }
	o << libport::iendl;
      }
    special_slots_dump (o);
    BOOST_FOREACH (slot_type s, slots_)
      o << s << libport::iendl;
    o << libport::decindent << '}';
    //We can not reuse current_depth variable above according to spec.
    o.iword(idx)--;
    return o;
  }

  std::ostream&
  Object::print(std::ostream& out) const
  {
    // Temporary hack, detect void and print nothing
    if (this == void_class.get())
      return out;
    // FIXME: Decide what should be printed, but at least print something
    return out << "<object_" << std::hex << (long) (this) << ">";
  }

} // namespace object
<commit_msg>Simplify useless recursion<commit_after>/**
 ** \file object/object.cc
 ** \brief Implementation of object::Object.
 */

#include <algorithm>

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include "libport/containers.hh"

#include "object/object.hh"
#include "object/atom.hh"
#include "object/urbi-exception.hh"

namespace object
{
  /*-------.
  | kind.  |
  `-------*/

  const char*
  Object::string_of (Object::kind_type k)
  {
    switch (k)
      {
#define CASE(What, Name) case kind_ ## What: return #Name; break;
	APPLY_ON_ALL_PRIMITIVES(CASE);
#undef CASE
      }
    pabort("unreachable");
  }

  /*--------.
  | Slots.  |
  `--------*/

  Object::locate_type
  Object::slot_locate (const key_type& k, Object::objects_type& os) const
  {
    /// Look in local slots.
    slots_type::const_iterator it = slots_.find (k);
    if (libport::mhas(slots_, k))
      return locate_type(true, rObject());

    /// Break recursive loops.
    if (libport::mhas(os, this))
      return locate_type(false, rObject());
    os.insert (this);

    /// Look in proto slots (depth first search).
    locate_type res;
    BOOST_FOREACH(rObject p, protos_)
      if ((res = p->slot_locate(k, os)).first)
	return res.second?res:locate_type(true, p);
    return locate_type(false, rObject());
  }

  rObject slot_locate(const rObject& ref, const Object::key_type& k)
  {
    Object::objects_type os;
    Object::locate_type l = ref->slot_locate(k, os);
    if (l.first)
      return l.second? l.second:ref;
    else
      return rObject();
  }

  Object*
  Object::slot_locate(const key_type& k) const
  {
    objects_type os;
    Object::locate_type l = slot_locate(k, os);
    if (l.first)
      return const_cast<Object*>(l.second?l.second.get():this);
    else
      return 0;
  }

  Object&
  Object::safe_slot_locate(const key_type& k) const
  {
    Object* r = slot_locate(k);
    if (!r)
      boost::throw_exception (LookupError(k));
    return *r;
  }

  const rObject&
  Object::slot_get (const key_type& k) const
  {
    Object& cont = safe_slot_locate(k);
    return cont.own_slot_get(k);
  }

  rObject&
  Object::slot_get (const key_type& k)
  {
    return const_cast<rObject&>(const_cast<const Object*>(this)->slot_get(k));
  }

  Object&
  Object::slot_set (const Object::key_type& k, rObject o)
  {
    if (libport::mhas(slots_, k))
      boost::throw_exception (RedefinitionError(k));
    slots_[k] = o;
    return *this;
  }

  Object&
  Object::slot_update (const Object::key_type& k, rObject o)
  {
    Object& l = safe_slot_locate(k);

    if (locals_ && l.locals_)  // Local scope writes local var: no copyonwrite.
      l.own_slot_get(k) = o;
    else if (locals_ && !l.locals_)
    {
      // Local->class: copyonwrite to "self".
      rObject self = slot_get(SYMBOL(self));
      assert(self);
      self.get ()->slots_[k] = o;
    }
    else // Class->class: copy on write.
      slots_[k] = o;

    return *this;
  }

  /*-----------.
  | Printing.  |
  `-----------*/

  std::ostream&
  Object::special_slots_dump (std::ostream& o) const
  {
    return o;
  }

  bool
  Object::operator< (const Object& rhs) const
  {
    return this < &rhs;
  }

  std::ostream&
  Object::id_dump (std::ostream& o) const
  {
    try
    {
      // Should be an rString.
      o << slot_get(SYMBOL(type)).cast<String>()->value_get ();
    }
    catch (UrbiException&)
    {}
    return o << '_' << this;
  }

  std::ostream&
  Object::dump (std::ostream& o) const
  {
    id_dump (o);
    /// Use xalloc/iword to store our current depth within the stream object.
    static const long idx = o.xalloc();
    static const long depth_max = 3;
    long& current_depth = o.iword(idx);
    /// Stop recursion at depth_max.
    if (current_depth > depth_max)
      return o << " <...>";
    ++current_depth;
    o << " {" << libport::incendl;
    if (protos_.begin () != protos_.end ())
      {
	o << "protos = ";
	for (protos_type::const_iterator i = protos_.begin ();
	     i != protos_.end (); ++i)
	  {
	    if (i != protos_.begin())
	      o << ", ";
	    (*i)->id_dump (o);
	  }
	o << libport::iendl;
      }
    special_slots_dump (o);
    BOOST_FOREACH (slot_type s, slots_)
      o << s << libport::iendl;
    o << libport::decindent << '}';
    //We can not reuse current_depth variable above according to spec.
    o.iword(idx)--;
    return o;
  }

  std::ostream&
  Object::print(std::ostream& out) const
  {
    // Temporary hack, detect void and print nothing
    if (this == void_class.get())
      return out;
    // FIXME: Decide what should be printed, but at least print something
    return out << "<object_" << std::hex << (long) (this) << ">";
  }

} // namespace object
<|endoftext|>


<commit_before>// Copyright (C) 2009, 2010 by Florent Lamiraux, Thomas Moulard, JRL.
//
// This file is part of the hpp-corbaserver.
//
// This software is provided "as is" without warranty of any kind,
// either expressed or implied, including but not limited to the
// implied warranties of fitness for a particular purpose.
//
// See the COPYING file for more information.

#include <iostream>
#include <hpp/util/debug.hh>
#include <fcl/BVH/BVH_model.h>
#include <fcl/shape/geometric_shapes.h>
#include <hpp/model/collision-object.hh>
#include <hpp/model/urdf/util.hh>
#include "obstacle.impl.hh"
#include "tools.hh"

#include "hpp/corbaserver/server.hh"

namespace hpp
{
  namespace corbaServer
  {
    namespace impl
    {
      Obstacle::Obstacle (corbaServer::Server* server)
	: server_ (server),
	  problemSolver_ (server->problemSolver ())
      {}

      void Obstacle::loadObstacleModel (const char* package,
					const char* filename,
					const char* prefix)
	throw (hpp::Error)
      {
	try {
	  model::DevicePtr_t device (model::Device::create
				     (std::string (filename)));
	  hpp::model::urdf::loadUrdfModel (device,
					   "anchor",
					   std::string (package),
					   std::string (filename));
	  // Detach objects from joints
	  for (ObjectIterator itObj = device->objectIterator
		 (hpp::model::COLLISION); !itObj.isEnd (); ++itObj) {
	    CollisionObjectPtr_t obj = model::CollisionObject::create
	      ((*itObj)->fcl ()->collisionGeometry(), (*itObj)->getTransform (),
	       std::string (prefix) + (*itObj)->name ());
	    problemSolver_->addObstacle (obj, true, true);
	    hppDout (info, "Adding obstacle " << obj->name ());
	  }
	} catch (const std::exception& exc) {
	  throw hpp::Error (exc.what ());
	}
      }

      void Obstacle::removeObstacleFromJoint
      (const char* objectName, const char* jointName, Boolean collision,
       Boolean distance) throw (hpp::Error)
      {
	using model::JointPtr_t;
	using model::ObjectVector_t;
	using model::COLLISION;
	using model::DISTANCE;
	std::string objName (objectName);
	std::string jName (jointName);

	try {
	  JointPtr_t joint = problemSolver_->robot ()->getJointByName (jName);
	  BodyPtr_t body = joint->linkedBody ();
	  if (!body) {
	    throw std::runtime_error
	      (std::string ("Joint " + jName + std::string (" has no body.")));
	  }
	  if (collision) {
	    bool found = false;
	    for (ObjectVector_t::const_iterator itObj =
		   body->outerObjects (COLLISION).begin ();
		 itObj != body->outerObjects (COLLISION).end () &&
		   !found; ++itObj) {
	      if ((*itObj)->name () == objName) {
		found = true;
		body->removeOuterObject (*itObj, true, false);
	      }
	    }
	    if (!found) {
	      throw std::runtime_error
		(std::string ("Joint ") + jName +
		 std::string (" has no outer object called ") + objName);
	    }
	  }
	  if (distance) {
	    bool found = false;
	    for (ObjectVector_t::const_iterator itObj =
		   body->outerObjects (DISTANCE).begin ();
		 itObj != body->outerObjects (DISTANCE).end () &&
		   !found; ++itObj) {
	      if ((*itObj)->name () == objName) {
		found = true;
		body->removeOuterObject (*itObj, false, true);
	      }
	    }
	    if (!found) {
	      throw std::runtime_error
		(std::string ("Joint ") + jName +
		 std::string (" has no outer object called ") + objName);
	    }
	  }
	} catch (const std::exception& exc) {
	  throw hpp::Error (exc.what ());
	}
      }

      void
      Obstacle::addObstacle(const char* objectName, Boolean collision,
			    Boolean distance)
	throw (hpp::Error)
      {
	std::string objName (objectName);
	CollisionGeometryPtr_t geometry;
	// Check that polyhedron exists.
	VertexMap_t::const_iterator itVertex = vertexMap_.find(objName);
	if (itVertex != vertexMap_.end ()) {
	  PolyhedronPtr_t polyhedron = PolyhedronPtr_t (new Polyhedron_t);
	  int res = polyhedron->beginModel ();
	  if (res != fcl::BVH_OK) {
	    std::ostringstream oss ("fcl BVHReturnCode = ");
	    oss << res;
	    throw hpp::Error (oss.str ().c_str ());
	  }

	  polyhedron->addSubModel (itVertex->second, triangleMap_ [objName]);
	  polyhedron->endModel ();
	  geometry = polyhedron;
	} else {
	  ShapeMap_t::iterator itShape = shapeMap_.find (objName);
	  if (itShape != shapeMap_.end ()) {
	    geometry = itShape->second;
	  }
	}
	if (!geometry) {
	  std::ostringstream oss ("Object ");
	  oss << objName << " does not exist.";
	  throw hpp::Error (oss.str ().c_str ());
	}

	Transform3f pos; pos.setIdentity ();
	CollisionObjectPtr_t collisionObject
	  (CollisionObject_t::create (geometry, pos, objName));
	problemSolver_->addObstacle (collisionObject, collision, distance);
      }

      CollisionObjectPtr_t Obstacle::getObstacleByName (const char* name)
      {
	const ObjectVector_t& collisionObstacles
	  (problemSolver_->collisionObstacles ());
	for (ObjectVector_t::const_iterator it = collisionObstacles.begin ();
	     it != collisionObstacles.end (); it++) {
	  CollisionObjectPtr_t object = *it;
	  if (object->name () == name) {
	    hppDout (info, "found \""
		     << object->name () << "\" in the obstacle list.");
	    return object;
	  }
	}
	const ObjectVector_t& distanceObstacles
	  (problemSolver_->distanceObstacles ());
	for (ObjectVector_t::const_iterator it = distanceObstacles.begin ();
	     it != distanceObstacles.end (); it++) {
	  CollisionObjectPtr_t object = *it;
	  if (object->name () == name) {
	    hppDout (info, "found \""
		     << object->name () << "\" in the obstacle list.");
	    return object;
	  }
	}
	return CollisionObjectPtr_t ();
      }

      void Obstacle::moveObstacle
      (const char* objectName, const CORBA::Double* cfg)
	throw(hpp::Error)
      {
	CollisionObjectPtr_t object = getObstacleByName (objectName);
	if (object) {
	  Transform3f mat;
	  hppTransformToTransform3f (cfg, mat);
	  object->move (mat);
	  return;
	}
	std::ostringstream oss ("Object ");
	oss << objectName <<  " not found";
	throw hpp::Error (oss.str ().c_str ());
      }

      void Obstacle::getObstaclePosition (const char* objectName,
					  Double* cfg)
	  throw (hpp::Error)
      {
	CollisionObjectPtr_t object = getObstacleByName (objectName);
	if (object) {
	  Transform3f transform = object->getTransform ();
	  Transform3fTohppTransform (transform, cfg);
	  return;
	}
	std::ostringstream oss ("Object ");
	oss << objectName <<  " not found";
	throw hpp::Error (oss.str ().c_str ());
      }

      void Obstacle::createPolyhedron
      (const char* polyhedronName) throw (hpp::Error)
      {
	// Check that polyhedron does not already exist.
	if (vertexMap_.find(polyhedronName) != vertexMap_.end ()) {
	  std::ostringstream oss ("polyhedron ");
	  oss << polyhedronName << " already exists.";
	  throw hpp::Error (oss.str ().c_str ());
	}
	vertexMap_ [polyhedronName] = std::vector <fcl::Vec3f> ();
	triangleMap_ [polyhedronName] = std::vector <fcl::Triangle> ();
      }

      void Obstacle::createBox
      (const char* boxName, Double x, Double y, Double z)
	throw (hpp::Error)
      {
	std::string shapeName(boxName);
	// Check that object does not already exist.
	if (vertexMap_.find(shapeName) != vertexMap_.end () ||
	    shapeMap_.find (shapeName) != shapeMap_.end ()) {
	  std::ostringstream oss ("object ");
	  oss << shapeName << " already exists.";
	  throw hpp::Error (oss.str ().c_str ());
	}
	BasicShapePtr_t box (new fcl::Box ( x, y, z));
	shapeMap_[shapeName] = box;
      }

      Short Obstacle::addPoint
      (const char* polyhedronName, Double x, Double y, Double z)
	throw (hpp::Error)
      {
	// Check that polyhedron exists.
	VertexMap_t::iterator itVertex = vertexMap_.find (polyhedronName);
	if (itVertex == vertexMap_.end ()) {
	  std::ostringstream oss ("polyhedron ");
	  oss << polyhedronName << " does not exist.";
	  throw hpp::Error (oss.str ().c_str ());
	}
	itVertex->second.push_back (fcl::Vec3f (x, y, z));
	return static_cast<Short> (vertexMap_.size ());
      }

      Short
      Obstacle::addTriangle
      (const char* polyhedronName, ULong pt1, ULong pt2, ULong pt3)
	throw (hpp::Error)
      {
	// Check that polyhedron exists.
	TriangleMap_t::iterator itTriangle = triangleMap_.find (polyhedronName);
	if (itTriangle == triangleMap_.end ()) {
	  std::ostringstream oss ("polyhedron ");
	  oss << polyhedronName << " does not exist.";
	  throw hpp::Error (oss.str ().c_str ());
	}

	itTriangle->second.push_back (fcl::Triangle (pt1, pt2, pt3));
	return static_cast<Short> (triangleMap_.size ());
      }
    } // end of namespace implementation.
  } // end of namespace corbaServer.
} // end of namespace hpp.
<commit_msg>Update method removeObstacleFromJoint.<commit_after>// Copyright (C) 2009, 2010 by Florent Lamiraux, Thomas Moulard, JRL.
//
// This file is part of the hpp-corbaserver.
//
// This software is provided "as is" without warranty of any kind,
// either expressed or implied, including but not limited to the
// implied warranties of fitness for a particular purpose.
//
// See the COPYING file for more information.

#include <iostream>
#include <hpp/util/debug.hh>
#include <fcl/BVH/BVH_model.h>
#include <fcl/shape/geometric_shapes.h>
#include <hpp/model/collision-object.hh>
#include <hpp/model/urdf/util.hh>
#include "obstacle.impl.hh"
#include "tools.hh"

#include "hpp/corbaserver/server.hh"

namespace hpp
{
  namespace corbaServer
  {
    namespace impl
    {
      Obstacle::Obstacle (corbaServer::Server* server)
	: server_ (server),
	  problemSolver_ (server->problemSolver ())
      {}

      void Obstacle::loadObstacleModel (const char* package,
					const char* filename,
					const char* prefix)
	throw (hpp::Error)
      {
	try {
	  model::DevicePtr_t device (model::Device::create
				     (std::string (filename)));
	  hpp::model::urdf::loadUrdfModel (device,
					   "anchor",
					   std::string (package),
					   std::string (filename));
	  // Detach objects from joints
	  for (ObjectIterator itObj = device->objectIterator
		 (hpp::model::COLLISION); !itObj.isEnd (); ++itObj) {
	    CollisionObjectPtr_t obj = model::CollisionObject::create
	      ((*itObj)->fcl ()->collisionGeometry(), (*itObj)->getTransform (),
	       std::string (prefix) + (*itObj)->name ());
	    problemSolver_->addObstacle (obj, true, true);
	    hppDout (info, "Adding obstacle " << obj->name ());
	  }
	} catch (const std::exception& exc) {
	  throw hpp::Error (exc.what ());
	}
      }

      void Obstacle::removeObstacleFromJoint
      (const char* objectName, const char* jointName, Boolean collision,
       Boolean distance) throw (hpp::Error)
      {
	using model::JointPtr_t;
	using model::ObjectVector_t;
	using model::COLLISION;
	using model::DISTANCE;
	std::string objName (objectName);
	std::string jName (jointName);

	try {
	  if (collision) {
	    problemSolver_->removeObstacleFromJoint (objectName, jointName);
	  }
	  if (distance) {
	    throw std::runtime_error ("Not implemented.");
	  }
	} catch (const std::exception& exc) {
	  throw hpp::Error (exc.what ());
	}
      }

      void
      Obstacle::addObstacle(const char* objectName, Boolean collision,
			    Boolean distance)
	throw (hpp::Error)
      {
	std::string objName (objectName);
	CollisionGeometryPtr_t geometry;
	// Check that polyhedron exists.
	VertexMap_t::const_iterator itVertex = vertexMap_.find(objName);
	if (itVertex != vertexMap_.end ()) {
	  PolyhedronPtr_t polyhedron = PolyhedronPtr_t (new Polyhedron_t);
	  int res = polyhedron->beginModel ();
	  if (res != fcl::BVH_OK) {
	    std::ostringstream oss ("fcl BVHReturnCode = ");
	    oss << res;
	    throw hpp::Error (oss.str ().c_str ());
	  }

	  polyhedron->addSubModel (itVertex->second, triangleMap_ [objName]);
	  polyhedron->endModel ();
	  geometry = polyhedron;
	} else {
	  ShapeMap_t::iterator itShape = shapeMap_.find (objName);
	  if (itShape != shapeMap_.end ()) {
	    geometry = itShape->second;
	  }
	}
	if (!geometry) {
	  std::ostringstream oss ("Object ");
	  oss << objName << " does not exist.";
	  throw hpp::Error (oss.str ().c_str ());
	}

	Transform3f pos; pos.setIdentity ();
	CollisionObjectPtr_t collisionObject
	  (CollisionObject_t::create (geometry, pos, objName));
	problemSolver_->addObstacle (collisionObject, collision, distance);
      }

      CollisionObjectPtr_t Obstacle::getObstacleByName (const char* name)
      {
	const ObjectVector_t& collisionObstacles
	  (problemSolver_->collisionObstacles ());
	for (ObjectVector_t::const_iterator it = collisionObstacles.begin ();
	     it != collisionObstacles.end (); it++) {
	  CollisionObjectPtr_t object = *it;
	  if (object->name () == name) {
	    hppDout (info, "found \""
		     << object->name () << "\" in the obstacle list.");
	    return object;
	  }
	}
	const ObjectVector_t& distanceObstacles
	  (problemSolver_->distanceObstacles ());
	for (ObjectVector_t::const_iterator it = distanceObstacles.begin ();
	     it != distanceObstacles.end (); it++) {
	  CollisionObjectPtr_t object = *it;
	  if (object->name () == name) {
	    hppDout (info, "found \""
		     << object->name () << "\" in the obstacle list.");
	    return object;
	  }
	}
	return CollisionObjectPtr_t ();
      }

      void Obstacle::moveObstacle
      (const char* objectName, const CORBA::Double* cfg)
	throw(hpp::Error)
      {
	CollisionObjectPtr_t object = getObstacleByName (objectName);
	if (object) {
	  Transform3f mat;
	  hppTransformToTransform3f (cfg, mat);
	  object->move (mat);
	  return;
	}
	std::ostringstream oss ("Object ");
	oss << objectName <<  " not found";
	throw hpp::Error (oss.str ().c_str ());
      }

      void Obstacle::getObstaclePosition (const char* objectName,
					  Double* cfg)
	  throw (hpp::Error)
      {
	CollisionObjectPtr_t object = getObstacleByName (objectName);
	if (object) {
	  Transform3f transform = object->getTransform ();
	  Transform3fTohppTransform (transform, cfg);
	  return;
	}
	std::ostringstream oss ("Object ");
	oss << objectName <<  " not found";
	throw hpp::Error (oss.str ().c_str ());
      }

      void Obstacle::createPolyhedron
      (const char* polyhedronName) throw (hpp::Error)
      {
	// Check that polyhedron does not already exist.
	if (vertexMap_.find(polyhedronName) != vertexMap_.end ()) {
	  std::ostringstream oss ("polyhedron ");
	  oss << polyhedronName << " already exists.";
	  throw hpp::Error (oss.str ().c_str ());
	}
	vertexMap_ [polyhedronName] = std::vector <fcl::Vec3f> ();
	triangleMap_ [polyhedronName] = std::vector <fcl::Triangle> ();
      }

      void Obstacle::createBox
      (const char* boxName, Double x, Double y, Double z)
	throw (hpp::Error)
      {
	std::string shapeName(boxName);
	// Check that object does not already exist.
	if (vertexMap_.find(shapeName) != vertexMap_.end () ||
	    shapeMap_.find (shapeName) != shapeMap_.end ()) {
	  std::ostringstream oss ("object ");
	  oss << shapeName << " already exists.";
	  throw hpp::Error (oss.str ().c_str ());
	}
	BasicShapePtr_t box (new fcl::Box ( x, y, z));
	shapeMap_[shapeName] = box;
      }

      Short Obstacle::addPoint
      (const char* polyhedronName, Double x, Double y, Double z)
	throw (hpp::Error)
      {
	// Check that polyhedron exists.
	VertexMap_t::iterator itVertex = vertexMap_.find (polyhedronName);
	if (itVertex == vertexMap_.end ()) {
	  std::ostringstream oss ("polyhedron ");
	  oss << polyhedronName << " does not exist.";
	  throw hpp::Error (oss.str ().c_str ());
	}
	itVertex->second.push_back (fcl::Vec3f (x, y, z));
	return static_cast<Short> (vertexMap_.size ());
      }

      Short
      Obstacle::addTriangle
      (const char* polyhedronName, ULong pt1, ULong pt2, ULong pt3)
	throw (hpp::Error)
      {
	// Check that polyhedron exists.
	TriangleMap_t::iterator itTriangle = triangleMap_.find (polyhedronName);
	if (itTriangle == triangleMap_.end ()) {
	  std::ostringstream oss ("polyhedron ");
	  oss << polyhedronName << " does not exist.";
	  throw hpp::Error (oss.str ().c_str ());
	}

	itTriangle->second.push_back (fcl::Triangle (pt1, pt2, pt3));
	return static_cast<Short> (triangleMap_.size ());
      }
    } // end of namespace implementation.
  } // end of namespace corbaServer.
} // end of namespace hpp.
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2008  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "User.h"
#include "znc.h"

// Forward Declaration
class CShellMod;

class CShellSock : public CExecSock {
public:
	CShellSock(CShellMod* pShellMod, CClient* pClient, const CString& sExec) : CExecSock( sExec ) {
		EnableReadLine();
		m_pParent = pShellMod;
		m_pClient = pClient;
	}
	// These next two function's bodies are at the bottom of the file since they reference CShellMod
	virtual void ReadLine(const CString& sData);
	virtual void Disconnected();

	CShellMod*	m_pParent;

private:
	CClient*	m_pClient;
};

class CShellMod : public CModule {
public:
	MODCONSTRUCTOR(CShellMod) {
		m_sPath = CZNC::Get().GetHomePath();
	}

	virtual ~CShellMod() {
		vector<Csock*> vSocks = m_pManager->FindSocksByName("SHELL");

		for (unsigned int a = 0; a < vSocks.size(); a++) {
			m_pManager->DelSockByAddr(vSocks[a]);
		}
	}

	virtual bool OnLoad(const CString& sArgs, CString& sMessage)
	{
#ifndef MOD_SHELL_ALLOW_EVERYONE
		if (!m_pUser->IsAdmin()) {
			sMessage = "You must be admin to use the shell module";
			return false;
		}
#endif

		return true;
	}

	virtual void OnModCommand(const CString& sCommand) {
		if ((strcasecmp(sCommand.c_str(), "cd") == 0) || (strncasecmp(sCommand.c_str(), "cd ", 3) == 0)) {
			CString sPath = CUtils::ChangeDir(m_sPath, ((sCommand.length() == 2) ? CString(CZNC::Get().GetHomePath()) : CString(sCommand.substr(3))), CZNC::Get().GetHomePath());
			CFile Dir(sPath);

			if (Dir.IsDir()) {
				m_sPath = sPath;
			} else if (Dir.Exists()) {
				PutShell("cd: not a directory [" + sPath + "]");
			} else {
				PutShell("cd: no such directory [" + sPath + "]");
			}

			PutShell("znc$");
		} else if (strcasecmp(sCommand.Token(0).c_str(), "SEND") == 0) {
			CString sToNick = sCommand.Token(1);
			CString sFile = sCommand.Token(2);

			if ((sToNick.empty()) || (sFile.empty())) {
				PutShell("usage: Send <nick> <file>");
			} else {
				sFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath());

				if (!CFile::Exists(sFile)) {
					PutShell("get: no such file [" + sFile + "]");
				} else if (!CFile::IsReg(sFile)) {
					PutShell("get: not a file [" + sFile + "]");
				} else {
					m_pUser->SendFile(sToNick, sFile, GetModName());
				}
			}
		} else if (strcasecmp(sCommand.Token(0).c_str(), "GET") == 0) {
			CString sFile = sCommand.Token(1);

			if (sFile.empty()) {
				PutShell("usage: Get <file>");
			} else {
				sFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath());

				if (!CFile::Exists(sFile)) {
					PutShell("get: no such file [" + sFile + "]");
				} else if (!CFile::IsReg(sFile)) {
					PutShell("get: not a file [" + sFile + "]");
				} else {
					m_pUser->SendFile(m_pUser->GetCurNick(), sFile, GetModName());
				}
			}
		} else {
			RunCommand(sCommand);
		}
	}

	virtual EModRet OnStatusCommand(const CString& sCommand) {
		if (strcasecmp(sCommand.c_str(), "SHELL") == 0) {
			PutShell("-- ZNC Shell Service --");
			return HALT;
		}

		return CONTINUE;
	}

	virtual EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize) {
		if (strcasecmp(RemoteNick.GetNick().c_str(), CString(GetModNick()).c_str()) == 0) {
			CString sLocalFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath());

			m_pUser->GetFile(m_pUser->GetCurNick(), CUtils::GetIP(uLongIP), uPort, sLocalFile, uFileSize, GetModName());

			return HALT;
		}

		return CONTINUE;
	}

	void PutShell(const CString& sLine) {
		CString sPath = m_sPath;

		CString::size_type a = sPath.find(' ');
		while (a != CString::npos) {
			sPath.replace(a, 1, "_");
			a = sPath.find(' ');
		}

		PutModule(sLine, m_pUser->GetCurNick(), sPath);
	}

	void RunCommand(const CString& sCommand) {
		m_pManager->AddSock((Csock*) new CShellSock(this, m_pClient, "cd " + m_sPath + " && " + sCommand), "SHELL");
	}
private:
	CString	m_sPath;
};

void CShellSock::ReadLine(const CString& sData) {
	CString sLine = sData;

	while (sLine.length() && (sLine[sLine.length() -1] == '\r' || sLine[sLine.length() -1] == '\n')) {
		sLine = sLine.substr(0, sLine.length() -1);
	}

	CString::size_type a = sLine.find('\t');
	while (a != CString::npos) {
		sLine.replace(a, 1, "    ");
		a = sLine.find('\t');
	}

	m_pParent->SetClient(m_pClient);
	m_pParent->PutShell(sLine);
	m_pParent->SetClient(NULL);
}

void CShellSock::Disconnected() {
	m_pParent->SetClient(m_pClient);
	m_pParent->PutShell("znc$");
	m_pParent->SetClient(NULL);
}

MODULEDEFS(CShellMod, "Gives shell access")

<commit_msg>Shell module: Also read incomplete lines (no trailing newline) and display them<commit_after>/*
 * Copyright (C) 2004-2008  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "User.h"
#include "znc.h"

// Forward Declaration
class CShellMod;

class CShellSock : public CExecSock {
public:
	CShellSock(CShellMod* pShellMod, CClient* pClient, const CString& sExec) : CExecSock( sExec ) {
		EnableReadLine();
		m_pParent = pShellMod;
		m_pClient = pClient;
	}
	// These next two function's bodies are at the bottom of the file since they reference CShellMod
	virtual void ReadLine(const CString& sData);
	virtual void Disconnected();

	CShellMod*	m_pParent;

private:
	CClient*	m_pClient;
};

class CShellMod : public CModule {
public:
	MODCONSTRUCTOR(CShellMod) {
		m_sPath = CZNC::Get().GetHomePath();
	}

	virtual ~CShellMod() {
		vector<Csock*> vSocks = m_pManager->FindSocksByName("SHELL");

		for (unsigned int a = 0; a < vSocks.size(); a++) {
			m_pManager->DelSockByAddr(vSocks[a]);
		}
	}

	virtual bool OnLoad(const CString& sArgs, CString& sMessage)
	{
#ifndef MOD_SHELL_ALLOW_EVERYONE
		if (!m_pUser->IsAdmin()) {
			sMessage = "You must be admin to use the shell module";
			return false;
		}
#endif

		return true;
	}

	virtual void OnModCommand(const CString& sCommand) {
		if ((strcasecmp(sCommand.c_str(), "cd") == 0) || (strncasecmp(sCommand.c_str(), "cd ", 3) == 0)) {
			CString sPath = CUtils::ChangeDir(m_sPath, ((sCommand.length() == 2) ? CString(CZNC::Get().GetHomePath()) : CString(sCommand.substr(3))), CZNC::Get().GetHomePath());
			CFile Dir(sPath);

			if (Dir.IsDir()) {
				m_sPath = sPath;
			} else if (Dir.Exists()) {
				PutShell("cd: not a directory [" + sPath + "]");
			} else {
				PutShell("cd: no such directory [" + sPath + "]");
			}

			PutShell("znc$");
		} else if (strcasecmp(sCommand.Token(0).c_str(), "SEND") == 0) {
			CString sToNick = sCommand.Token(1);
			CString sFile = sCommand.Token(2);

			if ((sToNick.empty()) || (sFile.empty())) {
				PutShell("usage: Send <nick> <file>");
			} else {
				sFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath());

				if (!CFile::Exists(sFile)) {
					PutShell("get: no such file [" + sFile + "]");
				} else if (!CFile::IsReg(sFile)) {
					PutShell("get: not a file [" + sFile + "]");
				} else {
					m_pUser->SendFile(sToNick, sFile, GetModName());
				}
			}
		} else if (strcasecmp(sCommand.Token(0).c_str(), "GET") == 0) {
			CString sFile = sCommand.Token(1);

			if (sFile.empty()) {
				PutShell("usage: Get <file>");
			} else {
				sFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath());

				if (!CFile::Exists(sFile)) {
					PutShell("get: no such file [" + sFile + "]");
				} else if (!CFile::IsReg(sFile)) {
					PutShell("get: not a file [" + sFile + "]");
				} else {
					m_pUser->SendFile(m_pUser->GetCurNick(), sFile, GetModName());
				}
			}
		} else {
			RunCommand(sCommand);
		}
	}

	virtual EModRet OnStatusCommand(const CString& sCommand) {
		if (strcasecmp(sCommand.c_str(), "SHELL") == 0) {
			PutShell("-- ZNC Shell Service --");
			return HALT;
		}

		return CONTINUE;
	}

	virtual EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize) {
		if (strcasecmp(RemoteNick.GetNick().c_str(), CString(GetModNick()).c_str()) == 0) {
			CString sLocalFile = CUtils::ChangeDir(m_sPath, sFile, CZNC::Get().GetHomePath());

			m_pUser->GetFile(m_pUser->GetCurNick(), CUtils::GetIP(uLongIP), uPort, sLocalFile, uFileSize, GetModName());

			return HALT;
		}

		return CONTINUE;
	}

	void PutShell(const CString& sLine) {
		CString sPath = m_sPath;

		CString::size_type a = sPath.find(' ');
		while (a != CString::npos) {
			sPath.replace(a, 1, "_");
			a = sPath.find(' ');
		}

		PutModule(sLine, m_pUser->GetCurNick(), sPath);
	}

	void RunCommand(const CString& sCommand) {
		m_pManager->AddSock((Csock*) new CShellSock(this, m_pClient, "cd " + m_sPath + " && " + sCommand), "SHELL");
	}
private:
	CString	m_sPath;
};

void CShellSock::ReadLine(const CString& sData) {
	CString sLine = sData;

	while (sLine.length() && (sLine[sLine.length() -1] == '\r' || sLine[sLine.length() -1] == '\n')) {
		sLine = sLine.substr(0, sLine.length() -1);
	}

	CString::size_type a = sLine.find('\t');
	while (a != CString::npos) {
		sLine.replace(a, 1, "    ");
		a = sLine.find('\t');
	}

	m_pParent->SetClient(m_pClient);
	m_pParent->PutShell(sLine);
	m_pParent->SetClient(NULL);
}

void CShellSock::Disconnected() {
	// If there is some incomplete line in the buffer, read it
	// (e.g. echo echo -n "hi" triggered this)
	CString &sBuffer = GetInternalBuffer();
	if (!sBuffer.empty())
		ReadLine(sBuffer);

	m_pParent->SetClient(m_pClient);
	m_pParent->PutShell("znc$");
	m_pParent->SetClient(NULL);
}

MODULEDEFS(CShellMod, "Gives shell access")

<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>

const double FIRST_BRACKET_LENGTH  = 18200;
const double SECOND_BRACKET_LENGTH = 18799;
const double THIRD_BRACKET_LENGTH  = 42999;
const double FOURTH_BRACKET_LENGTH = 100000;

const double P_FIRST_BRACKET = 1;
const double P_SECOND_BRACKET = 0.81;
const double P_THIRD_BRACKET = 0.675;
const double P_FOURTH_BRACKET = 0.63;
const double P_LAST_BRACKET = 0.55;

double tax_money_in_year(double income){
	double money_to_tax = income;
	double taxed_money = 0;

	// Between $0 - $18201
	if(money_to_tax >= 0){
		//If under the first bracket, no tax is taken.
		if(money_to_tax < FIRST_BRACKET_LENGTH){
			return money_to_tax;
		}
		taxed_money += FIRST_BRACKET_LENGTH * P_FIRST_BRACKET;
		money_to_tax -= FIRST_BRACKET_LENGTH;
	}

	// Between $18,201 - $37,000
	if(money_to_tax >= 0){

		if(money_to_tax < SECOND_BRACKET_LENGTH){
			return taxed_money + (money_to_tax * P_SECOND_BRACKET);
		}

		taxed_money += SECOND_BRACKET_LENGTH * P_SECOND_BRACKET;
		money_to_tax -= SECOND_BRACKET_LENGTH;
	}

	// Between $37,001 - $80,000
	if(money_to_tax >= 0){

		if(money_to_tax < THIRD_BRACKET_LENGTH){
			return taxed_money + (money_to_tax * P_THIRD_BRACKET);
		}

		taxed_money += THIRD_BRACKET_LENGTH * P_THIRD_BRACKET;
		money_to_tax -= THIRD_BRACKET_LENGTH;
	}

	// Between $80,001 - $180,000
	if(money_to_tax >= 0){

		if(money_to_tax < FOURTH_BRACKET_LENGTH){
			return taxed_money + (money_to_tax * P_FOURTH_BRACKET);
		}

		taxed_money += FOURTH_BRACKET_LENGTH * P_FOURTH_BRACKET;
		money_to_tax -= FOURTH_BRACKET_LENGTH;
	}

	// Greater than $180,000
	if(money_to_tax >= 0){
		taxed_money += money_to_tax * P_LAST_BRACKET;
		money_to_tax = 0;
	}

	return taxed_money;
}

int main(int argc, char* argv[]){

	if(argc != 4){
		std::cerr << "Usage: <y,m,w>(input) <dollars earned> <y,m,w>(output)" << std::endl;
		return 1;
	}

	const double user_input_wage = atof(argv[2]);
	double taxed_money_years;

	//Convers it to yearly for storage
	switch(*argv[1]){
		case 'y': taxed_money_years = tax_money_in_year(user_input_wage); break;
		case 'm': taxed_money_years = tax_money_in_year(user_input_wage * 12); break;
		case 'w': taxed_money_years = tax_money_in_year(user_input_wage * 52); break;
	}

	//Simply divides it back out.
	switch(*argv[3]){
		case 'y': std::cout << "Yearly earnings after tax is $" << taxed_money_years / 1.0 << std::endl; break;
		case 'm': std::cout << "Monthly earnings after tax is $" << taxed_money_years / 12.0 << std::endl; break;
		case 'w': std::cout << "Weekly earnings after tax is $" << taxed_money_years / 52.0 << std::endl; break;
	}

	switch(*argv[3]){
		case 'y': std::cout << "You lose $" << (user_input_wage	) - (taxed_money_years / 1.0) <<  " per year to the tax man" << std::endl; break;
		case 'm': std::cout << "You lose $" << (user_input_wage ) - (taxed_money_years / 12.0) << " per month to the tax man" << std::endl; break;
		case 'w': std::cout << "You lose $" << (user_input_wage ) - (taxed_money_years / 52.0) << " per week to the tax man" << std::endl; break;
	}

	std::cout << "Done by Dale Salter(Note the estimates only work if the input and output are the same)" << std::endl;

	return 0;
}<commit_msg>CHANGE FOR VCS<commit_after>#include <iostream>
#include <cstdlib>

const double FIRST_BRACKET_LENGTH  = 18200;
const double SECOND_BRACKET_LENGTH = 18799;
const double THIRD_BRACKET_LENGTH  = 42999;
const double FOURTH_BRACKET_LENGTH = 100000;

const double P_FIRST_BRACKET = 1;
const double P_SECOND_BRACKET = 0.81;
const double P_THIRD_BRACKET = 0.675;
const double P_FOURTH_BRACKET = 0.63;
const double P_LAST_BRACKET = 0.55;

double tax_money_in_year(double income){
	double money_to_tax = income;
	double taxed_money = 0;

	// Between $0 - $18201
	if(money_to_tax >= 0){
		//If under the first bracket, no tax is taken.
		if(money_to_tax < FIRST_BRACKET_LENGTH){
			return money_to_tax;
		}
		taxed_money += FIRST_BRACKET_LENGTH * P_FIRST_BRACKET;
		money_to_tax -= FIRST_BRACKET_LENGTH;
	}

	// Between $18,201 - $37,000
	if(money_to_tax >= 0){

		if(money_to_tax < SECOND_BRACKET_LENGTH){
			return taxed_money + (money_to_tax * P_SECOND_BRACKET);
		}

		taxed_money += SECOND_BRACKET_LENGTH * P_SECOND_BRACKET;
		money_to_tax -= SECOND_BRACKET_LENGTH;
	}

	// Between $37,001 - $80,000
	if(money_to_tax >= 0){

		if(money_to_tax < THIRD_BRACKET_LENGTH){
			return taxed_money + (money_to_tax * P_THIRD_BRACKET);
		}

		taxed_money += THIRD_BRACKET_LENGTH * P_THIRD_BRACKET;
		money_to_tax -= THIRD_BRACKET_LENGTH;
	}

	// Between $80,001 - $180,000
	if(money_to_tax >= 0){

		if(money_to_tax < FOURTH_BRACKET_LENGTH){
			return taxed_money + (money_to_tax * P_FOURTH_BRACKET);
		}

		taxed_money += FOURTH_BRACKET_LENGTH * P_FOURTH_BRACKET;
		money_to_tax -= FOURTH_BRACKET_LENGTH;
	}

	// Greater than $180,000
	if(money_to_tax >= 0){
		taxed_money += money_to_tax * P_LAST_BRACKET;
		money_to_tax = 0;
	}

	return taxed_money;
}

int main(int argc, char* argv[]){

	if(argc != 4){
		std::cerr << "Usage: <y,m,w>(input) <dollars earned> <y,m,w>(output)" << std::endl;
		return 1;
	}

	const double user_input_wage = atof(argv[2]);
	double taxed_money_years;

	//Convers it to yearly for storage
	switch(*argv[1]){
		case 'y': taxed_money_years = tax_money_in_year(user_input_wage); break;
		case 'm': taxed_money_years = tax_money_in_year(user_input_wage * 12); break;
		case 'w': taxed_money_years = tax_money_in_year(user_input_wage * 52); break;
	}

	//Simply divides it back out.
	switch(*argv[3]){
		case 'y': std::cout << "Yearly earnings after tax is $" << taxed_money_years / 1.0 << std::endl; break;
		case 'm': std::cout << "Monthly earnings after tax is $" << taxed_money_years / 12.0 << std::endl; break;
		case 'w': std::cout << "Weekly earnings after tax is $" << taxed_money_years / 52.0 << std::endl; break;
	}

	switch(*argv[3]){
		case 'y': std::cout << "You lose $" << (user_input_wage	) - (taxed_money_years / 1.0) <<  " per year to the tax man" << std::endl; break;
		case 'm': std::cout << "You lose $" << (user_input_wage ) - (taxed_money_years / 12.0) << " per month to the tax man" << std::endl; break;
		case 'w': std::cout << "You lose $" << (user_input_wage ) - (taxed_money_years / 52.0) << " per week to the tax man" << std::endl; break;
	}

	std::cout << "Done by Dale Salter(the input and output y/m/w have to be the same)" << std::endl;

	return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<commit_msg>--allow-empty_message<commit_after>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<|endoftext|>


<commit_before><commit_msg>planning: do not check traffic light color while creeping on right turn<commit_after><|endoftext|>


<commit_before>
#include <locale>
#include <vector>

#include <stdlib.h>

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif //

#include <lemon/fs/fs.hpp>
#include <lemon/strings.hpp>
#include <lemon/os/sysinfo.hpp>

namespace lemon { namespace os {
    typedef std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>, wchar_t> convert;

    host_t hostname()
    {

    #ifdef WIN32
		return host_t::Windows;
    #elif defined(__linux)
        #ifdef __android
            return host_t::Android;
        #else
            return host_t::Linux;
        #endif
    #elif defined(__sun)
        return host_t::Solaris;
    #elif defined(__hppa)
        return host_t::HPUX;
    #elif defined(_AIX)
        return host_t::AIX;
    #elif defined(__APPLE__)
    #if TARGET_OS_SIMULATOR == 1
        return host_t::iOS_Simulator;
    #elif TARGET_OS_IPHONE == 1
        return host_t::iOS;
    #elif TARGET_OS_MAC == 1
        return host_t::OSX;
    #else
        return host_t::OSX_Unknown;
    #endif
    #endif //WIN32
    }

	arch_t arch()
	{
#if defined(__alpha__) || defined(_M_ALPHA) || defined(__alpha)
		return arch_t::Alpha;
#elif defined(__amd64__) || defined(__amd64) || defined(_M_X64)
		return arch_t::AMD64;
#elif defined(__arm__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARMT) || defined(__arm)
		return arch_t::ARM;
#elif defined(__aarch64__) || defined(__arm64__)
		return arch_t::ARM64;
#elif defined(__hppa__) || defined(__HPPA__)
		return arch_t::HP_PA;
#elif defined(__i386__) || defined(__i386) || defined(__i386) || defined(_M_IX86) || defined(_X86_)
		return arch_t::X86;
#elif defined(__mips__) || defined(__mips)
		return arch_t::MIPS;
#elif defined(__powerpc) || defined(_M_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_PPC)
		return arch_t::PowerPC;
#elif defined(__sparc__)
		return arch_t::SPARC;
#endif
	}

    #ifdef WIN32
    std::tuple<std::string, bool> getenv(const std::string &name)
    {
        auto namew = convert().from_bytes(name);

        DWORD length = ::GetEnvironmentVariableW(namew.c_str(), NULL, 0);

        if(length == 0)
        {
            return std::make_tuple(std::string(), false);
        }

        std::vector<wchar_t> buff(length);

        ::GetEnvironmentVariableW(namew.c_str(), &buff[0], (DWORD)buff.size());

        return std::make_tuple(convert().to_bytes(&buff[0]), true);
    }

	void setenv(const std::string &name, const std::string &val,std::error_code &ec)
	{
		auto namew = convert().from_bytes(name);

		auto valnew = convert().from_bytes(val);

		if (!::SetEnvironmentVariableW(namew.c_str(), valnew.c_str()))
		{
			ec = std::error_code(GetLastError(),std::system_category());
		}
	}

    #else

    std::tuple<std::string,bool> getenv(const std::string &name)
    {
        const char *val = ::getenv(name.c_str());

        if(val)
        {
            return std::make_tuple(std::string(val),true);
        }

        return std::make_tuple(std::string(), false);
    }

	void setenv(const std::string &name, const std::string &val, std::error_code &ec)
	{
		if (-1 == setenv(name.c_str(), val.c_str(), 1))
		{
			ec = std::make_error_code(errno, std::system_category());
		}
	}

    #endif //WIN32

    std::string execute_suffix()
    {
    #ifdef WIN32
        return ".exe";
    #else
        return "";
    #endif
    }

#ifndef WIN32
    std::string tmpdir(std::error_code & )
    {
        auto val = getenv("TMPDIR");

        if(std::get<1>(val))
        {
            return std::get<0>(val);
        }
#ifdef __android
        return "/data/local/tmp";
#endif

        return "/tmp";
    }
#else

	std::string tmpdir(std::error_code & err)
	{
		wchar_t buff[MAX_PATH + 1];

		auto length = ::GetTempPathW(MAX_PATH, buff);

		if(length == 0)
		{
			err = std::error_code(GetLastError(),std::system_category());

			return "";
		}

		return convert().to_bytes(std::wstring(buff, buff + length));
	}
#endif

    std::tuple<std::string, bool> lookup(const std::string & cmd)
    {

		if(fs::exists(cmd))
		{
			return std::make_tuple(fs::absolute(cmd).string(), true);
		}

        auto path = os::getenv("PATH");

        if(!std::get<1>(path))
        {
            return std::make_tuple(std::string(),false);
        }

    #ifdef WIN32
        const std::string delimiter = ";";
        const std::string extend = ".exe";
    #else
        const std::string delimiter = ":";
        const std::string extend = "";
    #endif //WIN32

        auto paths = strings::split(std::get<0>(path), delimiter);

    #ifdef WIN32
        DWORD length = ::GetSystemDirectoryW(0, 0);

            std::vector<wchar_t> buff(length);

            ::GetSystemDirectoryW(&buff[0], (UINT)buff.size());

            paths.push_back(convert().to_bytes(&buff[0]));
    #else
    #endif

        for(auto p : paths)
        {
            auto fullPath = fs::filepath(p) / (cmd + extend);

            if(fs::exists(fullPath))
            {
                return std::make_tuple(fullPath.string(), true);
            }
        }

        return std::make_tuple(std::string(), false);
    }
}}<commit_msg>fix some bugs<commit_after>
#include <locale>
#include <vector>

#include <stdlib.h>

#ifdef __APPLE__
#include <TargetConditionals.h>
#endif //

#include <lemon/fs/fs.hpp>
#include <lemon/strings.hpp>
#include <lemon/os/sysinfo.hpp>

namespace lemon { namespace os {
    typedef std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>, wchar_t> convert;

    host_t hostname()
    {

    #ifdef WIN32
		return host_t::Windows;
    #elif defined(__linux)
        #ifdef __android
            return host_t::Android;
        #else
            return host_t::Linux;
        #endif
    #elif defined(__sun)
        return host_t::Solaris;
    #elif defined(__hppa)
        return host_t::HPUX;
    #elif defined(_AIX)
        return host_t::AIX;
    #elif defined(__APPLE__)
    #if TARGET_OS_SIMULATOR == 1
        return host_t::iOS_Simulator;
    #elif TARGET_OS_IPHONE == 1
        return host_t::iOS;
    #elif TARGET_OS_MAC == 1
        return host_t::OSX;
    #else
        return host_t::OSX_Unknown;
    #endif
    #endif //WIN32
    }

	arch_t arch()
	{
#if defined(__alpha__) || defined(_M_ALPHA) || defined(__alpha)
		return arch_t::Alpha;
#elif defined(__amd64__) || defined(__amd64) || defined(_M_X64)
		return arch_t::AMD64;
#elif defined(__arm__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARMT) || defined(__arm)
		return arch_t::ARM;
#elif defined(__aarch64__) || defined(__arm64__)
		return arch_t::ARM64;
#elif defined(__hppa__) || defined(__HPPA__)
		return arch_t::HP_PA;
#elif defined(__i386__) || defined(__i386) || defined(__i386) || defined(_M_IX86) || defined(_X86_)
		return arch_t::X86;
#elif defined(__mips__) || defined(__mips)
		return arch_t::MIPS;
#elif defined(__powerpc) || defined(_M_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_PPC)
		return arch_t::PowerPC;
#elif defined(__sparc__)
		return arch_t::SPARC;
#endif
	}

    #ifdef WIN32
    std::tuple<std::string, bool> getenv(const std::string &name)
    {
        auto namew = convert().from_bytes(name);

        DWORD length = ::GetEnvironmentVariableW(namew.c_str(), NULL, 0);

        if(length == 0)
        {
            return std::make_tuple(std::string(), false);
        }

        std::vector<wchar_t> buff(length);

        ::GetEnvironmentVariableW(namew.c_str(), &buff[0], (DWORD)buff.size());

        return std::make_tuple(convert().to_bytes(&buff[0]), true);
    }

	void setenv(const std::string &name, const std::string &val,std::error_code &ec)
	{
		auto namew = convert().from_bytes(name);

		auto valnew = convert().from_bytes(val);

		if (!::SetEnvironmentVariableW(namew.c_str(), valnew.c_str()))
		{
			ec = std::error_code(GetLastError(),std::system_category());
		}
	}

    #else

    std::tuple<std::string,bool> getenv(const std::string &name)
    {
        const char *val = ::getenv(name.c_str());

        if(val)
        {
            return std::make_tuple(std::string(val),true);
        }

        return std::make_tuple(std::string(), false);
    }

	void setenv(const std::string &name, const std::string &val, std::error_code &ec)
	{
		if (-1 == setenv(name.c_str(), val.c_str(), 1))
		{
			ec = std::make_error_code(errno, std::system_category());
		}
	}

    #endif //WIN32

    std::string execute_suffix()
    {
    #ifdef WIN32
        return ".exe";
    #else
        return "";
    #endif
    }

#ifndef WIN32
    std::string tmpdir(std::error_code & )
    {
        auto val = getenv("TMPDIR");

        if(std::get<1>(val))
        {
            return std::get<0>(val);
        }
#ifdef __android
        return "/data/local/tmp";
#endif

        return "/tmp";
    }
#else

	std::string tmpdir(std::error_code & err)
	{
		wchar_t buff[MAX_PATH + 1];

		auto length = ::GetTempPathW(MAX_PATH, buff);

		if(length == 0)
		{
			err = std::error_code(GetLastError(),std::system_category());

			return "";
		}

		return convert().to_bytes(std::wstring(buff, buff + length));
	}
#endif

    std::tuple<std::string, bool> lookup(const std::string & cmd)
    {

		if(fs::exists(cmd))
		{
			return std::make_tuple(fs::absolute(cmd).string(), true);
		}

        auto path = os::getenv("PATH");

        if(!std::get<1>(path))
        {
            return std::make_tuple(std::string(),false);
        }

    #ifdef WIN32
        const std::string delimiter = ";";
		const std::vector<std::string> extends = { ".exe",".cmd",".bat",".com" };
    #else
        const std::string delimiter = ":";
		const std::vector<std::string> extends = { "" };
    #endif //WIN32

        auto paths = strings::split(std::get<0>(path), delimiter);

    #ifdef WIN32
        DWORD length = ::GetSystemDirectoryW(0, 0);

            std::vector<wchar_t> buff(length);

            ::GetSystemDirectoryW(&buff[0], (UINT)buff.size());

            paths.push_back(convert().to_bytes(&buff[0]));
    #else
    #endif

        for(auto p : paths)
        {
			for (auto extend : extends)
			{
				auto fullPath = fs::filepath(p) / (cmd + extend);

				if (fs::exists(fullPath))
				{
					return std::make_tuple(fullPath.string(), true);
				}
			}

        }

        return std::make_tuple(std::string(), false);
    }
}}<|endoftext|>