<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)
//
// Contributors: Kirsten Weber

#ifndef DUNE_GDT_EVALUATION_ELLIPTIC_HH
#define DUNE_GDT_EVALUATION_ELLIPTIC_HH

#include <tuple>

#include <dune/common/dynmatrix.hh>
#include <dune/common/typetraits.hh>

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

#include "interface.hh"

namespace Dune {
namespace GDT {
namespace LocalEvaluation {

// forward
template< class DiffusionFactorImp, class DiffusionTensorImp = void >
class Elliptic;

namespace internal {

/**
 *  \brief  Traits for the Elliptic evaluation.
 */
template< class DiffusionFactorImp, class DiffusionTensorImp >
class EllipticTraits
{
  static_assert(Stuff::is_localizable_function< DiffusionFactorImp >::value,
                "DiffusionFactorImp has to be a localizable function!");
  static_assert(Stuff::is_localizable_function< DiffusionTensorImp >::value,
                "DiffusionTensorImp has to be a localizable function!");
  static_assert(std::is_same< typename DiffusionFactorImp::EntityType,
                              typename DiffusionTensorImp::EntityType >::value,
                "EntityTypes have to agree!");
  static_assert(std::is_same< typename DiffusionFactorImp::DomainFieldType,
                              typename DiffusionTensorImp::DomainFieldType >::value,
                "DomainFieldTypes have to agree!");
  static_assert(DiffusionFactorImp::dimDomain == DiffusionTensorImp::dimDomain,
                "Dimensions have to agree!");
public:
  typedef Elliptic< DiffusionFactorImp, DiffusionTensorImp >                  derived_type;
  typedef DiffusionFactorImp                                                  LocalizableDiffusionFactorFunctionType;
  typedef DiffusionTensorImp                                                  LocalizableDiffusionTensorFunctionType;
  typedef typename LocalizableDiffusionFactorFunctionType::LocalfunctionType  LocalDiffusionFactorFunctionType;
  typedef typename LocalizableDiffusionTensorFunctionType::LocalfunctionType  LocalDiffusionTensorFunctionType;
  typedef std::tuple< std::shared_ptr< LocalDiffusionFactorFunctionType >,
                      std::shared_ptr< LocalDiffusionTensorFunctionType > >   LocalfunctionTupleType;
  typedef typename LocalizableDiffusionFactorFunctionType::EntityType         EntityType;
  typedef typename LocalizableDiffusionFactorFunctionType::DomainFieldType    DomainFieldType;
  static const unsigned int dimDomain = LocalizableDiffusionFactorFunctionType::dimDomain;
}; // class EllipticTraits

template< class LocalizableFunctionImp >
class EllipticTraits< LocalizableFunctionImp, void >
{
  static_assert(Stuff::is_localizable_function< LocalizableFunctionImp >::value,
                "LocalizableFunctionImp has to be a localizable function!");
public:
  typedef LocalizableFunctionImp                                LocalizableFunctionType;
  typedef Elliptic< LocalizableFunctionType, void >             derived_type;
  typedef typename LocalizableFunctionType::EntityType          EntityType;
  typedef typename LocalizableFunctionType::DomainFieldType     DomainFieldType;
  typedef typename LocalizableFunctionType::LocalfunctionType   LocalfunctionType;
  typedef std::tuple< std::shared_ptr< LocalfunctionType > >    LocalfunctionTupleType;
  static const unsigned int dimDomain = LocalizableFunctionType::dimDomain;
}; // class EllipticTraits< ..., void >

} // namespace internal

/**
 *  \brief  Computes an elliptic evaluation.
 */
template< class LocalizableFunctionImp >
class Elliptic< LocalizableFunctionImp, void >
  : public LocalEvaluation::Codim0Interface< internal::EllipticTraits< LocalizableFunctionImp, void >, 2 >
{
public:
  typedef internal::EllipticTraits< LocalizableFunctionImp, void >  Traits;
  typedef typename Traits::LocalizableFunctionType                  LocalizableFunctionType;
  typedef typename Traits::LocalfunctionTupleType                   LocalfunctionTupleType;
  typedef typename Traits::EntityType                               EntityType;
  typedef typename Traits::DomainFieldType                          DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  explicit Elliptic(const LocalizableFunctionType& inducingFunction)
    : inducingFunction_(inducingFunction)
  {}

  LocalfunctionTupleType localFunctions(const EntityType& entity) const
  {
    return std::make_tuple(inducingFunction_.local_function(entity));
  }

  /**
   * \brief extracts the local functions and calls the correct order() method
   */
  template< class R, int rT, int rCT, int rA, int rCA >
  size_t order(const LocalfunctionTupleType& localFuncs,
               const Stuff::LocalfunctionSetInterface
                   < EntityType, DomainFieldType, dimDomain, R, rT, rCT >& testBase,
               const Stuff::LocalfunctionSetInterface
                   < EntityType, DomainFieldType, dimDomain, R, rA, rCA >& ansatzBase) const
  {
    const auto localFunction = std::get< 0 >(localFuncs);
    return redirect_order(*localFunction, testBase, ansatzBase);
  }

  /**
   * \brief extracts the local functions and calls the correct evaluate() method
   */
  template< class R, int rT, int rCT, int rA, int rCA >
  void evaluate(const LocalfunctionTupleType& localFuncs,
                const Stuff::LocalfunctionSetInterface
                    < EntityType, DomainFieldType, dimDomain, R, rT, rCT >& testBase,
                const Stuff::LocalfunctionSetInterface
                    < EntityType, DomainFieldType, dimDomain, R, rA, rCA >& ansatzBase,
                const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                Dune::DynamicMatrix< R >& ret) const
  {
    const auto localFunction = std::get< 0 >(localFuncs);
    evaluate(*localFunction, testBase, ansatzBase, localPoint, ret);
  }

  /**
   *  \brief  Computes an elliptic evaluation for a 2x2 matrix-valued local function and matrix-valued basefunctionsets.
   *  \tparam R RangeFieldType
   *  \note   Unfortunately we need this explicit specialization, otherwise the compiler will complain for 1d grids.
   */
  template< class R >
  void evaluate(const Stuff::LocalfunctionInterface< EntityType, DomainFieldType, dimDomain, R, 2, 2 >& localFunction,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& testBase,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& ansatzBase,
                const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                Dune::DynamicMatrix< R >& ret) const
  {
    evaluate_matrix_valued_(localFunction, testBase, ansatzBase, localPoint, ret);
  }

  /**
   *  \brief  Computes an elliptic evaluation for a 3x3 matrix-valued local function and matrix-valued basefunctionsets.
   *  \tparam R RangeFieldType
   *  \note   Unfortunately we need this explicit specialization, otherwise the compiler will complain for 1d grids.
   */
  template< class R >
  void evaluate(const Stuff::LocalfunctionInterface< EntityType, DomainFieldType, dimDomain, R, 3, 3 >& localFunction,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& testBase,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& ansatzBase,
                const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                Dune::DynamicMatrix< R >& ret) const
  {
    evaluate_matrix_valued_(localFunction, testBase, ansatzBase, localPoint, ret);
  }

private:
  /**
   *  \return localFunction.order() + (testBase.order() - 1) + (ansatzBase.order() - 1)
   */
  template< class R, int rL, int rCL, int rT, int rCT, int rA, int rCA >
  size_t redirect_order(const Stuff::LocalfunctionInterface
                            < EntityType, DomainFieldType, dimDomain, R, rL, rCL >& localFunction,
                        const Stuff::LocalfunctionSetInterface
                            < EntityType, DomainFieldType, dimDomain, R, rT, rCT >& testBase,
                        const Stuff::LocalfunctionSetInterface
                            < EntityType, DomainFieldType, dimDomain, R, rA, rCA >& ansatzBase) const
  {
    return localFunction.order()
         + std::max(ssize_t(testBase.order()) - 1, ssize_t(0))
         + std::max(ssize_t(ansatzBase.order()) - 1, ssize_t(0));
  } // size_t redirect_order( ... )

  /**
   *  \brief  Computes an elliptic evaluation for a scalar local function and scalar or vector valued basefunctionsets.
   *  \tparam R RangeFieldType
   */
  template< class R, int r >
  void evaluate(const Stuff::LocalfunctionInterface
                             < EntityType, DomainFieldType, dimDomain, R, 1, 1 >& localFunction,
                         const Stuff::LocalfunctionSetInterface
                             < EntityType, DomainFieldType, dimDomain, R, r, 1 >& testBase,
                         const Stuff::LocalfunctionSetInterface
                             < EntityType, DomainFieldType, dimDomain, R, r, 1 >& ansatzBase,
                         const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                         Dune::DynamicMatrix< R >& ret) const
  {
    typedef typename Stuff::LocalfunctionSetInterface
        < EntityType, DomainFieldType, dimDomain, R, r, 1 >::JacobianRangeType JacobianRangeType;
    // evaluate local function
    const auto functionValue = localFunction.evaluate(localPoint);
    // evaluate test gradient
    const size_t rows = testBase.size();
    std::vector< JacobianRangeType > testGradients(rows, JacobianRangeType(0));
    testBase.jacobian(localPoint, testGradients);
    // evaluate ansatz gradient
    const size_t cols = ansatzBase.size();
    std::vector< JacobianRangeType > ansatzGradients(cols, JacobianRangeType(0));
    ansatzBase.jacobian(localPoint, ansatzGradients);
    // compute products
    assert(ret.rows() >= rows);
    assert(ret.cols() >= cols);
    for (size_t ii = 0; ii < rows; ++ii) {
      auto& retRow = ret[ii];
      for (size_t jj = 0; jj < cols; ++jj) {
        retRow[jj] = functionValue * (ansatzGradients[jj][0] * testGradients[ii][0]);
      }
    }
  } // ... redirect_evaluate< ..., 1, ... >(...)

  template< class R >
  void evaluate_matrix_valued_(const Stuff::LocalfunctionInterface
                                   < EntityType, DomainFieldType, dimDomain, R, dimDomain, dimDomain >& localFunction,
                               const Stuff::LocalfunctionSetInterface
                                   < EntityType, DomainFieldType, dimDomain, R, 1, 1 >& testBase,
                               const Stuff::LocalfunctionSetInterface
                                   < EntityType, DomainFieldType, dimDomain, R, 1, 1 >& ansatzBase,
                               const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                               Dune::DynamicMatrix< R >& ret) const
  {
    typedef typename Stuff::LocalfunctionInterface
        < EntityType, DomainFieldType, dimDomain, R, dimDomain, dimDomain >::RangeType DiffusionRangeType;
    typedef typename Stuff::LocalfunctionSetInterface
        < EntityType, DomainFieldType, dimDomain, R, 1, 1 >::JacobianRangeType         JacobianRangeType;
    // evaluate local function
    const DiffusionRangeType functionValue = localFunction.evaluate(localPoint);
    // evaluate test gradient
    const size_t rows = testBase.size();
    std::vector< JacobianRangeType > testGradients(rows, JacobianRangeType(0));
    testBase.jacobian(localPoint, testGradients);
    // evaluate ansatz gradient
    const size_t cols = ansatzBase.size();
    std::vector< JacobianRangeType > ansatzGradients(cols, JacobianRangeType(0));
    ansatzBase.jacobian(localPoint, ansatzGradients);
    // compute products
    assert(ret.rows() >= rows);
    assert(ret.cols() >= cols);
    FieldVector< DomainFieldType, dimDomain > product(0.0);
    for (size_t ii = 0; ii < rows; ++ii) {
      auto& retRow = ret[ii];
      for (size_t jj = 0; jj < cols; ++jj) {
        functionValue.mv(ansatzGradients[jj][0], product);
        retRow[jj] = product * testGradients[ii][0];
      }
    }
  } // ... evaluate_matrix_valued_(...)

  const LocalizableFunctionType& inducingFunction_;
}; // class Elliptic

} // namespace Evaluation
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_EVALUATION_ELLIPTIC_HH
<commit_msg>[localevaluation.elliptic] add safe integer conversion<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)
//
// Contributors: Kirsten Weber

#ifndef DUNE_GDT_EVALUATION_ELLIPTIC_HH
#define DUNE_GDT_EVALUATION_ELLIPTIC_HH

#include <tuple>

#include <boost/numeric/conversion/cast.hpp>

#include <dune/common/dynmatrix.hh>
#include <dune/common/typetraits.hh>

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

#include "interface.hh"

namespace Dune {
namespace GDT {
namespace LocalEvaluation {

// forward
template< class DiffusionFactorImp, class DiffusionTensorImp = void >
class Elliptic;

namespace internal {

/**
 *  \brief  Traits for the Elliptic evaluation.
 */
template< class DiffusionFactorImp, class DiffusionTensorImp >
class EllipticTraits
{
  static_assert(Stuff::is_localizable_function< DiffusionFactorImp >::value,
                "DiffusionFactorImp has to be a localizable function!");
  static_assert(Stuff::is_localizable_function< DiffusionTensorImp >::value,
                "DiffusionTensorImp has to be a localizable function!");
  static_assert(std::is_same< typename DiffusionFactorImp::EntityType,
                              typename DiffusionTensorImp::EntityType >::value,
                "EntityTypes have to agree!");
  static_assert(std::is_same< typename DiffusionFactorImp::DomainFieldType,
                              typename DiffusionTensorImp::DomainFieldType >::value,
                "DomainFieldTypes have to agree!");
  static_assert(DiffusionFactorImp::dimDomain == DiffusionTensorImp::dimDomain,
                "Dimensions have to agree!");
public:
  typedef Elliptic< DiffusionFactorImp, DiffusionTensorImp >                  derived_type;
  typedef DiffusionFactorImp                                                  LocalizableDiffusionFactorFunctionType;
  typedef DiffusionTensorImp                                                  LocalizableDiffusionTensorFunctionType;
  typedef typename LocalizableDiffusionFactorFunctionType::LocalfunctionType  LocalDiffusionFactorFunctionType;
  typedef typename LocalizableDiffusionTensorFunctionType::LocalfunctionType  LocalDiffusionTensorFunctionType;
  typedef std::tuple< std::shared_ptr< LocalDiffusionFactorFunctionType >,
                      std::shared_ptr< LocalDiffusionTensorFunctionType > >   LocalfunctionTupleType;
  typedef typename LocalizableDiffusionFactorFunctionType::EntityType         EntityType;
  typedef typename LocalizableDiffusionFactorFunctionType::DomainFieldType    DomainFieldType;
  static const unsigned int dimDomain = LocalizableDiffusionFactorFunctionType::dimDomain;
}; // class EllipticTraits

template< class LocalizableFunctionImp >
class EllipticTraits< LocalizableFunctionImp, void >
{
  static_assert(Stuff::is_localizable_function< LocalizableFunctionImp >::value,
                "LocalizableFunctionImp has to be a localizable function!");
public:
  typedef LocalizableFunctionImp                                LocalizableFunctionType;
  typedef Elliptic< LocalizableFunctionType, void >             derived_type;
  typedef typename LocalizableFunctionType::EntityType          EntityType;
  typedef typename LocalizableFunctionType::DomainFieldType     DomainFieldType;
  typedef typename LocalizableFunctionType::LocalfunctionType   LocalfunctionType;
  typedef std::tuple< std::shared_ptr< LocalfunctionType > >    LocalfunctionTupleType;
  static const unsigned int dimDomain = LocalizableFunctionType::dimDomain;
}; // class EllipticTraits< ..., void >

} // namespace internal

/**
 *  \brief  Computes an elliptic evaluation.
 */
template< class LocalizableFunctionImp >
class Elliptic< LocalizableFunctionImp, void >
  : public LocalEvaluation::Codim0Interface< internal::EllipticTraits< LocalizableFunctionImp, void >, 2 >
{
public:
  typedef internal::EllipticTraits< LocalizableFunctionImp, void >  Traits;
  typedef typename Traits::LocalizableFunctionType                  LocalizableFunctionType;
  typedef typename Traits::LocalfunctionTupleType                   LocalfunctionTupleType;
  typedef typename Traits::EntityType                               EntityType;
  typedef typename Traits::DomainFieldType                          DomainFieldType;
  static const unsigned int dimDomain = Traits::dimDomain;

  explicit Elliptic(const LocalizableFunctionType& inducingFunction)
    : inducingFunction_(inducingFunction)
  {}

  LocalfunctionTupleType localFunctions(const EntityType& entity) const
  {
    return std::make_tuple(inducingFunction_.local_function(entity));
  }

  /**
   * \brief extracts the local functions and calls the correct order() method
   */
  template< class R, int rT, int rCT, int rA, int rCA >
  size_t order(const LocalfunctionTupleType& localFuncs,
               const Stuff::LocalfunctionSetInterface
                   < EntityType, DomainFieldType, dimDomain, R, rT, rCT >& testBase,
               const Stuff::LocalfunctionSetInterface
                   < EntityType, DomainFieldType, dimDomain, R, rA, rCA >& ansatzBase) const
  {
    const auto localFunction = std::get< 0 >(localFuncs);
    return redirect_order(*localFunction, testBase, ansatzBase);
  }

  /**
   * \brief extracts the local functions and calls the correct evaluate() method
   */
  template< class R, int rT, int rCT, int rA, int rCA >
  void evaluate(const LocalfunctionTupleType& localFuncs,
                const Stuff::LocalfunctionSetInterface
                    < EntityType, DomainFieldType, dimDomain, R, rT, rCT >& testBase,
                const Stuff::LocalfunctionSetInterface
                    < EntityType, DomainFieldType, dimDomain, R, rA, rCA >& ansatzBase,
                const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                Dune::DynamicMatrix< R >& ret) const
  {
    const auto localFunction = std::get< 0 >(localFuncs);
    evaluate(*localFunction, testBase, ansatzBase, localPoint, ret);
  }

  /**
   *  \brief  Computes an elliptic evaluation for a 2x2 matrix-valued local function and matrix-valued basefunctionsets.
   *  \tparam R RangeFieldType
   *  \note   Unfortunately we need this explicit specialization, otherwise the compiler will complain for 1d grids.
   */
  template< class R >
  void evaluate(const Stuff::LocalfunctionInterface< EntityType, DomainFieldType, dimDomain, R, 2, 2 >& localFunction,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& testBase,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& ansatzBase,
                const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                Dune::DynamicMatrix< R >& ret) const
  {
    evaluate_matrix_valued_(localFunction, testBase, ansatzBase, localPoint, ret);
  }

  /**
   *  \brief  Computes an elliptic evaluation for a 3x3 matrix-valued local function and matrix-valued basefunctionsets.
   *  \tparam R RangeFieldType
   *  \note   Unfortunately we need this explicit specialization, otherwise the compiler will complain for 1d grids.
   */
  template< class R >
  void evaluate(const Stuff::LocalfunctionInterface< EntityType, DomainFieldType, dimDomain, R, 3, 3 >& localFunction,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& testBase,
                const Stuff::LocalfunctionSetInterface< EntityType, DomainFieldType, dimDomain, R, 1, 1 >& ansatzBase,
                const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                Dune::DynamicMatrix< R >& ret) const
  {
    evaluate_matrix_valued_(localFunction, testBase, ansatzBase, localPoint, ret);
  }

private:
  /**
   *  \return localFunction.order() + (testBase.order() - 1) + (ansatzBase.order() - 1)
   */
  template< class R, int rL, int rCL, int rT, int rCT, int rA, int rCA >
  size_t redirect_order(const Stuff::LocalfunctionInterface
                            < EntityType, DomainFieldType, dimDomain, R, rL, rCL >& localFunction,
                        const Stuff::LocalfunctionSetInterface
                            < EntityType, DomainFieldType, dimDomain, R, rT, rCT >& testBase,
                        const Stuff::LocalfunctionSetInterface
                            < EntityType, DomainFieldType, dimDomain, R, rA, rCA >& ansatzBase) const
  {
    return localFunction.order()
        + boost::numeric_cast< size_t >(std::max(ssize_t(testBase.order())   - 1, ssize_t(0)))
        + boost::numeric_cast< size_t >(std::max(ssize_t(ansatzBase.order()) - 1, ssize_t(0)));
  } // size_t redirect_order( ... )

  /**
   *  \brief  Computes an elliptic evaluation for a scalar local function and scalar or vector valued basefunctionsets.
   *  \tparam R RangeFieldType
   */
  template< class R, int r >
  void evaluate(const Stuff::LocalfunctionInterface
                             < EntityType, DomainFieldType, dimDomain, R, 1, 1 >& localFunction,
                         const Stuff::LocalfunctionSetInterface
                             < EntityType, DomainFieldType, dimDomain, R, r, 1 >& testBase,
                         const Stuff::LocalfunctionSetInterface
                             < EntityType, DomainFieldType, dimDomain, R, r, 1 >& ansatzBase,
                         const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                         Dune::DynamicMatrix< R >& ret) const
  {
    typedef typename Stuff::LocalfunctionSetInterface
        < EntityType, DomainFieldType, dimDomain, R, r, 1 >::JacobianRangeType JacobianRangeType;
    // evaluate local function
    const auto functionValue = localFunction.evaluate(localPoint);
    // evaluate test gradient
    const size_t rows = testBase.size();
    std::vector< JacobianRangeType > testGradients(rows, JacobianRangeType(0));
    testBase.jacobian(localPoint, testGradients);
    // evaluate ansatz gradient
    const size_t cols = ansatzBase.size();
    std::vector< JacobianRangeType > ansatzGradients(cols, JacobianRangeType(0));
    ansatzBase.jacobian(localPoint, ansatzGradients);
    // compute products
    assert(ret.rows() >= rows);
    assert(ret.cols() >= cols);
    for (size_t ii = 0; ii < rows; ++ii) {
      auto& retRow = ret[ii];
      for (size_t jj = 0; jj < cols; ++jj) {
        retRow[jj] = functionValue * (ansatzGradients[jj][0] * testGradients[ii][0]);
      }
    }
  } // ... redirect_evaluate< ..., 1, ... >(...)

  template< class R >
  void evaluate_matrix_valued_(const Stuff::LocalfunctionInterface
                                   < EntityType, DomainFieldType, dimDomain, R, dimDomain, dimDomain >& localFunction,
                               const Stuff::LocalfunctionSetInterface
                                   < EntityType, DomainFieldType, dimDomain, R, 1, 1 >& testBase,
                               const Stuff::LocalfunctionSetInterface
                                   < EntityType, DomainFieldType, dimDomain, R, 1, 1 >& ansatzBase,
                               const Dune::FieldVector< DomainFieldType, dimDomain >& localPoint,
                               Dune::DynamicMatrix< R >& ret) const
  {
    typedef typename Stuff::LocalfunctionInterface
        < EntityType, DomainFieldType, dimDomain, R, dimDomain, dimDomain >::RangeType DiffusionRangeType;
    typedef typename Stuff::LocalfunctionSetInterface
        < EntityType, DomainFieldType, dimDomain, R, 1, 1 >::JacobianRangeType         JacobianRangeType;
    // evaluate local function
    const DiffusionRangeType functionValue = localFunction.evaluate(localPoint);
    // evaluate test gradient
    const size_t rows = testBase.size();
    std::vector< JacobianRangeType > testGradients(rows, JacobianRangeType(0));
    testBase.jacobian(localPoint, testGradients);
    // evaluate ansatz gradient
    const size_t cols = ansatzBase.size();
    std::vector< JacobianRangeType > ansatzGradients(cols, JacobianRangeType(0));
    ansatzBase.jacobian(localPoint, ansatzGradients);
    // compute products
    assert(ret.rows() >= rows);
    assert(ret.cols() >= cols);
    FieldVector< DomainFieldType, dimDomain > product(0.0);
    for (size_t ii = 0; ii < rows; ++ii) {
      auto& retRow = ret[ii];
      for (size_t jj = 0; jj < cols; ++jj) {
        functionValue.mv(ansatzGradients[jj][0], product);
        retRow[jj] = product * testGradients[ii][0];
      }
    }
  } // ... evaluate_matrix_valued_(...)

  const LocalizableFunctionType& inducingFunction_;
}; // class Elliptic

} // namespace Evaluation
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_EVALUATION_ELLIPTIC_HH
<|endoftext|>


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

#ifndef DUNE_STUFF_FUNCTION_CHECKERBOARD_HH
#define DUNE_STUFF_FUNCTION_CHECKERBOARD_HH

#include "config.h"

#include <vector>
#include <cmath>
#include <memory>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>

#include <dune/stuff/common/configtree.hh>

#include "interfaces.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class Checkerboard
  : public LocalizableFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
{
  typedef LocalizableFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
    BaseType;
  typedef Checkerboard< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > ThisType;

  class Localfunction
    : public LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
  {
    typedef LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > BaseType;
  public:
    typedef typename BaseType::EntityType EntityType;

    typedef typename BaseType::DomainFieldType  DomainFieldType;
    static const unsigned int                   dimDomain = BaseType::dimDomain;
    typedef typename BaseType::DomainType       DomainType;

    typedef typename BaseType::RangeFieldType RangeFieldType;
    static const unsigned int                 dimRange = BaseType::dimRange;
    static const unsigned int                 dimRangeCols = BaseType::dimRangeCols;
    typedef typename BaseType::RangeType      RangeType;

    typedef typename BaseType::JacobianRangeType JacobianRangeType;

    Localfunction(const EntityType& ent,
                  const RangeType value)
      : BaseType(ent)
      , value_(value)
    {}

    Localfunction(const Localfunction& /*other*/) = delete;

    Localfunction& operator=(const Localfunction& /*other*/) = delete;

    virtual size_t order() const DS_OVERRIDE
    {
      return 0;
    }

    virtual void evaluate(const DomainType& xx, RangeType& ret) const DS_OVERRIDE
    {
      assert(this->is_a_valid_point(xx));
      ret = value_;
    }

    virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const DS_OVERRIDE
    {
      assert(this->is_a_valid_point(xx));
      ret *= RangeFieldType(0);
    }

  private:
    const RangeType value_;
  }; // class Localfunction

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  typedef typename BaseType::DomainFieldType  DomainFieldType;
  static const int                            dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType       DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const int                          dimRange = BaseType::dimRange;
  static const int                          dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType      RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".checkerboard";
  }

