<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_INTERNAL_HH
#define DUNE_GDT_PRODUCTS_BASE_INTERNAL_HH

#include <type_traits>

#include <dune/grid/common/gridview.hh>

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/assembler/local/codim0.hh>
#include <dune/gdt/localoperator/interface.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {
namespace Products {

// forward
template< class LocalOperatorProvider, class RangeImp, class SourceImp >
class LocalizableBase;

// forward
template< class LocalOperatorProvider, class MatrixImp, class RangeSpaceImp, class SourceSpaceImp >
class AssemblableBase;

// forward
template< class LocalOperatorProvider >
class GenericBase;

/**
 * \brief Base class for all local operator providers.
 *
 *        You have to derive a custom class LocalOperatorProvider from this class in order to use \sa LocalizableBase!
 *        All classes derived from this class have to provide the following types:
 *        - `GridViewType`
 *        - `FieldType`
 *        Depending on the type of local operator you want to use for the product (aka provide to LocalizableBase) you
 *        have to additionally implement:
 *        - if the local operator is derived from LocalOperator::Codim0Interface you have to provide the public type
 *          - `VolumeOperatorType`
 *          and you have to provide the public members
 *          - `static const bool has_volume_operator = true;`
 *          - `const VolumeOperatorType volume_operator_;
 *          If you want to restrict the entities your local operator will be applied on you have to additionally provide
 *          a method:
 *          - `DSG::ApplyOn::WhichEntity< GridViewType >* entities() const;`
 *          See \sa Products::internal::WeightedL2Base in weightedl2-internal.hh for an example of a
 *          LocalOperatorProvider based on a codim 0 local operator.
 */
template< class GridViewType >
class LocalOperatorProviderBase
{
public:
  static const bool has_volume_operator   = false;

  DSG::ApplyOn::AllEntities< GridViewType >* entities() const
  {
    return new DSG::ApplyOn::AllEntities< GridViewType >();
  }
}; // class LocalOperatorProviderBase

namespace internal {

/**
 * \brief Helper class for \sa Products::LocalizableBase
 *
 *        This class manages the creation of the appropriate functors needed to handle the local operators provided
 *        by any class derived from \sa LocalOperatorProviderBase.
 * \note  This class is usually not of interest to the average user.
 */
template< class LocalOperatorProvider, class RangeType, class SourceType >
class LocalizableBaseHelper
{
  static_assert(std::is_base_of< LocalOperatorProviderBase< typename LocalOperatorProvider::GridViewType >,
                                 LocalOperatorProvider >::value,
                "LocalOperatorProvider has to be derived from LocalOperatorProviderBase!");

  typedef typename LocalOperatorProvider::GridViewType GridViewType;
  typedef typename LocalOperatorProvider::FieldType    FieldType;
  typedef Stuff::Grid::Walker< GridViewType > WalkerType;

  template< class LO, bool anthing = false >
  struct Volume
  {
    Volume(const GridViewType&, const LocalOperatorProvider&, const RangeType&, const SourceType&) {}

    void add(WalkerType&) {}

    FieldType result() const
    {
      return 0.0;
    }
  }; // struct Volume< ..., false >

  template< class LO >
  struct Volume< LO, true >
  {
    // if you get an error here you have defined has_volume_operator to true but either do not provide
    // VolumeOperatorType or your VolumeOperatorType is not derived from LocalOperator::Codim0Interface
    typedef typename LocalOperatorProvider::VolumeOperatorType LocalOperatorType;
    typedef LocalAssembler::Codim0OperatorAccumulateFunctor
        < GridViewType, LocalOperatorType, RangeType, SourceType, FieldType > FunctorType;

    Volume(const GridViewType& grid_view,
           const LocalOperatorProvider& local_operators,
           const RangeType& range,
           const SourceType& source)
      : local_operators_(local_operators)
      , functor_(grid_view, local_operators_.volume_operator_, range, source) // <- if you get an error here you have
    {}                                                                        //    defined has_volume_operator to true
                                                                              //    but do not provide volume_operator_

    void add(WalkerType& grid_walker)
    {
      grid_walker.add(functor_, local_operators_.entities()); // <- if you get an error here you have defined
    }                                                         //    has_volume_operator to true but implemented the
                                                              //    wrong entities()

    FieldType result() const
    {
      return functor_.result();
    }

    const LocalOperatorProvider& local_operators_;
    FunctorType functor_;
  }; // struct Volume< ..., true >

public:
  LocalizableBaseHelper(WalkerType& walker,
                        const LocalOperatorProvider& local_operators,
                        const RangeType& range,
                        const SourceType& source)
    : volume_helper_(walker.grid_view(), local_operators, range, source)
  {
    volume_helper_.add(walker);
  }

  FieldType result() const
  {
    return volume_helper_.result();
  }

private:
  Volume< LocalOperatorProvider, LocalOperatorProvider::has_volume_operator > volume_helper_;
}; // class LocalizableBaseHelper

/**
 * \note not of interest to the average user
 */
template< class LocalOperatorProvider, class RangeImp, class SourceImp >
class LocalizableBaseTraits
{
public:
  typedef LocalizableBase< LocalOperatorProvider, RangeImp, SourceImp > derived_type;
  typedef typename LocalOperatorProvider::GridViewType                  GridViewType;
  typedef typename LocalOperatorProvider::FieldType                     FieldType;
  typedef RangeImp  RangeType;
  typedef SourceImp SourceType;
private:
  static_assert(std::is_base_of< Dune::GridView< typename GridViewType::Traits >, GridViewType >::value,
                "GridViewType has to be derived from GridView!");
  static_assert(std::is_base_of< Stuff::Tags::LocalizableFunction, RangeType >::value,
                "RangeType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of< Stuff::Tags::LocalizableFunction, SourceType >::value,
                "SourceType has to be derived from Stuff::LocalizableFunctionInterface!");
}; // class LocalizableBaseTraits

/**
 * \note not of interest to the average user
 */
template< class LocalOperatorProvider, class MatrixImp, class RangeSpaceImp, class SourceSpaceImp >
class AssemblableBaseTraits
{
public:
  typedef AssemblableBase< LocalOperatorProvider, MatrixImp, RangeSpaceImp, SourceSpaceImp > derived_type;
  typedef typename LocalOperatorProvider::GridViewType                                       GridViewType;
  typedef RangeSpaceImp  RangeSpaceType;
  typedef SourceSpaceImp SourceSpaceType;
  typedef MatrixImp      MatrixType;
private:
  static_assert(std::is_base_of< Dune::GridView< typename GridViewType::Traits >, GridViewType >::value,
                "GridViewType has to be derived from GridView!");
  static_assert(std::is_base_of< SpaceInterface< typename RangeSpaceType::Traits >, RangeSpaceType >::value,
                "RangeSpaceType has to be derived from SpaceInterface!");
  static_assert(std::is_base_of< SpaceInterface< typename SourceSpaceType::Traits >, SourceSpaceType >::value,
                "SourceSpaceType has to be derived from SpaceInterface!");
  static_assert(std::is_base_of< Stuff::LA::MatrixInterface< typename MatrixType::Traits >, MatrixType >::value,
                "MatrixType has to be derived from Stuff::LA::MatrixInterface!");
}; // class AssemblableBaseTraits

/**
 * \note not of interest to the average user
 */
template< class LocalOperatorProvider >
class GenericBaseTraits
{
public:
  typedef GenericBase< LocalOperatorProvider >         derived_type;
  typedef typename LocalOperatorProvider::FieldType    FieldType;
  typedef typename LocalOperatorProvider::GridViewType GridViewType;
private:
  static_assert(std::is_base_of< Dune::GridView< typename GridViewType::Traits >, GridViewType >::value,
                "GridViewType has to be derived from GridView!");
}; // class GenericBaseTraits

} // namespace internal
} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_INTERNAL_HH
<commit_msg>[products.base] added codim1 boundary operators to LocalizableBaseHelper<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_INTERNAL_HH
#define DUNE_GDT_PRODUCTS_BASE_INTERNAL_HH