  static Common::ConfigTree default_config(const std::string sub_name = "")
  {
    Common::ConfigTree config;
    config["lower_left"] = "[0.0; 0.0; 0.0]";
    config["upper_right"] = "[1.0; 1.0; 1.0]";
    config["num_elements"] = "[2; 2; 2]";
    config["values"] = "[1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0]";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::ConfigTree config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    // extract needed data
      auto lower_left = cfg.get< std::vector< DomainFieldType > >("lower_left", dimDomain);
      auto upper_right = cfg.get< std::vector< DomainFieldType > >("upper_right", dimDomain);
      auto num_elements = cfg.get< std::vector< size_t > >("num_elements");
      size_t num_values = 1;
      for (size_t ii = 0; ii < num_elements.size(); ++ii)
        num_values *= num_elements[ii];
      auto values = cfg.get< std::vector< RangeType > >("values", num_values);
      auto nm = static_id();
      if (cfg.has_key("name"))
        nm = cfg.get< std::string >("name");
      return Common::make_unique< ThisType >(std::move(lower_left), std::move(upper_right), std::move(num_elements), std::move(values), nm);
  } // ... create(...)

  Checkerboard(std::vector< DomainFieldType >&& lowerLeft,
               std::vector< DomainFieldType >&& upperRight,
               std::vector< size_t >&& numElements,
               std::vector< RangeType >&& values,
               std::string nm = static_id())
    : lowerLeft_(new std::vector< DomainFieldType >(std::move(lowerLeft)))
    , upperRight_(new std::vector< DomainFieldType >(std::move(upperRight)))
    , numElements_(new std::vector< size_t >(std::move(numElements)))
    , values_(new std::vector< RangeType >(std::move(values)))
    , name_(nm)
  {
    // checks
    if (lowerLeft_->size() < dimDomain)
      DUNE_THROW(Dune::RangeError,
                 "lowerLeft too small (is " << lowerLeft_->size() << ", should be " << dimDomain << ")");
    if (upperRight_->size() < dimDomain)
      DUNE_THROW(Dune::RangeError,
                 "upperRight too small (is " << upperRight_->size() << ", should be " << dimDomain << ")");
    if (numElements_->size() < dimDomain)
      DUNE_THROW(Dune::RangeError,
                 "numElements too small (is " << numElements_->size() << ", should be " << dimDomain << ")");
    size_t totalSubdomains = 1;
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      const auto& ll = (*lowerLeft_)[dd];
      const auto& ur = (*upperRight_)[dd];
      const auto& ne = (*numElements_)[dd];
      if (!(ll < ur))
        DUNE_THROW(Dune::RangeError, "lowerLeft has to be elementwise smaller than upperRight!");
      totalSubdomains *= ne;
    }
    if (values_->size() < totalSubdomains)
      DUNE_THROW(Dune::RangeError,
                 "values too small (is " << values_->size() << ", should be " << totalSubdomains << ")");
  } // Checkerboard(...)