#include <type_traits>

#include <dune/grid/common/gridview.hh>

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/assembler/local/codim0.hh>
#include <dune/gdt/assembler/local/codim1.hh>
#include <dune/gdt/localoperator/interface.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {
namespace Products {

// forward
template< class LocalOperatorProvider, class RangeImp, class SourceImp >
class LocalizableBase;

// forward
template< class LocalOperatorProvider, class MatrixImp, class RangeSpaceImp, class SourceSpaceImp >
class AssemblableBase;

// forward
template< class LocalOperatorProvider >
class GenericBase;

/**
 * \brief Base class for all local operator providers.
 *
 *        You have to derive a custom class LocalOperatorProvider from this class in order to use \sa LocalizableBase!
 *        All classes derived from this class have to provide the following types:
 *        - `GridViewType`
 *        - `FieldType`
 *        Depending on the type of local operator you want to use for the product (aka provide to LocalizableBase) you
 *        have to additionally implement (you can have zero or one local operator per type each):
 *        - if a local operator is derived from LocalOperator::Codim0Interface you have to provide the public type
 *          - `VolumeOperatorType`
 *          and you have to provide the public members
 *          - `static const bool has_volume_operator = true;`
 *          - `const VolumeOperatorType volume_operator_;
 *          If you want to restrict the entities the local operator will be applied on you have to additionally provide
 *          a method:
 *          - `DSG::ApplyOn::WhichEntity< GridViewType >* entities() const`
 *          See \sa Products::internal::WeightedL2Base in weightedl2-internal.hh for an example of a
 *          LocalOperatorProvider based on a local codim 0 operator.
 *        - if a local operator is derived from LocalOperator::Codim1BoundaryInterface you have to provide the public
 *          type
 *          - `BoundaryOperatorType`
 *          and you have to provide the public members
 *          - `static const bool has_boundary_operator = true;`
 *          - `const BoundaryOperatorType boundary_operator_;`
 *          If you want to restrict the intersections your the local operator will be applied on you have to
 *          additionally provide a method
 *          - `DSG::ApplyOn::WhichIntersections< GridViewType >* boundary_intersections() const`
 *          See \sa Products::internal::BoundaryL2Base in boundaryl2-internal.hh for an example of a
 *          LocalOperatorProvider based on a local codim 1 boundary operator.
 */
template< class GridViewType >
class LocalOperatorProviderBase
{
public:
  static const bool has_volume_operator   = false;
  static const bool has_boundary_operator = false;

  DSG::ApplyOn::AllEntities< GridViewType >* entities() const
  {
    return new DSG::ApplyOn::AllEntities< GridViewType >();
  }

  DSG::ApplyOn::BoundaryIntersections< GridViewType >* boundary_intersections() const
  {
    return new DSG::ApplyOn::BoundaryIntersections< GridViewType >();
  }
}; // class LocalOperatorProviderBase

namespace internal {

/**
 * \brief Helper class for \sa Products::LocalizableBase
 *
 *        This class manages the creation of the appropriate functors needed to handle the local operators provided
 *        by any class derived from \sa LocalOperatorProviderBase.
 * \note  This class is usually not of interest to the average user.
 */
template< class LocalOperatorProvider, class RangeType, class SourceType >
class LocalizableBaseHelper
{
  static_assert(std::is_base_of< LocalOperatorProviderBase< typename LocalOperatorProvider::GridViewType >,
                                 LocalOperatorProvider >::value,
                "LocalOperatorProvider has to be derived from LocalOperatorProviderBase!");

  typedef typename LocalOperatorProvider::GridViewType GridViewType;
  typedef typename LocalOperatorProvider::FieldType    FieldType;
  typedef Stuff::Grid::Walker< GridViewType > WalkerType;

  template< class LO, bool anthing = false >
  struct Volume
  {
    Volume(const GridViewType&, const LocalOperatorProvider&, const RangeType&, const SourceType&) {}

    void add(WalkerType&) {}

    FieldType result() const
    {
      return 0.0;
    }
  }; // struct Volume< ..., false >

  template< class LO >
  struct Volume< LO, true >
  {
    // if you get an error here you have defined has_volume_operator to true but either do not provide
    // VolumeOperatorType or your VolumeOperatorType is not derived from LocalOperator::Codim0Interface
    typedef typename LocalOperatorProvider::VolumeOperatorType LocalOperatorType;
    typedef LocalAssembler::Codim0OperatorAccumulateFunctor
        < GridViewType, LocalOperatorType, RangeType, SourceType, FieldType > FunctorType;

    Volume(const GridViewType& grid_view,
           const LocalOperatorProvider& local_operators,
           const RangeType& range,
           const SourceType& source)
      : local_operators_(local_operators)
      , functor_(grid_view, local_operators_.volume_operator_, range, source) // <- if you get an error here you have
    {}                                                                        //    defined has_volume_operator to true
                                                                              //    but do not provide volume_operator_

    void add(WalkerType& grid_walker)
    {
      grid_walker.add(functor_, local_operators_.entities()); // <- if you get an error here you have defined
    }                                                         //    has_volume_operator to true but implemented the
                                                              //    wrong entities()

    FieldType result() const
    {
      return functor_.result();
    }

    const LocalOperatorProvider& local_operators_;
    FunctorType functor_;
  }; // struct Volume< ..., true >

  template< class LO, bool anthing = false >
  struct Boundary
  {
    Boundary(const GridViewType&, const LocalOperatorProvider&, const RangeType&, const SourceType&) {}

    void add(WalkerType&) {}

    FieldType result() const
    {
      return 0.0;
    }
  }; // struct Boundary< ..., false >