  Checkerboard(const ThisType& other)
    : lowerLeft_(other.lowerLeft_)
    , upperRight_(other.upperRight_)
    , numElements_(other.numElements_)
    , values_(other.values_)
    , name_(other.name_)
  {}

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      lowerLeft_ = other.lowerLeft_;
      upperRight_ = other.upperRight_;
      numElements_ = other.numElements_;
      values_ = other.values_;
      name_ = other.name_;
    }
    return *this;
  }

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  virtual std::string name() const DS_OVERRIDE
  {
    return name_;
  }

  virtual std::unique_ptr< LocalfunctionType > local_function(const EntityType& entity) const DS_OVERRIDE
  {
    // decide on the subdomain the center of the entity belongs to
    const auto center = entity.geometry().center();
    std::vector< size_t > whichPartition(dimDomain, 0);
    const auto& ll = *lowerLeft_;
    const auto& ur = *upperRight_;
    const auto& ne = *numElements_;
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      // for points that are on upperRight_[d], this selects one partition too much
      // so we need to cap this
      whichPartition[dd] = std::min(size_t(std::floor(ne[dd]*((center[dd] - ll[dd])/(ur[dd] - ll[dd])))),
                                    ne[dd] - 1);
    }
    size_t subdomain = 0;
    if (dimDomain == 1)
      subdomain = whichPartition[0];
    else if (dimDomain == 2)
      subdomain = whichPartition[0] + whichPartition[1]*ne[0];
    else
      subdomain = whichPartition[0] + whichPartition[1]*ne[0] + whichPartition[2]*ne[1]*ne[0];
    // return the component that belongs to the subdomain
    return std::unique_ptr< Localfunction >(new Localfunction(entity, (*values_)[subdomain]));
  } // ... local_function(...)

private:
  std::shared_ptr< const std::vector< DomainFieldType > > lowerLeft_;
  std::shared_ptr< const std::vector< DomainFieldType > > upperRight_;
  std::shared_ptr< const std::vector< size_t > > numElements_;
  std::shared_ptr< const std::vector< RangeType > > values_;
  std::string name_;
}; // class Checkerboard

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#ifdef DUNE_STUFF_FUNCTIONS_TO_LIB
# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(etype, ddim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, 1) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, 2) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, 3)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, rdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 1) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 2) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 3)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_RANGEFIELDTYPES(etype, double, ddim, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_RANGEFIELDTYPES(etype, dftype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION(etype, dftype, ddim, double, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION(etype, dftype, ddim, long double, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION(etype, dftype, ddim, rftype, rdim, rcdim) \
  extern template class Dune::Stuff::Functions::Checkerboard< etype, dftype, ddim, rftype, rdim, rcdim >;

# if HAVE_DUNE_GRID

DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid3dEntityType, 3)

DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid3dEntityType, 3)

#   if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H

DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid3dEntityType, 3)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluCubeGrid3dEntityType, 3)

#   endif // HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
# endif // HAVE_DUNE_GRID

# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_RANGEFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE
#endif // DUNE_STUFF_FUNCTIONS_TO_LIB

#endif // DUNE_STUFF_FUNCTION_CHECKERBOARD_HH
<commit_msg>[functions.checkerboard] read values as scalar values (old behavior, reading of values as vectors lead to lexical_cast error)<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_FUNCTION_CHECKERBOARD_HH
#define DUNE_STUFF_FUNCTION_CHECKERBOARD_HH

#include <vector>
#include <cmath>
#include <memory>

#include <dune/common/exceptions.hh>
#include <dune/common/static_assert.hh>

#include <dune/stuff/common/configtree.hh>

#include "interfaces.hh"

namespace Dune {
namespace Stuff {
namespace Functions {

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class Checkerboard
  : public LocalizableFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
{
  typedef LocalizableFunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
    BaseType;
  typedef Checkerboard< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > ThisType;

  class Localfunction
    : public LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols >
  {
    typedef LocalfunctionInterface< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, rangeDimCols > BaseType;
  public:
    typedef typename BaseType::EntityType EntityType;

    typedef typename BaseType::DomainFieldType  DomainFieldType;
    static const unsigned int                   dimDomain = BaseType::dimDomain;
    typedef typename BaseType::DomainType       DomainType;

    typedef typename BaseType::RangeFieldType RangeFieldType;
    static const unsigned int                 dimRange = BaseType::dimRange;
    static const unsigned int                 dimRangeCols = BaseType::dimRangeCols;
    typedef typename BaseType::RangeType      RangeType;

    typedef typename BaseType::JacobianRangeType JacobianRangeType;

    Localfunction(const EntityType& ent,
                  const RangeType value)
      : BaseType(ent)
      , value_(value)
    {}

    Localfunction(const Localfunction& /*other*/) = delete;

    Localfunction& operator=(const Localfunction& /*other*/) = delete;

    virtual size_t order() const DS_OVERRIDE
    {
      return 0;
    }

    virtual void evaluate(const DomainType& xx, RangeType& ret) const DS_OVERRIDE
    {
      assert(this->is_a_valid_point(xx));
      ret = value_;
    }

    virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const DS_OVERRIDE
    {
      assert(this->is_a_valid_point(xx));
      ret *= RangeFieldType(0);
    }

  private:
    const RangeType value_;
  }; // class Localfunction

public:
  typedef typename BaseType::EntityType         EntityType;
  typedef typename BaseType::LocalfunctionType  LocalfunctionType;

  typedef typename BaseType::DomainFieldType  DomainFieldType;
  static const int                            dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType       DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const int                          dimRange = BaseType::dimRange;
  static const int                          dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType      RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

  static std::string static_id()
  {
    return BaseType::static_id() + ".checkerboard";
  }

  static Common::ConfigTree default_config(const std::string sub_name = "")
  {
    Common::ConfigTree config;
    config["lower_left"] = "[0.0; 0.0; 0.0]";
    config["upper_right"] = "[1.0; 1.0; 1.0]";
    config["num_elements"] = "[2; 2; 2]";
    config["values"] = "[1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0]";
    config["name"] = static_id();
    if (sub_name.empty())
      return config;
    else {
      Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Common::ConfigTree config = default_config(), const std::string sub_name = static_id())
  {
    // get correct config
    const Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    // extract needed data
      auto lower_left = cfg.get< std::vector< DomainFieldType > >("lower_left", dimDomain);
      auto upper_right = cfg.get< std::vector< DomainFieldType > >("upper_right", dimDomain);
      auto num_elements = cfg.get< std::vector< size_t > >("num_elements");
      size_t num_values = 1;
      for (size_t ii = 0; ii < num_elements.size(); ++ii)
        num_values *= num_elements[ii];
      auto values_rf = cfg.get< std::vector< RangeFieldType > >("values", num_values);
      std::vector< RangeType > values(values_rf.size());
      for (size_t ii = 0; ii < values_rf.size(); ++ii)
        values[ii] = RangeType(values_rf[ii]);
      auto nm = static_id();
      if (cfg.has_key("name"))
        nm = cfg.get< std::string >("name");
      return Common::make_unique< ThisType >(std::move(lower_left), std::move(upper_right), std::move(num_elements), std::move(values), nm);
  } // ... create(...)

  Checkerboard(std::vector< DomainFieldType >&& lowerLeft,
               std::vector< DomainFieldType >&& upperRight,
               std::vector< size_t >&& numElements,
               std::vector< RangeType >&& values,
               std::string nm = static_id())
    : lowerLeft_(new std::vector< DomainFieldType >(std::move(lowerLeft)))
    , upperRight_(new std::vector< DomainFieldType >(std::move(upperRight)))
    , numElements_(new std::vector< size_t >(std::move(numElements)))
    , values_(new std::vector< RangeType >(std::move(values)))
    , name_(nm)
  {
    // checks
    if (lowerLeft_->size() < dimDomain)
      DUNE_THROW(Dune::RangeError,
                 "lowerLeft too small (is " << lowerLeft_->size() << ", should be " << dimDomain << ")");
    if (upperRight_->size() < dimDomain)
      DUNE_THROW(Dune::RangeError,
                 "upperRight too small (is " << upperRight_->size() << ", should be " << dimDomain << ")");
    if (numElements_->size() < dimDomain)
      DUNE_THROW(Dune::RangeError,
                 "numElements too small (is " << numElements_->size() << ", should be " << dimDomain << ")");
    size_t totalSubdomains = 1;
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      const auto& ll = (*lowerLeft_)[dd];
      const auto& ur = (*upperRight_)[dd];
      const auto& ne = (*numElements_)[dd];
      if (!(ll < ur))
        DUNE_THROW(Dune::RangeError, "lowerLeft has to be elementwise smaller than upperRight!");
      totalSubdomains *= ne;
    }
    if (values_->size() < totalSubdomains)
      DUNE_THROW(Dune::RangeError,
                 "values too small (is " << values_->size() << ", should be " << totalSubdomains << ")");
  } // Checkerboard(...)

  Checkerboard(const ThisType& other)
    : lowerLeft_(other.lowerLeft_)
    , upperRight_(other.upperRight_)
    , numElements_(other.numElements_)
    , values_(other.values_)
    , name_(other.name_)
  {}

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      lowerLeft_ = other.lowerLeft_;
      upperRight_ = other.upperRight_;
      numElements_ = other.numElements_;
      values_ = other.values_;
      name_ = other.name_;
    }
    return *this;
  }

  virtual ThisType* copy() const DS_OVERRIDE
  {
    return new ThisType(*this);
  }

  virtual std::string name() const DS_OVERRIDE
  {
    return name_;
  }

  virtual std::unique_ptr< LocalfunctionType > local_function(const EntityType& entity) const DS_OVERRIDE
  {
    // decide on the subdomain the center of the entity belongs to
    const auto center = entity.geometry().center();
    std::vector< size_t > whichPartition(dimDomain, 0);
    const auto& ll = *lowerLeft_;
    const auto& ur = *upperRight_;
    const auto& ne = *numElements_;
    for (size_t dd = 0; dd < dimDomain; ++dd) {
      // for points that are on upperRight_[d], this selects one partition too much
      // so we need to cap this
      whichPartition[dd] = std::min(size_t(std::floor(ne[dd]*((center[dd] - ll[dd])/(ur[dd] - ll[dd])))),
                                    ne[dd] - 1);
    }
    size_t subdomain = 0;
    if (dimDomain == 1)
      subdomain = whichPartition[0];
    else if (dimDomain == 2)
      subdomain = whichPartition[0] + whichPartition[1]*ne[0];
    else
      subdomain = whichPartition[0] + whichPartition[1]*ne[0] + whichPartition[2]*ne[1]*ne[0];
    // return the component that belongs to the subdomain
    return std::unique_ptr< Localfunction >(new Localfunction(entity, (*values_)[subdomain]));
  } // ... local_function(...)

private:
  std::shared_ptr< const std::vector< DomainFieldType > > lowerLeft_;
  std::shared_ptr< const std::vector< DomainFieldType > > upperRight_;
  std::shared_ptr< const std::vector< size_t > > numElements_;
  std::shared_ptr< const std::vector< RangeType > > values_;
  std::string name_;
}; // class Checkerboard

} // namespace Functions
} // namespace Stuff
} // namespace Dune

#ifdef DUNE_STUFF_FUNCTIONS_TO_LIB
# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(etype, ddim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, 1) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, 2) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, 3)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS(etype, ddim, rdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 1) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 2) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, 3)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES(etype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_RANGEFIELDTYPES(etype, double, ddim, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_RANGEFIELDTYPES(etype, dftype, ddim, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION(etype, dftype, ddim, double, rdim, rcdim) \
  DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION(etype, dftype, ddim, long double, rdim, rcdim)

# define DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION(etype, dftype, ddim, rftype, rdim, rcdim) \
  extern template class Dune::Stuff::Functions::Checkerboard< etype, dftype, ddim, rftype, rdim, rcdim >;

# if HAVE_DUNE_GRID

DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesSGrid3dEntityType, 3)

DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid1dEntityType, 1)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesYaspGrid3dEntityType, 3)

#   if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H

DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid2dEntityType, 2)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluSimplexGrid3dEntityType, 3)
DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE(DuneStuffFunctionsInterfacesAluCubeGrid3dEntityType, 3)

#   endif // HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
# endif // HAVE_DUNE_GRID

# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LAST_EXPANSION
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_RANGEFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DOMAINFIELDTYPES
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGECOLS
# undef DUNE_STUFF_FUNCTIONS_CHECKERBOARD_LIST_DIMRANGE
#endif // DUNE_STUFF_FUNCTIONS_TO_LIB