  template< class LO >
  struct Boundary< LO, true >
  {
    // if you get an error here you have defined has_boundary_operator to true but either do not provide
    // BoundaryOperatorType or your BoundaryOperatorType is not derived from LocalOperator::Codim1BoundaryInterface
    typedef typename LocalOperatorProvider::BoundaryOperatorType LocalOperatorType;
    typedef LocalAssembler::Codim1BoundaryOperatorAccumulateFunctor
        < GridViewType, LocalOperatorType, RangeType, SourceType, FieldType > FunctorType;

    Boundary(const GridViewType& grid_view,
             const LocalOperatorProvider& local_operators,
             const RangeType& range,
             const SourceType& source)
      : local_operators_(local_operators)
      , functor_(grid_view, local_operators_.boundary_operator_, range, source) // <- if you get an error here you have
    {}                                                                          //    defined has_boundary_operator to
                                                                                //    true but do not provide
                                                                                //    boundary_operator_

    void add(WalkerType& grid_walker)
    {
      grid_walker.add(functor_, local_operators_.boundary_intersections()); // <- if you get an error here you have
    }                                                                       //    defined has_boundary_operator to true
                                                                            //    but implemented the wrong
                                                                            //    boundary_intersections()

    FieldType result() const
    {
      return functor_.result();
    }

    const LocalOperatorProvider& local_operators_;
    FunctorType functor_;
  }; // struct Boundary< ..., true >

public:
  LocalizableBaseHelper(WalkerType& walker,
                        const LocalOperatorProvider& local_operators,
                        const RangeType& range,
                        const SourceType& source)
    : volume_helper_(  walker.grid_view(), local_operators, range, source)
    , boundary_helper_(walker.grid_view(), local_operators, range, source)
  {
    volume_helper_.add(walker);
    boundary_helper_.add(walker);
  }

  FieldType result() const
  {
    return volume_helper_.result() + boundary_helper_.result();
  }

private:
  Volume<   LocalOperatorProvider, LocalOperatorProvider::has_volume_operator >   volume_helper_;
  Boundary< LocalOperatorProvider, LocalOperatorProvider::has_boundary_operator > boundary_helper_;
}; // class LocalizableBaseHelper

/**
 * \note not of interest to the average user
 */
template< class LocalOperatorProvider, class RangeImp, class SourceImp >
class LocalizableBaseTraits
{
public:
  typedef LocalizableBase< LocalOperatorProvider, RangeImp, SourceImp > derived_type;
  typedef typename LocalOperatorProvider::GridViewType                  GridViewType;
  typedef typename LocalOperatorProvider::FieldType                     FieldType;
  typedef RangeImp  RangeType;
  typedef SourceImp SourceType;
private:
  static_assert(std::is_base_of< Dune::GridView< typename GridViewType::Traits >, GridViewType >::value,
                "GridViewType has to be derived from GridView!");
  static_assert(std::is_base_of< Stuff::Tags::LocalizableFunction, RangeType >::value,
                "RangeType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of< Stuff::Tags::LocalizableFunction, SourceType >::value,
                "SourceType has to be derived from Stuff::LocalizableFunctionInterface!");
}; // class LocalizableBaseTraits

/**
 * \note not of interest to the average user
 */
template< class LocalOperatorProvider, class MatrixImp, class RangeSpaceImp, class SourceSpaceImp >
class AssemblableBaseTraits
{
public:
  typedef AssemblableBase< LocalOperatorProvider, MatrixImp, RangeSpaceImp, SourceSpaceImp > derived_type;
  typedef typename LocalOperatorProvider::GridViewType                                       GridViewType;
  typedef RangeSpaceImp  RangeSpaceType;
  typedef SourceSpaceImp SourceSpaceType;
  typedef MatrixImp      MatrixType;
private:
  static_assert(std::is_base_of< Dune::GridView< typename GridViewType::Traits >, GridViewType >::value,
                "GridViewType has to be derived from GridView!");
  static_assert(std::is_base_of< SpaceInterface< typename RangeSpaceType::Traits >, RangeSpaceType >::value,
                "RangeSpaceType has to be derived from SpaceInterface!");
  static_assert(std::is_base_of< SpaceInterface< typename SourceSpaceType::Traits >, SourceSpaceType >::value,
                "SourceSpaceType has to be derived from SpaceInterface!");
  static_assert(std::is_base_of< Stuff::LA::MatrixInterface< typename MatrixType::Traits >, MatrixType >::value,
                "MatrixType has to be derived from Stuff::LA::MatrixInterface!");
}; // class AssemblableBaseTraits

/**
 * \note not of interest to the average user
 */
template< class LocalOperatorProvider >
class GenericBaseTraits
{
public:
  typedef GenericBase< LocalOperatorProvider >         derived_type;
  typedef typename LocalOperatorProvider::FieldType    FieldType;
  typedef typename LocalOperatorProvider::GridViewType GridViewType;
private:
  static_assert(std::is_base_of< Dune::GridView< typename GridViewType::Traits >, GridViewType >::value,
                "GridViewType has to be derived from GridView!");
}; // class GenericBaseTraits

} // namespace internal
} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_INTERNAL_HH
<|endoftext|>


<commit_before>#include <config.h>
// dune-multiscale
// Copyright Holders: Patrick Henning, Rene Milk
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include <assert.h>
#include <boost/format.hpp>
#include <dune/grid/io/file/dgfparser/gridptr.hh>
#include <dune/multiscale/common/error_calc.hh>

#include <dune/multiscale/common/traits.hh>
#include <dune/multiscale/msfem/fem_solver.hh>
#include <dune/multiscale/fem/print_info.hh>
#include <dune/multiscale/msfem/localproblems/subgrid-list.hh>
#include <dune/multiscale/msfem/msfem_solver.hh>
#include <dune/multiscale/msfem/msfem_traits.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/multiscale/tools/discretefunctionwriter.hh>
#include <dune/multiscale/tools/misc/outputparameter.hh>

#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/grid/output/entity_visualization.hh>
#include <dune/stuff/grid/information.hh>
#include <dune/stuff/grid/structuredgridfactory.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/gdt/discretefunction/default.hh>

#include <cmath>
#include <iterator>
#include <memory>
#include <sstream>

#include "algorithm.hh"
#include <dune/multiscale/problems/base.hh>
#include <dune/multiscale/common/grid_creation.hh>