#endif // DUNE_STUFF_FUNCTION_CHECKERBOARD_HH
<|endoftext|>


<commit_before>/*
 * File:   SDFLoader.cpp
 * Author: Benedikt Vogler
 *
 * Created on 8. Juli 2014, 18:52
 */

#include <algorithm>
#include "SDFloader.hpp"
#include "Camera.hpp"
#include "Box.hpp"
#include "Sphere.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Material.hpp"
#include "LightPoint.hpp"

using namespace std;

SDFLoader::SDFLoader() {
}

SDFLoader::SDFLoader(const SDFLoader& orig) {
}

SDFLoader::~SDFLoader() {
}

/**
 * Loads a scene file and reacts to the commands in it
 * @param scenefile the string to the file
 * @return
 */
Scene SDFLoader::load(std::string const& scenefile) {
    cout << "Loading file: " << scenefile << endl;
    Scene scene = Scene();

    std::map<std::string, Material> mMap;
    std::map<std::string, LightPoint> lMap;
    std::map<std::string, RenderObject*> roMap;

    string line;
    ifstream file(scenefile);
    stringstream ss;
    //file.open(scenefile, ios::in);
    if (file.is_open()) {
        while (getline (file,line)){//get line
            ss = stringstream(line);//fill the line into stringstream
            string tmpString;
            ss >> tmpString;
            //is first string define?
            if (tmpString=="define"){
                cout << "defininig: ";

                ss >> tmpString;
                if (tmpString=="material"){
                    cout << "a material: "<<endl;
                    //extract name
                    string name;
                    ss>>name;

                    //extract color
                    float red, green, blue;
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color ca(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cd(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cs(red, green, blue);
                    float m;
                    ss >> m;
                    Material mat(ca, cd, cs,m, name);
                    cout << "Material specs: "<<endl<<mat;
                    mMap[name]=mat;
                } else if (tmpString=="camera"){
                    string cameraname;
                    ss >> cameraname;
                    int fovX;
                    ss >> fovX;
                    scene.camera = Camera(cameraname,fovX);
                    cout << "camera: "<<cameraname<<"("<<fovX<<")"<<endl;
                } else if (tmpString=="light"){
                    string type;
                    ss>>type;

                    if (type=="diffuse") {
                        string name;
                        ss >> name;

                        glm::vec3 pos;
                        ss >> pos.x;
                        ss >> pos.y;
                        ss >> pos.z;

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color diff(red, green, blue);

                        LightPoint light = LightPoint(name, pos, diff);
                        cout << "light point: "<<name<<"("<<pos.x<<","<<pos.y<<","<<pos.z<<","<<diff<<")"<<endl;
                        lMap[name] = light;
                    }else if (type=="ambient") {
                        string lightname;
                        ss >> lightname;//name get's ignored

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color amb(red, green, blue);

                        scene.amb = amb;
                        cout << "ambient light "<<amb<<endl;
                    } else {
                        cout << "type not supported yet."<<endl;
                    }
                } else if (tmpString=="shape"){
                    string classname;
                    ss >> classname;
                    cout << "Shape \""<< classname << "\"."<<endl;
                    transform(classname.begin(), classname.end(),classname.begin(), ::toupper);

                    string name;
                    ss >> name;

                    RenderObject* rObject = nullptr;
                    if (classname=="BOX"){
                        int edge1x, edge1y, edge1z;
                        ss>> edge1x;
                        ss>> edge1y;
                        ss>> edge1z;

                        int edge2x, edge2y, edge2z;
                        ss>> edge2x;
                        ss>> edge2y;
                        ss>> edge2z;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Box(
                                name,
                                glm::vec3(edge1x, edge1y, edge1z),
                                glm::vec3(edge2x, edge2y, edge2z),
                                material
                                );
                    }else if (classname=="SPHERE") {
                        int posX, posY, posZ;
                        ss>> posX;
                        ss>> posY;
                        ss>> posZ;
                        float radius;
                        ss>>radius;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Sphere(
                                name,
                                glm::vec3(posX, posY, posZ),
                                radius,
                                material
                                );
                        cout << "Shape \""<< name << "\" aus Material "<<materialString<<" mit Radius: "<<radius<<"@("<<posX<<","<<posY<<","<<posZ<<")"<<endl;
                    }else cout << "ERROR: Shape \""<< classname << "\" not defined."<<endl;

                    if (rObject != nullptr)
                        roMap[name] = rObject;
                } else
                    cout << "object to define not implemented:"<<ss.str() <<endl;
            } else if (tmpString=="render"){
                ss >> scene.camname;
                ss >> scene.outputFile;
                ss >> scene.resX;
                ss >> scene.resY;
                //set default if not set
                if (scene.resX<=0) scene.resX=480;
                if (scene.resY<=0) scene.resY=320;
                cout << "Scene should be rendered from "<< scene.camname << " at resolution "<<scene.resX<<"x"<< scene.resY<< " to "<<scene.outputFile<<endl;
            } else if (tmpString=="#"){
                cout << line << endl;//just print comment lines
            } else
                cout << "Line not supported:"<<line <<endl;
        }
        file.close();
    }else cout << "Unable to open file";

    //save collected data in scene
    scene.materials = mMap;
    scene.renderObjects = roMap;
    scene.lights = lMap;
    return scene;
}<commit_msg>improved debugging output<commit_after>/*
 * File:   SDFLoader.cpp
 * Author: Benedikt Vogler
 *
 * Created on 8. Juli 2014, 18:52
 */

#include <algorithm>
#include "SDFloader.hpp"
#include "Camera.hpp"
#include "Box.hpp"
#include "Sphere.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Material.hpp"
#include "LightPoint.hpp"

using namespace std;

SDFLoader::SDFLoader() {
}

SDFLoader::SDFLoader(const SDFLoader& orig) {
}

SDFLoader::~SDFLoader() {
}

/**
 * Loads a scene file and reacts to the commands in it
 * @param scenefile the string to the file
 * @return
 */
Scene SDFLoader::load(std::string const& scenefile) {
    cout << "Loading file: " << scenefile << endl;
    Scene scene = Scene();

    std::map<std::string, Material> mMap;
    std::map<std::string, LightPoint> lMap;
    std::map<std::string, RenderObject*> roMap;

    string line;
    ifstream file(scenefile);
    stringstream ss;
    //file.open(scenefile, ios::in);
    if (file.is_open()) {
        while (getline (file,line)){//get line
            ss = stringstream(line);//fill the line into stringstream
            string tmpString;
            ss >> tmpString;
            //is first string define?
            if (tmpString=="define"){
                cout << "defininig: ";

                ss >> tmpString;
                if (tmpString=="material"){
                    cout << "a material: "<<endl;
                    //extract name
                    string name;
                    ss>>name;

                    //extract color
                    float red, green, blue;
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color ca(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cd(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cs(red, green, blue);
                    float m;
                    ss >> m;
                    Material mat(ca, cd, cs,m, name);
                    cout << "Material specs: "<<endl<<mat;
                    mMap[name]=mat;
                } else if (tmpString=="camera"){
                    string cameraname;
                    ss >> cameraname;
                    int fovX;
                    ss >> fovX;
                    scene.camera = Camera(cameraname,fovX);
                    cout << "camera: "<<cameraname<<"("<<fovX<<")"<<endl;
                } else if (tmpString=="light"){
                    string type;
                    ss>>type;

                    if (type=="diffuse") {
                        string name;
                        ss >> name;

                        glm::vec3 pos;
                        ss >> pos.x;
                        ss >> pos.y;
                        ss >> pos.z;

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color diff(red, green, blue);

                        LightPoint light = LightPoint(name, pos, diff);
                        cout << "light point: "<<name<<"("<<pos.x<<","<<pos.y<<","<<pos.z<<","<<diff<<")"<<endl;
                        lMap[name] = light;
                    }else if (type=="ambient") {
                        string lightname;
                        ss >> lightname;//name get's ignored

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color amb(red, green, blue);

                        scene.amb = amb;
                        cout << "ambient light "<<amb<<endl;
                    } else {
                        cout << "type not supported yet."<<endl;
                    }
                } else if (tmpString=="shape"){
                    string classname;
                    ss >> classname;
                    cout << "Shape \""<< classname << "\"."<<endl;
                    transform(classname.begin(), classname.end(),classname.begin(), ::toupper);

                    string name;
                    ss >> name;

                    RenderObject* rObject = nullptr;
                    if (classname=="BOX"){
                        int edge1x, edge1y, edge1z;
                        ss>> edge1x;
                        ss>> edge1y;
                        ss>> edge1z;

                        int edge2x, edge2y, edge2z;
                        ss>> edge2x;
                        ss>> edge2y;
                        ss>> edge2z;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Box(
                                name,
                                glm::vec3(edge1x, edge1y, edge1z),
                                glm::vec3(edge2x, edge2y, edge2z),
                                material
                                );
                    }else if (classname=="SPHERE") {
                        int posX, posY, posZ;
                        ss>> posX;
                        ss>> posY;
                        ss>> posZ;
                        float radius;
                        ss>>radius;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Sphere(
                                name,
                                glm::vec3(posX, posY, posZ),
                                radius,
                                material
                                );
                        cout << "Shape \""<< name << "\" aus Material "<<material<<" mit Radius: "<<radius<<"@("<<posX<<","<<posY<<","<<posZ<<")"<<endl;
                    }else cout << "ERROR: Shape \""<< classname << "\" not defined."<<endl;

                    if (rObject != nullptr)
                        roMap[name] = rObject;
                } else
                    cout << "object to define not implemented:"<<ss.str() <<endl;
            } else if (tmpString=="render"){
                ss >> scene.camname;
                ss >> scene.outputFile;
                ss >> scene.resX;
                ss >> scene.resY;
                //set default if not set
                if (scene.resX<=0) scene.resX=480;
                if (scene.resY<=0) scene.resY=320;
                cout << "Scene should be rendered from "<< scene.camname << " at resolution "<<scene.resX<<"x"<< scene.resY<< " to "<<scene.outputFile<<endl;
            } else if (tmpString=="#"){
                cout << line << endl;//just print comment lines
            } else
                cout << "Line not supported:"<<line <<endl;
        }
        file.close();
    }else cout << "Unable to open file";

    //save collected data in scene
    scene.materials = mMap;
    scene.renderObjects = roMap;
    scene.lights = lMap;
    return scene;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: impoct.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-24 10:00:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SV_IMPOCT_HXX
#define _SV_IMPOCT_HXX

#ifndef _SV_OCTREE_HXX
#include <vcl/octree.hxx>
#endif

// ----------------
// - ImpErrorQuad -
// ----------------

class ImpErrorQuad
{
    long                    nRed;
    long                    nGreen;
    long                    nBlue;
    long                    nReserved;

public:

    inline                  ImpErrorQuad() {}
    inline                  ImpErrorQuad( const BitmapColor& rColor ) :
                                nRed    ( (long) rColor.GetRed() << 5L ),
                                nGreen  ( (long) rColor.GetGreen() << 5L ),
                                nBlue   ( (long) rColor.GetBlue() << 5L ) {}

    inline void             operator=( const BitmapColor& rColor );
    inline ImpErrorQuad&    operator-=( const BitmapColor& rColor );

    inline void             ImplAddColorError1( const ImpErrorQuad& rErrQuad );
    inline void             ImplAddColorError3( const ImpErrorQuad& rErrQuad );
    inline void             ImplAddColorError5( const ImpErrorQuad& rErrQuad );
    inline void             ImplAddColorError7( const ImpErrorQuad& rErrQuad );

    inline BitmapColor      ImplGetColor();
};

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

inline void ImpErrorQuad::operator=( const BitmapColor& rColor )
{
    nRed = (long) rColor.GetRed() << 5L;
    nGreen = (long) rColor.GetGreen() << 5L;
    nBlue = (long) rColor.GetBlue() << 5L;
}

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

inline ImpErrorQuad& ImpErrorQuad::operator-=( const BitmapColor& rColor )
{
    nRed -= ( (long) rColor.GetRed() << 5L );
    nGreen -= ( (long) rColor.GetGreen() << 5L );
    nBlue -= ( (long) rColor.GetBlue() << 5L );

    return *this;
}

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

inline void ImpErrorQuad::ImplAddColorError1( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed >> 4L );
    nGreen += ( rErrQuad.nGreen >> 4L );
    nBlue += ( rErrQuad.nBlue >> 4L );
}

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

inline void ImpErrorQuad::ImplAddColorError3( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed * 3L >> 4L );
    nGreen += ( rErrQuad.nGreen * 3L >> 4L );
    nBlue += ( rErrQuad.nBlue * 3L >> 4L );
}

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

inline void ImpErrorQuad::ImplAddColorError5( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed * 5L >> 4L );
    nGreen += ( rErrQuad.nGreen * 5L >> 4L );
    nBlue += ( rErrQuad.nBlue * 5L >> 4L );
}

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

inline void ImpErrorQuad::ImplAddColorError7( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed * 7L >> 4L );
    nGreen += ( rErrQuad.nGreen * 7L >> 4L );
    nBlue += ( rErrQuad.nBlue *7L >> 4L );
}

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

inline BitmapColor ImpErrorQuad::ImplGetColor()
{
    return BitmapColor( (BYTE) ( ( nRed < 0L ? 0L : nRed > 8160L ? 8160L : nRed ) >> 5L ),
                        (BYTE) ( ( nGreen < 0L ? 0L : nGreen > 8160L ? 8160L : nGreen ) >> 5L ),
                        (BYTE) ( ( nBlue < 0L ? 0L : nBlue > 8160L ? 8160L : nBlue ) >> 5L ) );
}

// -------------
// - NodeCache -
// -------------

class ImpNodeCache
{
    OctreeNode*         pActNode;
    ULONG               nNew;
    ULONG               nDelete;
    ULONG               nGet;
    ULONG               nRelease;

public:

                        ImpNodeCache( const ULONG nInitSize );
                        ~ImpNodeCache();

    inline OctreeNode*  ImplGetFreeNode();
    inline void         ImplReleaseNode( OctreeNode* pNode );
};

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

inline OctreeNode* ImpNodeCache::ImplGetFreeNode()
{
    OctreeNode* pNode;

    if ( !pActNode )
    {
        pActNode = new NODE;
        pActNode->pNextInCache = NULL;
    }

    pNode = pActNode;
    pActNode = pNode->pNextInCache;
    memset( pNode, 0, sizeof( NODE ) );

    return pNode;
}

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

inline void ImpNodeCache::ImplReleaseNode( OctreeNode* pNode )
{
    pNode->pNextInCache = pActNode;
    pActNode = pNode;
}

#endif // _SV_IMPOCT_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.2.224); FILE MERGED 2008/04/01 13:01:11 thb 1.2.224.2: #i85898# Stripping all external header guards 2008/03/28 15:44:13 rt 1.2.224.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: impoct.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SV_IMPOCT_HXX
#define _SV_IMPOCT_HXX

#include <vcl/octree.hxx>

// ----------------
// - ImpErrorQuad -
// ----------------

class ImpErrorQuad
{
    long                    nRed;
    long                    nGreen;
    long                    nBlue;
    long                    nReserved;

public:

    inline                  ImpErrorQuad() {}
    inline                  ImpErrorQuad( const BitmapColor& rColor ) :
                                nRed    ( (long) rColor.GetRed() << 5L ),
                                nGreen  ( (long) rColor.GetGreen() << 5L ),
                                nBlue   ( (long) rColor.GetBlue() << 5L ) {}

    inline void             operator=( const BitmapColor& rColor );
    inline ImpErrorQuad&    operator-=( const BitmapColor& rColor );

    inline void             ImplAddColorError1( const ImpErrorQuad& rErrQuad );
    inline void             ImplAddColorError3( const ImpErrorQuad& rErrQuad );
    inline void             ImplAddColorError5( const ImpErrorQuad& rErrQuad );
    inline void             ImplAddColorError7( const ImpErrorQuad& rErrQuad );

    inline BitmapColor      ImplGetColor();
};

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

inline void ImpErrorQuad::operator=( const BitmapColor& rColor )
{
    nRed = (long) rColor.GetRed() << 5L;
    nGreen = (long) rColor.GetGreen() << 5L;
    nBlue = (long) rColor.GetBlue() << 5L;
}

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

inline ImpErrorQuad& ImpErrorQuad::operator-=( const BitmapColor& rColor )
{
    nRed -= ( (long) rColor.GetRed() << 5L );
    nGreen -= ( (long) rColor.GetGreen() << 5L );
    nBlue -= ( (long) rColor.GetBlue() << 5L );

    return *this;
}

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

inline void ImpErrorQuad::ImplAddColorError1( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed >> 4L );
    nGreen += ( rErrQuad.nGreen >> 4L );
    nBlue += ( rErrQuad.nBlue >> 4L );
}

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

inline void ImpErrorQuad::ImplAddColorError3( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed * 3L >> 4L );
    nGreen += ( rErrQuad.nGreen * 3L >> 4L );
    nBlue += ( rErrQuad.nBlue * 3L >> 4L );
}

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

inline void ImpErrorQuad::ImplAddColorError5( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed * 5L >> 4L );
    nGreen += ( rErrQuad.nGreen * 5L >> 4L );
    nBlue += ( rErrQuad.nBlue * 5L >> 4L );
}

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

inline void ImpErrorQuad::ImplAddColorError7( const ImpErrorQuad& rErrQuad )
{
    nRed += ( rErrQuad.nRed * 7L >> 4L );
    nGreen += ( rErrQuad.nGreen * 7L >> 4L );
    nBlue += ( rErrQuad.nBlue *7L >> 4L );
}

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

inline BitmapColor ImpErrorQuad::ImplGetColor()
{
    return BitmapColor( (BYTE) ( ( nRed < 0L ? 0L : nRed > 8160L ? 8160L : nRed ) >> 5L ),
                        (BYTE) ( ( nGreen < 0L ? 0L : nGreen > 8160L ? 8160L : nGreen ) >> 5L ),
                        (BYTE) ( ( nBlue < 0L ? 0L : nBlue > 8160L ? 8160L : nBlue ) >> 5L ) );
}

// -------------
// - NodeCache -
// -------------

class ImpNodeCache
{
    OctreeNode*         pActNode;
    ULONG               nNew;
    ULONG               nDelete;
    ULONG               nGet;
    ULONG               nRelease;

public:

                        ImpNodeCache( const ULONG nInitSize );
                        ~ImpNodeCache();

    inline OctreeNode*  ImplGetFreeNode();
    inline void         ImplReleaseNode( OctreeNode* pNode );
};

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

inline OctreeNode* ImpNodeCache::ImplGetFreeNode()
{
    OctreeNode* pNode;

    if ( !pActNode )
    {
        pActNode = new NODE;
        pActNode->pNextInCache = NULL;
    }

    pNode = pActNode;
    pActNode = pNode->pNextInCache;
    memset( pNode, 0, sizeof( NODE ) );

    return pNode;
}

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

inline void ImpNodeCache::ImplReleaseNode( OctreeNode* pNode )
{
    pNode->pNextInCache = pActNode;
    pActNode = pNode;
}

#endif // _SV_IMPOCT_HXX
<|endoftext|>


<commit_before><commit_msg>document VclContainer a bit<commit_after><|endoftext|>


<commit_before>#ifndef CXX_OBJECT_HXX
# define CXX_OBJECT_HXX

# include <boost/bind.hpp>

# include <object/atom.hh>
# include <object/primitive-class.hh>
# include <object/string-class.hh>
# include <object/object-class.hh>
# include <object/primitives.hh>

namespace object
{
  template <typename T>
  bool CxxObject::add(const std::string& name, rObject& tgt)
  {
    initializers_get().push_back(new TypeInitializer<T>(name, tgt));
    return true;
  }

  template <typename T>
  CxxObject::TypeInitializer<T>::TypeInitializer(const std::string& name,
                                                 rObject& tgt)
    : Initializer(tgt), name_(name)
  {}

  namespace
  {
    template <typename T>
    rObject cxx_object_clone(runner::Runner&, objects_type args)
    {
      CHECK_ARG_COUNT(1);
      rObject tgt = args[0];
      rObject res;
      if (tgt->is_a<T>())
        res = new T(tgt->as<T>());
      else
        res = new T();
      return res;
    }

    template <typename T>
    rObject cxx_object_id(runner::Runner&, objects_type args)
    {
      CHECK_ARG_COUNT(1);
      return args[0];
    }
  }

  template <typename T>
  void
  CxxObject::TypeInitializer<T>::create()
  {
    res_ = new Object();
  }