namespace Dune {
namespace Multiscale {
namespace MsFEM {

//! \TODO docme
void solution_output(const CommonTraits::DiscreteFunctionType& msfem_solution,
                     const CommonTraits::DiscreteFunctionType& coarse_part_msfem_solution,
                     const CommonTraits::DiscreteFunctionType& fine_part_msfem_solution) {
  using namespace Dune;

  Dune::Multiscale::OutputParameters outputparam;
  outputparam.set_prefix("msfem_solution_");
  msfem_solution.visualize(outputparam.fullpath(msfem_solution.name()));

  outputparam.set_prefix("coarse_part_msfem_solution_");
  coarse_part_msfem_solution.visualize(outputparam.fullpath(coarse_part_msfem_solution.name()));

  outputparam.set_prefix("fine_part_msfem_solution_");
  fine_part_msfem_solution.visualize(outputparam.fullpath(fine_part_msfem_solution.name()));

  DSG::ElementVisualization::all(fine_part_msfem_solution.space().grid_view()->grid(), outputparam.path());
}

//! \TODO docme
void data_output(const CommonTraits::GridViewType &gridPart,
                 const CommonTraits::DiscreteFunctionSpaceType& /*coarseSpace*/) {
  using namespace Dune;
  Dune::Multiscale::OutputParameters outputparam;

  if (Problem::getModelData()->hasExactSolution()) {
    const auto& u = Dune::Multiscale::Problem::getExactSolution();
    outputparam.set_prefix("exact_solution");
    u->visualize(gridPart, outputparam.fullpath(u->name()));
  }

  //! \todo re-enable
//  CommonTraits::DiscreteFunctionType coarse_grid_visualization("Visualization of the coarse grid",
//                                                               coarseSpace);
//  coarse_grid_visualization.clear();
//  OutputTraits::IOTupleType coarse_grid_series(&coarse_grid_visualization);
//  const std::string coarse_grid_name("coarse_grid_visualization_");
//  outputparam.set_prefix(coarse_grid_name);
//  OutputTraits::DataOutputType(coarseSpace.grid_view().grid(), coarse_grid_series, outputparam)
//      .writeData(1.0 /*dummy*/, coarse_grid_name);
}

//! algorithm
std::map<std::string, double> algorithm() {
  using namespace Dune;

  auto grids = make_grids();
  CommonTraits::GridProviderType coarse_grid_provider(grids.first);
  CommonTraits::GridProviderType fine_grid_provider(grids.second);
  const CommonTraits::GdtSpaceType coarseSpace =
      CommonTraits::SpaceProviderType::create(coarse_grid_provider, CommonTraits::st_gdt_grid_level);
  const CommonTraits::GdtSpaceType fineSpace =
      CommonTraits::SpaceProviderType::create(fine_grid_provider, CommonTraits::st_gdt_grid_level);

  const auto& diffusion_op = *Dune::Multiscale::Problem::getDiffusion();
  const auto& f = *Dune::Multiscale::Problem::getSource();

  CommonTraits::DiscreteFunctionType msfem_solution(fineSpace, "MsFEM_Solution");
  CommonTraits::DiscreteFunctionType coarse_part_msfem_solution(fineSpace, "Coarse_Part_MsFEM_Solution");
  CommonTraits::DiscreteFunctionType fine_part_msfem_solution(fineSpace, "Fine_Part_MsFEM_Solution" );

  Elliptic_MsFEM_Solver().apply(coarseSpace, diffusion_op, coarse_part_msfem_solution,
                                fine_part_msfem_solution, msfem_solution);

  if (DSC_CONFIG_GET("global.vtk_output", false)) {
    DSC_LOG_INFO_0 << "Solution output for MsFEM Solution." << std::endl;
    data_output(*fineSpace.grid_view(), coarseSpace);
    solution_output(msfem_solution, coarse_part_msfem_solution, fine_part_msfem_solution);
  }

  std::unique_ptr<CommonTraits::DiscreteFunctionType> fem_solution(nullptr);

  if (DSC_CONFIG_GET("msfem.fem_comparison", false)) {
    fem_solution = DSC::make_unique<CommonTraits::DiscreteFunctionType>(fineSpace, "fem_solution");
    const Dune::Multiscale::Elliptic_FEM_Solver fem_solver(fineSpace);
    fem_solver.apply(diffusion_op, f, *fem_solution);
    if (DSC_CONFIG_GET("global.vtk_output", false)) {
      Dune::Multiscale::FEM::write_discrete_function(*fem_solution, "fem_solution");
    }
  }

  return ErrorCalculator(&msfem_solution, fem_solution.get()).print(DSC_LOG_INFO_0);

} // function algorithm

} // namespace MsFEM {
} // namespace Multiscale {
} // namespace Dune {
<commit_msg>re-enables coarse grid vis<commit_after>#include <config.h>
// dune-multiscale
// Copyright Holders: Patrick Henning, Rene Milk
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include <assert.h>
#include <boost/format.hpp>
#include <dune/grid/io/file/dgfparser/gridptr.hh>
#include <dune/multiscale/common/error_calc.hh>

#include <dune/multiscale/common/traits.hh>
#include <dune/multiscale/msfem/fem_solver.hh>
#include <dune/multiscale/fem/print_info.hh>
#include <dune/multiscale/msfem/localproblems/subgrid-list.hh>
#include <dune/multiscale/msfem/msfem_solver.hh>
#include <dune/multiscale/msfem/msfem_traits.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/multiscale/tools/discretefunctionwriter.hh>
#include <dune/multiscale/tools/misc/outputparameter.hh>

#include <dune/stuff/common/logging.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/stuff/grid/output/entity_visualization.hh>
#include <dune/stuff/grid/information.hh>
#include <dune/stuff/grid/structuredgridfactory.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/gdt/discretefunction/default.hh>

#include <cmath>
#include <iterator>
#include <memory>
#include <sstream>

#include "algorithm.hh"
#include <dune/multiscale/problems/base.hh>
#include <dune/multiscale/common/grid_creation.hh>

namespace Dune {
namespace Multiscale {
namespace MsFEM {

//! \TODO docme
void solution_output(const CommonTraits::DiscreteFunctionType& msfem_solution,
                     const CommonTraits::DiscreteFunctionType& coarse_part_msfem_solution,
                     const CommonTraits::DiscreteFunctionType& fine_part_msfem_solution) {
  using namespace Dune;

  Dune::Multiscale::OutputParameters outputparam;
  outputparam.set_prefix("msfem_solution_");
  msfem_solution.visualize(outputparam.fullpath(msfem_solution.name()));

  outputparam.set_prefix("coarse_part_msfem_solution_");
  coarse_part_msfem_solution.visualize(outputparam.fullpath(coarse_part_msfem_solution.name()));

  outputparam.set_prefix("fine_part_msfem_solution_");
  fine_part_msfem_solution.visualize(outputparam.fullpath(fine_part_msfem_solution.name()));

  DSG::ElementVisualization::all(fine_part_msfem_solution.space().grid_view()->grid(), outputparam.path());
}

//! \TODO docme
void data_output(const CommonTraits::GridViewType &gridPart,
                 const CommonTraits::DiscreteFunctionSpaceType& coarseSpace) {
  using namespace Dune;
  Dune::Multiscale::OutputParameters outputparam;

  if (Problem::getModelData()->hasExactSolution()) {
    const auto& u = Dune::Multiscale::Problem::getExactSolution();
    outputparam.set_prefix("exact_solution");
    u->visualize(gridPart, outputparam.fullpath(u->name()));
  }

  CommonTraits::DiscreteFunctionType coarse_grid_visualization(coarseSpace, "Visualization_of_the_coarse_grid");
  coarse_grid_visualization.visualize(outputparam.fullpath(coarse_grid_visualization.name()));
}

//! algorithm
std::map<std::string, double> algorithm() {
  using namespace Dune;

  auto grids = make_grids();
  CommonTraits::GridProviderType coarse_grid_provider(grids.first);
  CommonTraits::GridProviderType fine_grid_provider(grids.second);
  const CommonTraits::GdtSpaceType coarseSpace =
      CommonTraits::SpaceProviderType::create(coarse_grid_provider, CommonTraits::st_gdt_grid_level);
  const CommonTraits::GdtSpaceType fineSpace =
      CommonTraits::SpaceProviderType::create(fine_grid_provider, CommonTraits::st_gdt_grid_level);

  const auto& diffusion_op = *Dune::Multiscale::Problem::getDiffusion();
  const auto& f = *Dune::Multiscale::Problem::getSource();

  CommonTraits::DiscreteFunctionType msfem_solution(fineSpace, "MsFEM_Solution");
  CommonTraits::DiscreteFunctionType coarse_part_msfem_solution(fineSpace, "Coarse_Part_MsFEM_Solution");
  CommonTraits::DiscreteFunctionType fine_part_msfem_solution(fineSpace, "Fine_Part_MsFEM_Solution" );

  Elliptic_MsFEM_Solver().apply(coarseSpace, diffusion_op, coarse_part_msfem_solution,
                                fine_part_msfem_solution, msfem_solution);

  if (DSC_CONFIG_GET("global.vtk_output", false)) {
    DSC_LOG_INFO_0 << "Solution output for MsFEM Solution." << std::endl;
    data_output(*fineSpace.grid_view(), coarseSpace);
    solution_output(msfem_solution, coarse_part_msfem_solution, fine_part_msfem_solution);
  }

  std::unique_ptr<CommonTraits::DiscreteFunctionType> fem_solution(nullptr);

  if (DSC_CONFIG_GET("msfem.fem_comparison", false)) {
    fem_solution = DSC::make_unique<CommonTraits::DiscreteFunctionType>(fineSpace, "fem_solution");
    const Dune::Multiscale::Elliptic_FEM_Solver fem_solver(fineSpace);
    fem_solver.apply(diffusion_op, f, *fem_solution);
    if (DSC_CONFIG_GET("global.vtk_output", false)) {
      Dune::Multiscale::FEM::write_discrete_function(*fem_solution, "fem_solution");
    }
  }

  return ErrorCalculator(&msfem_solution, fem_solution.get()).print(DSC_LOG_INFO_0);

} // function algorithm

} // namespace MsFEM {
} // namespace Multiscale {
} // namespace Dune {
<|endoftext|>


<commit_before><commit_msg>Fix argument order<commit_after><|endoftext|>


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

#ifndef ECCLESIA_LIB_STRINGS_STRIP_TEST_H_
#define ECCLESIA_LIB_STRINGS_STRIP_TEST_H_

#include "ecclesia/lib/strings/strip.h"

#include "gtest/gtest.h"

namespace ecclesia {
namespace {

TEST(StringStripTest, TrimSuffixWhitespace) {
  EXPECT_EQ(TrimSuffixWhitespace("abc "), "abc");
  EXPECT_EQ(TrimSuffixWhitespace("abc xyz   "), "abc xyz");
  EXPECT_EQ(TrimSuffixWhitespace("abc\t"), "abc");
  EXPECT_EQ(TrimSuffixWhitespace(" abc"), " abc");
  EXPECT_EQ(TrimSuffixWhitespace(" a b c "), " a b c");
  EXPECT_EQ(TrimSuffixWhitespace(""), "");
  EXPECT_EQ(TrimSuffixWhitespace(" "), "");
}

TEST(StringStripTest, TrimPrefixWhitespace) {
  EXPECT_EQ(TrimPrefixWhitespace("abc "), "abc ");
  EXPECT_EQ(TrimPrefixWhitespace(" abc xyz"), "abc xyz");
  EXPECT_EQ(TrimPrefixWhitespace("\tabc\t"), "abc\t");
  EXPECT_EQ(TrimPrefixWhitespace(" abc"), "abc");
  EXPECT_EQ(TrimPrefixWhitespace(" a b c "), "a b c ");
  EXPECT_EQ(TrimPrefixWhitespace(""), "");
  EXPECT_EQ(TrimPrefixWhitespace(" "), "");
}

TEST(StringStripTest, TrimString) {
  EXPECT_EQ(TrimString("abc "), "abc");
  EXPECT_EQ(TrimString(" abc xyz "), "abc xyz");
  EXPECT_EQ(TrimString("\tabc\t"), "abc");
  EXPECT_EQ(TrimString(" abc"), "abc");
  EXPECT_EQ(TrimString(" a b c "), "a b c");
  EXPECT_EQ(TrimString(""), "");
  EXPECT_EQ(TrimString(" "), "");
}

}  // namespace
}  // namespace ecclesia

#endif  // ECCLESIA_LIB_STRINGS_STRIP_TEST_H_
<commit_msg>Internal change<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * 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 "ecclesia/lib/strings/strip.h"

#include "gtest/gtest.h"

namespace ecclesia {
namespace {

TEST(StringStripTest, TrimSuffixWhitespace) {
  EXPECT_EQ(TrimSuffixWhitespace("abc "), "abc");
  EXPECT_EQ(TrimSuffixWhitespace("abc xyz   "), "abc xyz");
  EXPECT_EQ(TrimSuffixWhitespace("abc\t"), "abc");
  EXPECT_EQ(TrimSuffixWhitespace(" abc"), " abc");
  EXPECT_EQ(TrimSuffixWhitespace(" a b c "), " a b c");
  EXPECT_EQ(TrimSuffixWhitespace(""), "");
  EXPECT_EQ(TrimSuffixWhitespace(" "), "");
}

TEST(StringStripTest, TrimPrefixWhitespace) {
  EXPECT_EQ(TrimPrefixWhitespace("abc "), "abc ");
  EXPECT_EQ(TrimPrefixWhitespace(" abc xyz"), "abc xyz");
  EXPECT_EQ(TrimPrefixWhitespace("\tabc\t"), "abc\t");
  EXPECT_EQ(TrimPrefixWhitespace(" abc"), "abc");
  EXPECT_EQ(TrimPrefixWhitespace(" a b c "), "a b c ");
  EXPECT_EQ(TrimPrefixWhitespace(""), "");
  EXPECT_EQ(TrimPrefixWhitespace(" "), "");
}

TEST(StringStripTest, TrimString) {
  EXPECT_EQ(TrimString("abc "), "abc");
  EXPECT_EQ(TrimString(" abc xyz "), "abc xyz");
  EXPECT_EQ(TrimString("\tabc\t"), "abc");
  EXPECT_EQ(TrimString(" abc"), "abc");
  EXPECT_EQ(TrimString(" a b c "), "a b c");
  EXPECT_EQ(TrimString(""), "");
  EXPECT_EQ(TrimString(" "), "");
}

}  // namespace
}  // namespace ecclesia
<|endoftext|>