  template <typename T>
  rObject
  CxxObject::TypeInitializer<T>::make_class()
  {
    res_->proto_add(object_class);
    res_->slot_set(SYMBOL(protoName), new String(name_));
    res_->slot_set(SYMBOL(clone),
                   rPrimitive(new Primitive(boost::bind(cxx_object_clone<T>,
                                                        _1, _2))));
    Binder<T> b(res_);
    T::initialize(b);

    libport::Symbol conversion =
      libport::Symbol(std::string("as") + name_.name_get());
    if (!res_->slot_locate(conversion, 0))
      res_->slot_set(conversion,
                     rPrimitive(new Primitive(boost::bind(cxx_object_id<T>,
                                                          _1, _2))));
    return res_;
  }

  template <typename T>
  libport::Symbol
  CxxObject::TypeInitializer<T>::name()
  {
    return name_;
  }

  // BINDER

  template <typename T>
  CxxObject::Binder<T>::Binder(rObject tgt)
    : tgt_(tgt)
  {}

  namespace
  {

# define PRINT_true(X) X
# define PRINT_false(X)
# define PRINT_truetrue(X) X
# define PRINT_falsetrue(X)
# define PRINT_truefalse(X)
# define PRINT_falsefalse(X)
# define NPRINT_true(X)
# define NPRINT_false(X) X

# define WHEN(Cond, X) PRINT_##Cond(X)
# define WHEN_NOT(Cond, X) NPRINT_##Cond(X)

# define IF(Cond, Then, Else) WHEN(Cond, Then) WHEN_NOT(Cond, Else)

# define COMMA_ ,
# define COMMA(Cond) PRINT_##Cond(COMMA_)

# define COMMA2(Cond1, Cond2) PRINT_##Cond1##Cond2(COMMA_)

# define MET(Met, Name, Ret, Run, Arg1, Arg2, Arg3)     \
    IF(Ret, libport::shared_ptr<R>, void)               \
    (WHEN(Met, T::)*Name)(                              \
      WHEN(Run, runner::Runner&) COMMA2(Run, Arg1)      \
      WHEN(Arg1, libport::shared_ptr<A1>)               \
      COMMA(Arg2) WHEN(Arg2, libport::shared_ptr<A2>)   \
      COMMA(Arg3) WHEN(Arg3, libport::shared_ptr<A3>)   \
      )

#define GET_ARG(Met, N)                                                 \
    type_check<A##N>(args[N WHEN_NOT(Met, - 1)], name.name_get());     \
    libport::shared_ptr<A##N> a##N =                                   \
      args[N WHEN_NOT(Met, - 1)].unsafe_cast<A##N>();                  \
    assert(a##N);

#define FETCH_TGT()                                                     \
    type_check<T>(args[0], name.name_get());                            \
    libport::shared_ptr<T> tgt = args[0].unsafe_cast<T>();

#define PRIMITIVE(Met, Ret, ArgsC, Run, Arg1, Arg2, Arg3)               \
    template <typename T                                                \
              COMMA(Ret) WHEN(Ret, typename R)                          \
      COMMA(Arg1) WHEN(Arg1, typename A1)                               \
      COMMA(Arg2) WHEN(Arg2, typename A2)                               \
      COMMA(Arg3) WHEN(Arg3, typename A3)                               \
      >                                                                 \
    struct primitive<T, MET(Met, , Ret, Run, Arg1, Arg2, Arg3)>         \
    {                                                                   \
        static rObject make(                                            \
          MET(Met, method, Ret, Run, Arg1, Arg2, Arg3),                 \
          const libport::Symbol& IF(Met, name, WHEN(Arg1, name)),       \
          runner::Runner& WHEN(Run, r),                                 \
          objects_type args)                                            \
        {                                                               \
	  (void)args;							\
          assert(args.size() ==                                         \
                 ArgsC IF(Met, + 1, WHEN_NOT(Arg1, + 1)));              \
          WHEN(Met, FETCH_TGT());                                       \
          WHEN(Arg1, GET_ARG(Met, 1))                                   \
            WHEN(Arg2, GET_ARG(Met, 2))                                 \
            WHEN(Arg3, GET_ARG(Met, 3))                                 \
            WHEN(Ret, return)                                           \
            (WHEN(Met, tgt.get()->*)method)(                            \
              WHEN(Run, r) COMMA2(Run, Arg1)                            \
              WHEN(Arg1, a1)                                            \
              COMMA(Arg2) WHEN(Arg2, a2)                                \
              COMMA(Arg3) WHEN(Arg3, a3)                                \
              );                                                        \
          return void_class;                                            \
        }                                                               \
      }

#define LIST_MET(Name, Met, Ret, Run)                                  \
    IF(Ret, R, void)                                                   \
    (WHEN(Met, T::)*Name)(WHEN(Run, runner::Runner&) COMMA(Run)        \
                          objects_type)                                \

#define LIST_PRIMITIVE(Met, Ret, Run)                                   \
    template <typename T                                                \
              COMMA(Ret) WHEN(Ret, typename R)                          \
      >                                                                 \
    struct primitive<T, LIST_MET(, Met, Ret, Run)>                      \
    {                                                                   \
        static rObject make(                                            \
          LIST_MET(method, Met, Ret, Run),                              \
          const libport::Symbol& name,                                  \
          runner::Runner& WHEN(Run, r),                                 \
          objects_type args)                                            \
        {                                                               \
          WHEN(Met, FETCH_TGT());                                       \
          WHEN(Met, args.pop_front());                                  \
          WHEN(Ret, return)                                             \
            (WHEN(Met, tgt.get()->*)method)(                            \
              WHEN(Run, r) COMMA(Run)                                   \
              args                                                      \
              );                                                        \
          return void_class;                                            \
        }                                                               \
      }

    template <typename T, typename M>
    struct primitive
    {
    };

    /* Python for these:
for met in ('true', 'false'):
    for ret in ('true', 'false'):
        for run in ('true', 'false'):
            print "    LIST_PRIMITIVE(%s, %s, %s);" % (met, ret, run)
     */
    LIST_PRIMITIVE(true, true, true);
    LIST_PRIMITIVE(true, true, false);
    LIST_PRIMITIVE(true, false, true);
    LIST_PRIMITIVE(true, false, false);
    LIST_PRIMITIVE(false, true, true);
    LIST_PRIMITIVE(false, true, false);
    LIST_PRIMITIVE(false, false, true);
    LIST_PRIMITIVE(false, false, false);

    /* Python for these:
max = 3
for ret in ('true', 'false'):
    for run in ('true', 'false'):
        for nargs in range(max + 1):
            for macro in ('PRIMITIVE ', 'PRIMITIVEF'):
                print "    %s(%s, %i, %s" % (macro, ret, nargs, run),
                for i in range(max):
                    print ", %s" % str(i < nargs).lower(),
                print ");"
    */
    PRIMITIVE(true , true, 0, true , false , false , false );
    PRIMITIVE(true , true, 1, true , true , false , false );
    PRIMITIVE(true , true, 2, true , true , true , false );
    PRIMITIVE(true , true, 3, true , true , true , true );
    PRIMITIVE(true , true, 0, false , false , false , false );
    PRIMITIVE(true , true, 1, false , true , false , false );
    PRIMITIVE(true , true, 2, false , true , true , false );
    PRIMITIVE(true , true, 3, false , true , true , true );
    PRIMITIVE(true , false, 0, true , false , false , false );
    PRIMITIVE(true , false, 1, true , true , false , false );
    PRIMITIVE(true , false, 2, true , true , true , false );
    PRIMITIVE(true , false, 3, true , true , true , true );
    PRIMITIVE(true , false, 0, false , false , false , false );
    PRIMITIVE(true , false, 1, false , true , false , false );
    PRIMITIVE(true , false, 2, false , true , true , false );
    PRIMITIVE(true , false, 3, false , true , true , true );
    PRIMITIVE(false, true, 0, true , false , false , false );
    PRIMITIVE(false, true, 1, true , true , false , false );
    PRIMITIVE(false, true, 2, true , true , true , false );
    PRIMITIVE(false, true, 3, true , true , true , true );
    PRIMITIVE(false, true, 0, false , false , false , false );
    PRIMITIVE(false, true, 1, false , true , false , false );
    PRIMITIVE(false, true, 2, false , true , true , false );
    PRIMITIVE(false, true, 3, false , true , true , true );
    PRIMITIVE(false, false, 0, true , false , false , false );
    PRIMITIVE(false, false, 1, true , true , false , false );
    PRIMITIVE(false, false, 2, true , true , true , false );
    PRIMITIVE(false, false, 3, true , true , true , true );
    PRIMITIVE(false, false, 0, false , false , false , false );
    PRIMITIVE(false, false, 1, false , true , false , false );
    PRIMITIVE(false, false, 2, false , true , true , false );
    PRIMITIVE(false, false, 3, false , true , true , true );
  }

  template <typename T>
  template <typename M>
  void CxxObject::Binder<T>::operator()(const libport::Symbol& name,
                                        M method)
  {
    // If make is unfound here, you passed an unsupported pointer type
    // to the binder.
    rObject p =
      new Primitive(boost::bind(primitive<T, M>::make,
                                method, name, _1, _2));
    tgt_->slot_set(name, p);
  }

  template <typename T>
  inline void
  type_check(rObject o, const std::string& fun)
  {
    libport::shared_ptr<CxxObject> co = o.unsafe_cast<CxxObject>();
     // FIXME: I can't fill all the source type for now since some old
     // atoms don't define type_name for now
    if (!co)
      throw object::WrongArgumentType(T::type_name, "Object", fun);
    else if (!o->is_a<T>())
      throw object::WrongArgumentType(T::type_name, co->type_name_get(), fun);
  }

  template <>
  inline void
  type_check<Object>(rObject, const std::string&)
  {}

  template <>
  inline void
  type_check<List>(rObject, const std::string&)
  {}

}

#endif
<commit_msg>Force "name" to be used.<commit_after>#ifndef CXX_OBJECT_HXX
# define CXX_OBJECT_HXX

# include <boost/bind.hpp>

# include <object/atom.hh>
# include <object/primitive-class.hh>
# include <object/string-class.hh>
# include <object/object-class.hh>
# include <object/primitives.hh>

namespace object
{
  template <typename T>
  bool CxxObject::add(const std::string& name, rObject& tgt)
  {
    initializers_get().push_back(new TypeInitializer<T>(name, tgt));
    return true;
  }

  template <typename T>
  CxxObject::TypeInitializer<T>::TypeInitializer(const std::string& name,
                                                 rObject& tgt)
    : Initializer(tgt), name_(name)
  {}