<commit_before>/* +---------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)               |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2016, Individual contributors, see AUTHORS file        |
   | See: http://www.mrpt.org/Authors - All rights reserved.                   |
   | Released under BSD License. See details in http://www.mrpt.org/License    |
   +---------------------------------------------------------------------------+ */

#include "base-precomp.h"  // Precompiled headers

#include <mrpt/utils/CConfigFileBase.h>
#include <mrpt/system/string_utils.h>
#include <mrpt/system/os.h>

using namespace std;
using namespace mrpt::utils;
using namespace mrpt::system;

void  CConfigFileBase::write(const std::string &section, const std::string &name, double value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format("%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, float value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format("%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, int value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format("%i",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint32_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint64_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::string &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, value , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%i ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<unsigned int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<unsigned int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%u ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<float> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<float>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.9e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<double> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<double>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.16e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<bool> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<bool>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%c ", *it ? '1':'0');
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

/** Write a generic string with optional padding and a comment field ("// ...") at the end of the line. */
void  CConfigFileBase::writeString(const std::string &section,const std::string &name, const std::string &str, const int name_padding_width, const int value_padding_width, const std::string &comment)
{
	if (name_padding_width<1 && value_padding_width<1 && comment.empty())
		this->writeString(section,name,str);  // Default (old) behavior.

	std::string name_pad;
	if (name_padding_width>=1)
	     name_pad = mrpt::format("%*s",-name_padding_width, name.c_str());  // negative width: printf right padding
	else name_pad = name;

	std::string value_pad;
	if (value_padding_width>=1)
	     value_pad = mrpt::format(" %*s",-value_padding_width, str.c_str());   // negative width: printf right padding
	else value_pad = str;

	if (!comment.empty())
	{
		value_pad += std::string("// ");
		value_pad += comment;
	}

	this->writeString(section,name_pad,value_pad);
}

/*---------------------------------------------------------------
					read_double
 ---------------------------------------------------------------*/
double  CConfigFileBase::read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound ) const
{
	return atof( readString(section,name,format("%.16e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_float
 ---------------------------------------------------------------*/
float  CConfigFileBase::read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound ) const
{
	return (float)atof( readString(section,name,format("%.10e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_int
 ---------------------------------------------------------------*/
int  CConfigFileBase::read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound ) const
{
	return atoi( readString(section,name,format("%i",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_uint64_t
 ---------------------------------------------------------------*/
uint64_t CConfigFileBase::read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound ) const
{
	string s = readString(section,name,format("%lu",(long unsigned int)defaultValue),failIfNotFound);
	return mrpt::system::os::_strtoull(s.c_str(),NULL, 0);
}

/*---------------------------------------------------------------
					read_bool
 ---------------------------------------------------------------*/
bool  CConfigFileBase::read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound ) const
{
	const string s = mrpt::system::lowerCase(trim(readString(section,name,string(defaultValue ? "1":"0"),failIfNotFound)));
	if (s=="true") return true;
	if (s=="false") return false;
	if (s=="yes") return true;
	if (s=="no") return false;
	return (0 != atoi(s.c_str()));
}

/*---------------------------------------------------------------
					read_string
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	return mrpt::system::trim(readString(section, name, defaultValue,failIfNotFound ));
}

/*---------------------------------------------------------------
					read_string_first_word
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	string s = readString(section, name, defaultValue,failIfNotFound );
	vector_string  auxStrs;
	mrpt::system::tokenize(s,"[], \t", auxStrs);
	if (auxStrs.empty())
	{
		if (failIfNotFound)
		{
			THROW_EXCEPTION( format("Value '%s' seems to be present in section '%s' but, are all whitespaces??",
				name.c_str(),
				section.c_str()  ) );
		}
		else return "";
	}
	else return auxStrs[0];
}

/** Checks if a given section exists (name is case insensitive) */
bool CConfigFileBase::sectionExists( const std::string &section_name) const
{
	vector_string sects;
	getAllSections(sects);
	for (vector_string::iterator s=sects.begin();s!=sects.end();++s)
		if (!mrpt::system::os::_strcmpi(section_name.c_str(), s->c_str() ))
			return true;
	return false;
}

<commit_msg>smarter formatting of cfg files write()<commit_after>/* +---------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)               |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2016, Individual contributors, see AUTHORS file        |
   | See: http://www.mrpt.org/Authors - All rights reserved.                   |
   | Released under BSD License. See details in http://www.mrpt.org/License    |
   +---------------------------------------------------------------------------+ */

#include "base-precomp.h"  // Precompiled headers

#include <mrpt/utils/CConfigFileBase.h>
#include <mrpt/system/string_utils.h>
#include <mrpt/system/os.h>

using namespace std;
using namespace mrpt::utils;
using namespace mrpt::system;

void  CConfigFileBase::write(const std::string &section, const std::string &name, double value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format(((std::abs(value)>1e-4 && std::abs(value)<1e4 ) || value==.0)? "%f" : "%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, float value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format(((std::abs(value)>1e-4f && std::abs(value)<1e4f ) || value==.0f) ? "%f" : "%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, int value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format("%i",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint32_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint64_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::string &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, value , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%i ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<unsigned int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<unsigned int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%u ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<float> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<float>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.9e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<double> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<double>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.16e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<bool> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<bool>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%c ", *it ? '1':'0');
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

/** Write a generic string with optional padding and a comment field ("// ...") at the end of the line. */
void  CConfigFileBase::writeString(const std::string &section,const std::string &name, const std::string &str, const int name_padding_width, const int value_padding_width, const std::string &comment)
{
	if (name_padding_width<1 && value_padding_width<1 && comment.empty())
		this->writeString(section,name,str);  // Default (old) behavior.

	std::string name_pad;
	if (name_padding_width>=1)
	     name_pad = mrpt::format("%*s",-name_padding_width, name.c_str());  // negative width: printf right padding
	else name_pad = name;

	std::string value_pad;
	if (value_padding_width>=1)
	     value_pad = mrpt::format(" %*s",-value_padding_width, str.c_str());   // negative width: printf right padding
	else value_pad = str;

	if (!comment.empty())
	{
		value_pad += std::string("// ");
		value_pad += comment;
	}

	this->writeString(section,name_pad,value_pad);
}

/*---------------------------------------------------------------
					read_double
 ---------------------------------------------------------------*/
double  CConfigFileBase::read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound ) const
{
	return atof( readString(section,name,format("%.16e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_float
 ---------------------------------------------------------------*/
float  CConfigFileBase::read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound ) const
{
	return (float)atof( readString(section,name,format("%.10e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_int
 ---------------------------------------------------------------*/
int  CConfigFileBase::read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound ) const
{
	return atoi( readString(section,name,format("%i",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_uint64_t
 ---------------------------------------------------------------*/
uint64_t CConfigFileBase::read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound ) const
{
	string s = readString(section,name,format("%lu",(long unsigned int)defaultValue),failIfNotFound);
	return mrpt::system::os::_strtoull(s.c_str(),NULL, 0);
}

/*---------------------------------------------------------------
					read_bool
 ---------------------------------------------------------------*/
bool  CConfigFileBase::read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound ) const
{
	const string s = mrpt::system::lowerCase(trim(readString(section,name,string(defaultValue ? "1":"0"),failIfNotFound)));
	if (s=="true") return true;
	if (s=="false") return false;
	if (s=="yes") return true;
	if (s=="no") return false;
	return (0 != atoi(s.c_str()));
}

/*---------------------------------------------------------------
					read_string
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	return mrpt::system::trim(readString(section, name, defaultValue,failIfNotFound ));
}

/*---------------------------------------------------------------
					read_string_first_word
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	string s = readString(section, name, defaultValue,failIfNotFound );
	vector_string  auxStrs;
	mrpt::system::tokenize(s,"[], \t", auxStrs);
	if (auxStrs.empty())
	{
		if (failIfNotFound)
		{
			THROW_EXCEPTION( format("Value '%s' seems to be present in section '%s' but, are all whitespaces??",
				name.c_str(),
				section.c_str()  ) );
		}
		else return "";
	}
	else return auxStrs[0];
}

/** Checks if a given section exists (name is case insensitive) */
bool CConfigFileBase::sectionExists( const std::string &section_name) const
{
	vector_string sects;
	getAllSections(sects);
	for (vector_string::iterator s=sects.begin();s!=sects.end();++s)
		if (!mrpt::system::os::_strcmpi(section_name.c_str(), s->c_str() ))
			return true;
	return false;
}

<|endoftext|>


<commit_before>/***********************************************************************
    filename:   SimpleTimer.cpp
    created:    Sat Feb 18 2012
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/SimpleTimer.h"

namespace CEGUI
{

#if defined(__WIN32__) || defined(_WIN32)
#include <windows.h>
double SimpleTimer::currentTime()
{
    return timeGetTime() / 1000.0;
}

#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)  || defined(__HAIKU__) || defined(__CYGWIN__)
#include <sys/time.h>
double SimpleTimer::currentTime()
{
    timeval timeStructure;
    gettimeofday(&timeStructure, 0);
    return timeStructure.tv_sec + timeStructure.tv_usec / 1000000.0;
}
#else
#error "SimpleTimer not available for this platform, please implement it"
#endif

}

<commit_msg>Do not include system timer related headers into CEGUI namespace<commit_after>/***********************************************************************
    filename:   SimpleTimer.cpp
    created:    Sat Feb 18 2012
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUI/SimpleTimer.h"

#if defined(__WIN32__) || defined(_WIN32)
#include <windows.h>
double CEGUI::SimpleTimer::currentTime()
{
    return timeGetTime() / 1000.0;
}

#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)  || defined(__HAIKU__) || defined(__CYGWIN__)
#include <sys/time.h>
double CEGUI::SimpleTimer::currentTime()
{
    timeval timeStructure;
    gettimeofday(&timeStructure, 0);
    return timeStructure.tv_sec + timeStructure.tv_usec / 1000000.0;
}
#else
#error "SimpleTimer not available for this platform, please implement it"
#endif
<|endoftext|>


<commit_before>/* +---------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)               |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2016, Individual contributors, see AUTHORS file        |
   | See: http://www.mrpt.org/Authors - All rights reserved.                   |
   | Released under BSD License. See details in http://www.mrpt.org/License    |
   +---------------------------------------------------------------------------+ */

#include "base-precomp.h"  // Precompiled headers

#include <mrpt/utils/CConfigFileBase.h>
#include <mrpt/system/string_utils.h>
#include <mrpt/system/os.h>

using namespace std;
using namespace mrpt::utils;
using namespace mrpt::system;

void  CConfigFileBase::write(const std::string &section, const std::string &name, double value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format(((std::abs(value)>1e-4 && std::abs(value)<1e4 ) || value==.0)? "%f" : "%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, float value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format(((std::abs(value)>1e-4f && std::abs(value)<1e4f ) || value==.0f) ? "%f" : "%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, int value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format("%i",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint32_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint64_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::string &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, value , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%i ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<unsigned int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<unsigned int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%u ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<float> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<float>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.9e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<double> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<double>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.16e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<bool> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<bool>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%c ", *it ? '1':'0');
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

/** Write a generic string with optional padding and a comment field ("// ...") at the end of the line. */
void  CConfigFileBase::writeString(const std::string &section,const std::string &name, const std::string &str, const int name_padding_width, const int value_padding_width, const std::string &comment)
{
	if (name_padding_width<1 && value_padding_width<1 && comment.empty())
		this->writeString(section,name,str);  // Default (old) behavior.

	std::string name_pad;
	if (name_padding_width>=1)
	     name_pad = mrpt::format("%*s",-name_padding_width, name.c_str());  // negative width: printf right padding
	else name_pad = name;

	std::string value_pad;
	if (value_padding_width>=1)
	     value_pad = mrpt::format(" %*s",-value_padding_width, str.c_str());   // negative width: printf right padding
	else value_pad = str;

	if (!comment.empty())
	{
		value_pad += std::string("// ");
		value_pad += comment;
	}

	this->writeString(section,name_pad,value_pad);
}

/*---------------------------------------------------------------
					read_double
 ---------------------------------------------------------------*/
double  CConfigFileBase::read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound ) const
{
	return atof( readString(section,name,format("%.16e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_float
 ---------------------------------------------------------------*/
float  CConfigFileBase::read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound ) const
{
	return (float)atof( readString(section,name,format("%.10e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_int
 ---------------------------------------------------------------*/
int  CConfigFileBase::read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound ) const
{
	return atoi( readString(section,name,format("%i",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_uint64_t
 ---------------------------------------------------------------*/
uint64_t CConfigFileBase::read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound ) const
{
	string s = readString(section,name,format("%lu",(long unsigned int)defaultValue),failIfNotFound);
	return mrpt::system::os::_strtoull(s.c_str(),NULL, 0);
}

/*---------------------------------------------------------------
					read_bool
 ---------------------------------------------------------------*/
bool  CConfigFileBase::read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound ) const
{
	const string s = mrpt::system::lowerCase(trim(readString(section,name,string(defaultValue ? "1":"0"),failIfNotFound)));
	if (s=="true") return true;
	if (s=="false") return false;
	if (s=="yes") return true;
	if (s=="no") return false;
	return (0 != atoi(s.c_str()));
}

/*---------------------------------------------------------------
					read_string
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	return mrpt::system::trim(readString(section, name, defaultValue,failIfNotFound ));
}

/*---------------------------------------------------------------
					read_string_first_word
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	string s = readString(section, name, defaultValue,failIfNotFound );
	vector_string  auxStrs;
	mrpt::system::tokenize(s,"[], \t", auxStrs);
	if (auxStrs.empty())
	{
		if (failIfNotFound)
		{
			THROW_EXCEPTION( format("Value '%s' seems to be present in section '%s' but, are all whitespaces??",
				name.c_str(),
				section.c_str()  ) );
		}
		else return "";
	}
	else return auxStrs[0];
}

/** Checks if a given section exists (name is case insensitive) */
bool CConfigFileBase::sectionExists( const std::string &section_name) const
{
	vector_string sects;
	getAllSections(sects);
	for (vector_string::iterator s=sects.begin();s!=sects.end();++s)
		if (!mrpt::system::os::_strcmpi(section_name.c_str(), s->c_str() ))
			return true;
	return false;
}

<commit_msg>make sure there is always a space before comments in INI files<commit_after>/* +---------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)               |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2016, Individual contributors, see AUTHORS file        |
   | See: http://www.mrpt.org/Authors - All rights reserved.                   |
   | Released under BSD License. See details in http://www.mrpt.org/License    |
   +---------------------------------------------------------------------------+ */

#include "base-precomp.h"  // Precompiled headers

#include <mrpt/utils/CConfigFileBase.h>
#include <mrpt/system/string_utils.h>
#include <mrpt/system/os.h>

using namespace std;
using namespace mrpt::utils;
using namespace mrpt::system;

void  CConfigFileBase::write(const std::string &section, const std::string &name, double value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format(((std::abs(value)>1e-4 && std::abs(value)<1e4 ) || value==.0)? "%f" : "%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, float value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format(((std::abs(value)>1e-4f && std::abs(value)<1e4f ) || value==.0f) ? "%f" : "%e",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, int value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, format("%i",value), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint32_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}
void  CConfigFileBase::write(const std::string &section, const std::string &name, uint64_t value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	std::stringstream ss;
	ss << value;
	writeString(section, name, ss.str(), name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::string &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	writeString(section, name, value , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%i ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<unsigned int> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<unsigned int>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%u ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<float> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<float>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.9e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<double> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<double>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%.16e ", *it);
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

void  CConfigFileBase::write(const std::string &section, const std::string &name, const std::vector<bool> &value, const int name_padding_width, const int value_padding_width, const std::string &comment )
{
	string str;
	for (std::vector<bool>::const_iterator it=value.begin();it!=value.end();++it)
		str+=format("%c ", *it ? '1':'0');
	writeString(section, name, str , name_padding_width,value_padding_width,comment);
}

/** Write a generic string with optional padding and a comment field ("// ...") at the end of the line. */
void  CConfigFileBase::writeString(const std::string &section,const std::string &name, const std::string &str, const int name_padding_width, const int value_padding_width, const std::string &comment)
{
	if (name_padding_width<1 && value_padding_width<1 && comment.empty())
		this->writeString(section,name,str);  // Default (old) behavior.

	std::string name_pad;
	if (name_padding_width>=1)
	     name_pad = mrpt::format("%*s",-name_padding_width, name.c_str());  // negative width: printf right padding
	else name_pad = name;

	std::string value_pad;
	if (value_padding_width>=1)
	     value_pad = mrpt::format(" %*s",-value_padding_width, str.c_str());   // negative width: printf right padding
	else value_pad = str;

	if (!comment.empty())
	{
		value_pad += std::string(" // ");
		value_pad += comment;
	}

	this->writeString(section,name_pad,value_pad);
}

/*---------------------------------------------------------------
					read_double
 ---------------------------------------------------------------*/
double  CConfigFileBase::read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound ) const
{
	return atof( readString(section,name,format("%.16e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_float
 ---------------------------------------------------------------*/
float  CConfigFileBase::read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound ) const
{
	return (float)atof( readString(section,name,format("%.10e",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_int
 ---------------------------------------------------------------*/
int  CConfigFileBase::read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound ) const
{
	return atoi( readString(section,name,format("%i",defaultValue),failIfNotFound).c_str());
}

/*---------------------------------------------------------------
					read_uint64_t
 ---------------------------------------------------------------*/
uint64_t CConfigFileBase::read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound ) const
{
	string s = readString(section,name,format("%lu",(long unsigned int)defaultValue),failIfNotFound);
	return mrpt::system::os::_strtoull(s.c_str(),NULL, 0);
}

/*---------------------------------------------------------------
					read_bool
 ---------------------------------------------------------------*/
bool  CConfigFileBase::read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound ) const
{
	const string s = mrpt::system::lowerCase(trim(readString(section,name,string(defaultValue ? "1":"0"),failIfNotFound)));
	if (s=="true") return true;
	if (s=="false") return false;
	if (s=="yes") return true;
	if (s=="no") return false;
	return (0 != atoi(s.c_str()));
}

/*---------------------------------------------------------------
					read_string
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	return mrpt::system::trim(readString(section, name, defaultValue,failIfNotFound ));
}

/*---------------------------------------------------------------
					read_string_first_word
 ---------------------------------------------------------------*/
std::string  CConfigFileBase::read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound ) const
{
	string s = readString(section, name, defaultValue,failIfNotFound );
	vector_string  auxStrs;
	mrpt::system::tokenize(s,"[], \t", auxStrs);
	if (auxStrs.empty())
	{
		if (failIfNotFound)
		{
			THROW_EXCEPTION( format("Value '%s' seems to be present in section '%s' but, are all whitespaces??",
				name.c_str(),
				section.c_str()  ) );
		}
		else return "";
	}
	else return auxStrs[0];
}

/** Checks if a given section exists (name is case insensitive) */
bool CConfigFileBase::sectionExists( const std::string &section_name) const
{
	vector_string sects;
	getAllSections(sects);
	for (vector_string::iterator s=sects.begin();s!=sects.end();++s)
		if (!mrpt::system::os::_strcmpi(section_name.c_str(), s->c_str() ))
			return true;
	return false;
}

<|endoftext|>