  namespace
  {
    template <typename T>
    rObject cxx_object_clone(runner::Runner&, objects_type args)
    {
      CHECK_ARG_COUNT(1);
      rObject tgt = args[0];
      rObject res;
      if (tgt->is_a<T>())
        res = new T(tgt->as<T>());
      else
        res = new T();
      return res;
    }

    template <typename T>
    rObject cxx_object_id(runner::Runner&, objects_type args)
    {
      CHECK_ARG_COUNT(1);
      return args[0];
    }
  }

  template <typename T>
  void
  CxxObject::TypeInitializer<T>::create()
  {
    res_ = new Object();
  }

  template <typename T>
  rObject
  CxxObject::TypeInitializer<T>::make_class()
  {
    res_->proto_add(object_class);
    res_->slot_set(SYMBOL(protoName), new String(name_));
    res_->slot_set(SYMBOL(clone),
                   rPrimitive(new Primitive(boost::bind(cxx_object_clone<T>,
                                                        _1, _2))));
    Binder<T> b(res_);
    T::initialize(b);

    libport::Symbol conversion =
      libport::Symbol(std::string("as") + name_.name_get());
    if (!res_->slot_locate(conversion, 0))
      res_->slot_set(conversion,
                     rPrimitive(new Primitive(boost::bind(cxx_object_id<T>,
                                                          _1, _2))));
    return res_;
  }

  template <typename T>
  libport::Symbol
  CxxObject::TypeInitializer<T>::name()
  {
    return name_;
  }

  // BINDER

  template <typename T>
  CxxObject::Binder<T>::Binder(rObject tgt)
    : tgt_(tgt)
  {}

  namespace
  {

# define PRINT_true(X) X
# define PRINT_false(X)
# define PRINT_truetrue(X) X
# define PRINT_falsetrue(X)
# define PRINT_truefalse(X)
# define PRINT_falsefalse(X)
# define NPRINT_true(X)
# define NPRINT_false(X) X

# define WHEN(Cond, X) PRINT_##Cond(X)
# define WHEN_NOT(Cond, X) NPRINT_##Cond(X)

# define IF(Cond, Then, Else) WHEN(Cond, Then) WHEN_NOT(Cond, Else)

# define COMMA_ ,
# define COMMA(Cond) PRINT_##Cond(COMMA_)

# define COMMA2(Cond1, Cond2) PRINT_##Cond1##Cond2(COMMA_)

# define MET(Met, Name, Ret, Run, Arg1, Arg2, Arg3)     \
    IF(Ret, libport::shared_ptr<R>, void)               \
    (WHEN(Met, T::)*Name)(                              \
      WHEN(Run, runner::Runner&) COMMA2(Run, Arg1)      \
      WHEN(Arg1, libport::shared_ptr<A1>)               \
      COMMA(Arg2) WHEN(Arg2, libport::shared_ptr<A2>)   \
      COMMA(Arg3) WHEN(Arg3, libport::shared_ptr<A3>)   \
      )

#define GET_ARG(Met, N)                                                 \
    type_check<A##N>(args[N WHEN_NOT(Met, - 1)], name.name_get());     \
    libport::shared_ptr<A##N> a##N =                                   \
      args[N WHEN_NOT(Met, - 1)].unsafe_cast<A##N>();                  \
    assert(a##N);

#define FETCH_TGT()                                                     \
    type_check<T>(args[0], name.name_get());                            \
    libport::shared_ptr<T> tgt = args[0].unsafe_cast<T>();

#define PRIMITIVE(Met, Ret, ArgsC, Run, Arg1, Arg2, Arg3)               \
    template <typename T                                                \
              COMMA(Ret) WHEN(Ret, typename R)                          \
      COMMA(Arg1) WHEN(Arg1, typename A1)                               \
      COMMA(Arg2) WHEN(Arg2, typename A2)                               \
      COMMA(Arg3) WHEN(Arg3, typename A3)                               \
      >                                                                 \
    struct primitive<T, MET(Met, , Ret, Run, Arg1, Arg2, Arg3)>         \
    {                                                                   \
        static rObject make(                                            \
          MET(Met, method, Ret, Run, Arg1, Arg2, Arg3),                 \
          const libport::Symbol& IF(Met, name, WHEN(Arg1, name)),       \
          runner::Runner& WHEN(Run, r),                                 \
          objects_type args)                                            \
        {                                                               \
	  (void)args;							\
          assert(args.size() ==                                         \
                 ArgsC IF(Met, + 1, WHEN_NOT(Arg1, + 1)));              \
          WHEN(Met, FETCH_TGT());                                       \
          WHEN(Arg1, GET_ARG(Met, 1))                                   \
            WHEN(Arg2, GET_ARG(Met, 2))                                 \
            WHEN(Arg3, GET_ARG(Met, 3))                                 \
            WHEN(Ret, return)                                           \
            (WHEN(Met, tgt.get()->*)method)(                            \
              WHEN(Run, r) COMMA2(Run, Arg1)                            \
              WHEN(Arg1, a1)                                            \
              COMMA(Arg2) WHEN(Arg2, a2)                                \
              COMMA(Arg3) WHEN(Arg3, a3)                                \
              );                                                        \
          return void_class;                                            \
        }                                                               \
      }

#define LIST_MET(Name, Met, Ret, Run)                                  \
    IF(Ret, R, void)                                                   \
    (WHEN(Met, T::)*Name)(WHEN(Run, runner::Runner&) COMMA(Run)        \
                          objects_type)                                \

#define LIST_PRIMITIVE(Met, Ret, Run)                                   \
    template <typename T                                                \
              COMMA(Ret) WHEN(Ret, typename R)                          \
      >                                                                 \
    struct primitive<T, LIST_MET(, Met, Ret, Run)>                      \
    {                                                                   \
        static rObject make(                                            \
          LIST_MET(method, Met, Ret, Run),                              \
          const libport::Symbol& name,                                  \
          runner::Runner& WHEN(Run, r),                                 \
          objects_type args)                                            \
        {                                                               \
	  (void)name;                                                   \
          WHEN(Met, FETCH_TGT());                                       \
          WHEN(Met, args.pop_front());                                  \
          WHEN(Ret, return)                                             \
            (WHEN(Met, tgt.get()->*)method)(                            \
              WHEN(Run, r) COMMA(Run)                                   \
              args                                                      \
              );                                                        \
          return void_class;                                            \
        }                                                               \
      }

    template <typename T, typename M>
    struct primitive
    {
    };

    /* Python for these:
for met in ('true', 'false'):
    for ret in ('true', 'false'):
        for run in ('true', 'false'):
            print "    LIST_PRIMITIVE(%s, %s, %s);" % (met, ret, run)
     */
    LIST_PRIMITIVE(true, true, true);
    LIST_PRIMITIVE(true, true, false);
    LIST_PRIMITIVE(true, false, true);
    LIST_PRIMITIVE(true, false, false);
    LIST_PRIMITIVE(false, true, true);
    LIST_PRIMITIVE(false, true, false);
    LIST_PRIMITIVE(false, false, true);
    LIST_PRIMITIVE(false, false, false);

    /* Python for these:
max = 3
for ret in ('true', 'false'):
    for run in ('true', 'false'):
        for nargs in range(max + 1):
            for macro in ('PRIMITIVE ', 'PRIMITIVEF'):
                print "    %s(%s, %i, %s" % (macro, ret, nargs, run),
                for i in range(max):
                    print ", %s" % str(i < nargs).lower(),
                print ");"
    */
    PRIMITIVE(true , true, 0, true , false , false , false );
    PRIMITIVE(true , true, 1, true , true , false , false );
    PRIMITIVE(true , true, 2, true , true , true , false );
    PRIMITIVE(true , true, 3, true , true , true , true );
    PRIMITIVE(true , true, 0, false , false , false , false );
    PRIMITIVE(true , true, 1, false , true , false , false );
    PRIMITIVE(true , true, 2, false , true , true , false );
    PRIMITIVE(true , true, 3, false , true , true , true );
    PRIMITIVE(true , false, 0, true , false , false , false );
    PRIMITIVE(true , false, 1, true , true , false , false );
    PRIMITIVE(true , false, 2, true , true , true , false );
    PRIMITIVE(true , false, 3, true , true , true , true );
    PRIMITIVE(true , false, 0, false , false , false , false );
    PRIMITIVE(true , false, 1, false , true , false , false );
    PRIMITIVE(true , false, 2, false , true , true , false );
    PRIMITIVE(true , false, 3, false , true , true , true );
    PRIMITIVE(false, true, 0, true , false , false , false );
    PRIMITIVE(false, true, 1, true , true , false , false );
    PRIMITIVE(false, true, 2, true , true , true , false );
    PRIMITIVE(false, true, 3, true , true , true , true );
    PRIMITIVE(false, true, 0, false , false , false , false );
    PRIMITIVE(false, true, 1, false , true , false , false );
    PRIMITIVE(false, true, 2, false , true , true , false );
    PRIMITIVE(false, true, 3, false , true , true , true );
    PRIMITIVE(false, false, 0, true , false , false , false );
    PRIMITIVE(false, false, 1, true , true , false , false );
    PRIMITIVE(false, false, 2, true , true , true , false );
    PRIMITIVE(false, false, 3, true , true , true , true );
    PRIMITIVE(false, false, 0, false , false , false , false );
    PRIMITIVE(false, false, 1, false , true , false , false );
    PRIMITIVE(false, false, 2, false , true , true , false );
    PRIMITIVE(false, false, 3, false , true , true , true );
  }

  template <typename T>
  template <typename M>
  void CxxObject::Binder<T>::operator()(const libport::Symbol& name,
                                        M method)
  {
    // If make is unfound here, you passed an unsupported pointer type
    // to the binder.
    rObject p =
      new Primitive(boost::bind(primitive<T, M>::make,
                                method, name, _1, _2));
    tgt_->slot_set(name, p);
  }

  template <typename T>
  inline void
  type_check(rObject o, const std::string& fun)
  {
    libport::shared_ptr<CxxObject> co = o.unsafe_cast<CxxObject>();
     // FIXME: I can't fill all the source type for now since some old
     // atoms don't define type_name for now
    if (!co)
      throw object::WrongArgumentType(T::type_name, "Object", fun);
    else if (!o->is_a<T>())
      throw object::WrongArgumentType(T::type_name, co->type_name_get(), fun);
  }

  template <>
  inline void
  type_check<Object>(rObject, const std::string&)
  {}

  template <>
  inline void
  type_check<List>(rObject, const std::string&)
  {}

}

#endif
<|endoftext|>