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

#ifndef DUNE_GDT_SPACE_INTERFACE_HH
#define DUNE_GDT_SPACE_INTERFACE_HH

#include <memory>
#include <type_traits>

#include <dune/common/dynvector.hh>
#include <dune/common/fvector.hh>

#include <dune/grid/common/gridview.hh>
#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/common/float_cmp.hh>

#include "constraints.hh"

namespace Dune {
namespace GDT {

template <class Traits>
class SpaceInterface : protected Stuff::CRTPInterface<SpaceInterface<Traits>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  static const int polOrder = Traits::polOrder;
  typedef typename Traits::BackendType BackendType;
  typedef typename Traits::MapperType MapperType;
  typedef typename Traits::BaseFunctionSetType BaseFunctionSetType;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeFieldType RangeFieldType;
  static const unsigned int dimRange     = Traits::dimRange;
  static const unsigned int dimRangeCols = Traits::dimRangeCols;

private:
  static_assert(std::is_base_of<GridView<typename GridViewType::Traits>, GridViewType>::value,
                "GridViewType has to be derived from GridView!");

public:
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridViewType::dimension;
  typedef FieldVector<DomainFieldType, dimDomain> DomainType;

  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::Intersection IntersectionType;
  typedef Stuff::GridboundaryInterface<IntersectionType> BoundaryInfoType;
  typedef Dune::Stuff::LA::SparsityPatternDefault PatternType;

  static const bool needs_grid_view = Traits::needs_grid_view;

public:
  /**
   * \defgroup interface ´´These methods have to be implemented!''
   * @{
   **/

  const std::shared_ptr<const GridViewType>& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const BackendType& backend() const
  {
    CHECK_CRTP(this->as_imp(*this).backend());
    return this->as_imp(*this).backend();
  }

  const MapperType& mapper() const
  {
    CHECK_CRTP(this->as_imp(*this).mapper());
    return this->as_imp(*this).mapper();
  }

  BaseFunctionSetType base_function_set(const EntityType& entity) const
  {
    CHECK_CRTP(this->as_imp(*this).base_function_set(entity));
    return this->as_imp(*this).base_function_set(entity);
  }

  template <class ConstraintsType>
  void local_constraints(const EntityType& entity, ConstraintsType& ret) const
  {
    local_constraints(*this, entity, ret);
  }

  template <class ConstraintsType, class T>
  void local_constraints(const SpaceInterface<T>& ansatz_space, const EntityType& entity, ConstraintsType& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).local_constraints(ansatz_space, entity, ret));
    this->as_imp(*this).local_constraints(ansatz_space, entity, ret);
  }

  /**
   *  \brief  Computes the appropriate sparsity pattern.
   *  \note   This method can be implemented in a derived class by a forward to one of the methods provided by this
   * class, namely compute_volume_pattern(), compute_face_pattern() or compute_face_and_volume_pattern().
   */
  template <class G, class S>
  PatternType compute_pattern(const GridView<G>& local_grid_view, const SpaceInterface<S>& ansatz_space) const
  {
    CHECK_CRTP(this->as_imp(*this).compute_pattern(local_grid_view, ansatz_space));
    return this->as_imp(*this).compute_pattern(local_grid_view, ansatz_space);
  }
  /* @} */

  /**
   * \defgroup provided ´´These methods are provided by the interface for convenience.''
   * @{
   **/

  PatternType compute_pattern() const
  {
    return compute_pattern(*this);
  }

  template <class S>
  PatternType compute_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_pattern(*(grid_view()), ansatz_space);
  }

  template <class G>
  PatternType compute_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_pattern(local_grid_view, *this);
  }

  PatternType compute_volume_pattern() const
  {
    return compute_volume_pattern(*this);
  }

  template <class S>
  PatternType compute_volume_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_volume_pattern(*(grid_view()), ansatz_space);
  }

  template <class G>
  PatternType compute_volume_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_volume_pattern(local_grid_view, *this);
  }

  /**
   *  \brief  computes a sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class G, class S>
  PatternType compute_volume_pattern(const GridView<G>& local_grid_view, const SpaceInterface<S>& ansatz_space) const
  {
    PatternType pattern(mapper().size());
    // walk the grid view
    const auto entityItEnd = local_grid_view.template end<0>();
    for (auto entityIt = local_grid_view.template begin<0>(); entityIt != entityItEnd; ++entityIt) {
      const auto& entity = *entityIt;
      // get basefunctionsets
      const auto testBase   = base_function_set(entity);
      const auto ansatzBase = ansatz_space.base_function_set(entity);
      Dune::DynamicVector<size_t> globalRows(testBase.size(), 0);
      mapper().globalIndices(entity, globalRows);
      Dune::DynamicVector<size_t> globalCols(ansatzBase.size(), 0);
      ansatz_space.mapper().globalIndices(entity, globalCols);
      for (size_t ii = 0; ii < testBase.size(); ++ii) {
        auto& columns = pattern.inner(globalRows[ii]);
        for (size_t jj = 0; jj < ansatzBase.size(); ++jj) {
          columns.insert(globalCols[jj]);
        }
      }
    } // walk the grid view
    return pattern;
  } // ... compute_volume_pattern(...)

  PatternType compute_face_and_volume_pattern() const
  {
    return compute_face_and_volume_pattern(*(grid_view()), *this);
  }

  template <class G>
  PatternType compute_face_and_volume_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_face_and_volume_pattern(local_grid_view, *this);
  }

  template <class S>
  PatternType compute_face_and_volume_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_face_and_volume_pattern(*(grid_view()), ansatz_space);
  }

  /**
   *  \brief  computes a DG sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class G, class S>
  PatternType compute_face_and_volume_pattern(const GridView<G>& local_grid_view,
                                              const SpaceInterface<S>& ansatz_space) const
  {
    // prepare
    PatternType pattern(mapper().size());
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(ansatz_space.mapper().maxNumDofs(), 0);
    // walk the grid view
    const auto entity_it_end = local_grid_view.template end<0>();
    for (auto entity_it = local_grid_view.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity   = base_function_set(entity);
      const auto ansatz_base_entity = ansatz_space.base_function_set(entity);
      mapper().globalIndices(entity, global_rows);
      ansatz_space.mapper().globalIndices(entity, global_cols);
      // compute entity/entity
      for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
        auto& columns = pattern.inner(global_rows[ii]);
        for (size_t jj = 0; jj < ansatz_base_entity.size(); ++jj) {
          columns.insert(global_cols[jj]);
        }
      }
      // walk the intersections
      const auto intersection_it_end = local_grid_view.iend(entity);
      for (auto intersection_it = local_grid_view.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = ansatz_space.base_function_set(neighbour);
          ansatz_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid view
    return pattern;
  } // ... compute_face_and_volume_pattern(...)

  PatternType compute_face_pattern() const
  {
    return compute_face_pattern(*(grid_view()), *this);
  }

  template <class G>
  PatternType compute_face_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_face_pattern(local_grid_view, *this);
  }

  template <class S>
  PatternType compute_face_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_face_pattern(*(grid_view()), ansatz_space);
  }

  template <class G, class S>
  PatternType compute_face_pattern(const GridView<G>& local_grid_view, const SpaceInterface<S>& ansatz_space) const
  {
    // prepare
    PatternType pattern(mapper().size());
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(ansatz_space.mapper().maxNumDofs(), 0);
    // walk the grid view
    const auto entity_it_end = local_grid_view.template end<0>();
    for (auto entity_it = local_grid_view.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity = base_function_set(entity);
      mapper().globalIndices(entity, global_rows);
      // walk the intersections
      const auto intersection_it_end = local_grid_view.iend(entity);
      for (auto intersection_it = local_grid_view.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = ansatz_space.base_function_set(neighbour);
          ansatz_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid view
    return pattern;
  } // ... compute_face_pattern(...)

private:
  class BasisVisualization : public Dune::VTKFunction<GridViewType>
  {
    static_assert(dimRangeCols == 1, "Not implemented for matrixvalued spaces yet!");

  public:
    typedef typename BaseFunctionSetType::DomainType DomainType;
    typedef typename BaseFunctionSetType::RangeType RangeType;

    BasisVisualization(const derived_type& sp, const size_t ind, const std::string nm = "basis")
      : space_(sp)
      , index_(ind)
      , values_(space_.mapper().maxNumDofs(), RangeType(0))
      , name_(nm)
    {
      if (index_ >= space_.mapper().maxNumDofs())
        DUNE_THROW(Dune::RangeError,
                   "index has to be smaller than " << space_.mapper().maxNumDofs() << "(is " << index_ << ")!");
    }

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

    /** \defgroup vtk ´´Methods to comply with the Dune::VTKFunction interface.'' */
    /* @{ */
    virtual int ncomps() const
    {
      return dimRange;
    }

    virtual double evaluate(int component, const EntityType& entity, const DomainType& xx) const
    {
      const auto baseFunctionSet = space_.base_function_set(entity);
      if (component < 0)
        DUNE_THROW(Dune::RangeError, "component must not be negative (is " << component << ")!");
      if (component < int(baseFunctionSet.size())) {
        baseFunctionSet.evaluate(xx, values_);
        assert(component < int(values_.size()) && "This should not happen!");
        return values_[index_][component];
      } else if (component < int(space_.mapper().maxNumDofs()))
        return 0.0;
      else
        DUNE_THROW(Dune::RangeError,
                   "component has to be smaller than " << space_.mapper().maxNumDofs() << "(is " << component << ")!");
    }
    /* @} */

  private:
    const derived_type& space_;
    const size_t index_;
    mutable std::vector<RangeType> values_;
    const std::string name_;
  }; // class BasisVisualization

public:
  void visualize(const std::string filename_prefix = "") const
  {
    std::string filename = filename_prefix;
    if (filename.empty()) {
      filename = "dune.gdt.space";
    }
    VTKWriter<GridViewType> vtk_writer(*(grid_view()), Dune::VTK::nonconforming);
    for (size_t ii = 0; ii < mapper().maxNumDofs(); ++ii) {
      std::string number = "";
      if (ii == 1)
        number = "1st";
      else if (ii == 2)
        number = "2nd";
      else if (ii == 3)
        number = "3rd";
      else
        number                     = Stuff::Common::toString(ii) + "th";
      const auto iith_baseFunction = std::make_shared<BasisVisualization>(this->as_imp(*this), ii, number + " basis");
      vtk_writer.addVertexData(iith_baseFunction);
    }
    vtk_writer.write(filename);
  } // ... visualize(...)

  /* @} */

protected:
  mutable std::vector<typename BaseFunctionSetType::RangeType> tmp_basis_values_;
}; // class SpaceInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACE_INTERFACE_HH
<commit_msg>[space.interface] improve compute_volume_pattern() * use common index storage for all entities<commit_after>// This file is view of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACE_INTERFACE_HH
#define DUNE_GDT_SPACE_INTERFACE_HH

#include <memory>
#include <type_traits>

#include <dune/common/dynvector.hh>
#include <dune/common/fvector.hh>

#include <dune/grid/common/gridview.hh>
#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/stuff/common/crtp.hh>
#include <dune/stuff/la/container/pattern.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/common/float_cmp.hh>

#include "constraints.hh"

namespace Dune {
namespace GDT {

template <class Traits>
class SpaceInterface : protected Stuff::CRTPInterface<SpaceInterface<Traits>, Traits>
{
public:
  typedef typename Traits::derived_type derived_type;
  static const int polOrder = Traits::polOrder;
  typedef typename Traits::BackendType BackendType;
  typedef typename Traits::MapperType MapperType;
  typedef typename Traits::BaseFunctionSetType BaseFunctionSetType;
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeFieldType RangeFieldType;
  static const unsigned int dimRange     = Traits::dimRange;
  static const unsigned int dimRangeCols = Traits::dimRangeCols;

private:
  static_assert(std::is_base_of<GridView<typename GridViewType::Traits>, GridViewType>::value,
                "GridViewType has to be derived from GridView!");

public:
  typedef typename GridViewType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridViewType::dimension;
  typedef FieldVector<DomainFieldType, dimDomain> DomainType;

  typedef typename GridViewType::template Codim<0>::Entity EntityType;
  typedef typename GridViewType::Intersection IntersectionType;
  typedef Stuff::GridboundaryInterface<IntersectionType> BoundaryInfoType;
  typedef Dune::Stuff::LA::SparsityPatternDefault PatternType;

  static const bool needs_grid_view = Traits::needs_grid_view;

public:
  /**
   * \defgroup interface ´´These methods have to be implemented!''
   * @{
   **/

  const std::shared_ptr<const GridViewType>& grid_view() const
  {
    CHECK_CRTP(this->as_imp(*this).grid_view());
    return this->as_imp(*this).grid_view();
  }

  const BackendType& backend() const
  {
    CHECK_CRTP(this->as_imp(*this).backend());
    return this->as_imp(*this).backend();
  }

  const MapperType& mapper() const
  {
    CHECK_CRTP(this->as_imp(*this).mapper());
    return this->as_imp(*this).mapper();
  }

  BaseFunctionSetType base_function_set(const EntityType& entity) const
  {
    CHECK_CRTP(this->as_imp(*this).base_function_set(entity));
    return this->as_imp(*this).base_function_set(entity);
  }

  template <class ConstraintsType>
  void local_constraints(const EntityType& entity, ConstraintsType& ret) const
  {
    local_constraints(*this, entity, ret);
  }

  template <class ConstraintsType, class T>
  void local_constraints(const SpaceInterface<T>& ansatz_space, const EntityType& entity, ConstraintsType& ret) const
  {
    CHECK_AND_CALL_CRTP(this->as_imp(*this).local_constraints(ansatz_space, entity, ret));
    this->as_imp(*this).local_constraints(ansatz_space, entity, ret);
  }

  /**
   *  \brief  Computes the appropriate sparsity pattern.
   *  \note   This method can be implemented in a derived class by a forward to one of the methods provided by this
   * class, namely compute_volume_pattern(), compute_face_pattern() or compute_face_and_volume_pattern().
   */
  template <class G, class S>
  PatternType compute_pattern(const GridView<G>& local_grid_view, const SpaceInterface<S>& ansatz_space) const
  {
    CHECK_CRTP(this->as_imp(*this).compute_pattern(local_grid_view, ansatz_space));
    return this->as_imp(*this).compute_pattern(local_grid_view, ansatz_space);
  }
  /* @} */

  /**
   * \defgroup provided ´´These methods are provided by the interface for convenience.''
   * @{
   **/

  PatternType compute_pattern() const
  {
    return compute_pattern(*this);
  }

  template <class S>
  PatternType compute_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_pattern(*(grid_view()), ansatz_space);
  }

  template <class G>
  PatternType compute_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_pattern(local_grid_view, *this);
  }

  PatternType compute_volume_pattern() const
  {
    return compute_volume_pattern(*this);
  }

  template <class S>
  PatternType compute_volume_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_volume_pattern(*(grid_view()), ansatz_space);
  }

  template <class G>
  PatternType compute_volume_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_volume_pattern(local_grid_view, *this);
  }

  /**
   *  \brief  computes a sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class G, class S>
  PatternType compute_volume_pattern(const GridView<G>& local_grid_view, const SpaceInterface<S>& ansatz_space) const
  {
    PatternType pattern(mapper().size());
    Dune::DynamicVector<size_t> globalRows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> globalCols(ansatz_space.mapper().maxNumDofs(), 0);
    // walk the grid view
    const auto entityItEnd = local_grid_view.template end<0>();
    for (auto entityIt = local_grid_view.template begin<0>(); entityIt != entityItEnd; ++entityIt) {
      const auto& entity = *entityIt;
      // get basefunctionsets
      const auto testBase   = base_function_set(entity);
      const auto ansatzBase = ansatz_space.base_function_set(entity);
      mapper().globalIndices(entity, globalRows);
      ansatz_space.mapper().globalIndices(entity, globalCols);
      for (size_t ii = 0; ii < testBase.size(); ++ii) {
        auto& columns = pattern.inner(globalRows[ii]);
        for (size_t jj = 0; jj < ansatzBase.size(); ++jj) {
          columns.insert(globalCols[jj]);
        }
      }
    } // walk the grid view
    return pattern;
  } // ... compute_volume_pattern(...)

  PatternType compute_face_and_volume_pattern() const
  {
    return compute_face_and_volume_pattern(*(grid_view()), *this);
  }

  template <class G>
  PatternType compute_face_and_volume_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_face_and_volume_pattern(local_grid_view, *this);
  }

  template <class S>
  PatternType compute_face_and_volume_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_face_and_volume_pattern(*(grid_view()), ansatz_space);
  }

  /**
   *  \brief  computes a DG sparsity pattern, where this space is the test space (rows/outer) and the other space is the
   *          ansatz space (cols/inner)
   */
  template <class G, class S>
  PatternType compute_face_and_volume_pattern(const GridView<G>& local_grid_view,
                                              const SpaceInterface<S>& ansatz_space) const
  {
    // prepare
    PatternType pattern(mapper().size());
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(ansatz_space.mapper().maxNumDofs(), 0);
    // walk the grid view
    const auto entity_it_end = local_grid_view.template end<0>();
    for (auto entity_it = local_grid_view.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity   = base_function_set(entity);
      const auto ansatz_base_entity = ansatz_space.base_function_set(entity);
      mapper().globalIndices(entity, global_rows);
      ansatz_space.mapper().globalIndices(entity, global_cols);
      // compute entity/entity
      for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
        auto& columns = pattern.inner(global_rows[ii]);
        for (size_t jj = 0; jj < ansatz_base_entity.size(); ++jj) {
          columns.insert(global_cols[jj]);
        }
      }
      // walk the intersections
      const auto intersection_it_end = local_grid_view.iend(entity);
      for (auto intersection_it = local_grid_view.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = ansatz_space.base_function_set(neighbour);
          ansatz_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid view
    return pattern;
  } // ... compute_face_and_volume_pattern(...)

  PatternType compute_face_pattern() const
  {
    return compute_face_pattern(*(grid_view()), *this);
  }

  template <class G>
  PatternType compute_face_pattern(const GridView<G>& local_grid_view) const
  {
    return compute_face_pattern(local_grid_view, *this);
  }

  template <class S>
  PatternType compute_face_pattern(const SpaceInterface<S>& ansatz_space) const
  {
    return compute_face_pattern(*(grid_view()), ansatz_space);
  }

  template <class G, class S>
  PatternType compute_face_pattern(const GridView<G>& local_grid_view, const SpaceInterface<S>& ansatz_space) const
  {
    // prepare
    PatternType pattern(mapper().size());
    Dune::DynamicVector<size_t> global_rows(mapper().maxNumDofs(), 0);
    Dune::DynamicVector<size_t> global_cols(ansatz_space.mapper().maxNumDofs(), 0);
    // walk the grid view
    const auto entity_it_end = local_grid_view.template end<0>();
    for (auto entity_it = local_grid_view.template begin<0>(); entity_it != entity_it_end; ++entity_it) {
      const auto& entity = *entity_it;
      // get basefunctionsets
      const auto test_base_entity = base_function_set(entity);
      mapper().globalIndices(entity, global_rows);
      // walk the intersections
      const auto intersection_it_end = local_grid_view.iend(entity);
      for (auto intersection_it = local_grid_view.ibegin(entity); intersection_it != intersection_it_end;
           ++intersection_it) {
        const auto& intersection = *intersection_it;
        // get the neighbour
        if (intersection.neighbor() && !intersection.boundary()) {
          const auto neighbour_ptr = intersection.outside();
          const auto& neighbour    = *neighbour_ptr;
          // get the basis
          const auto ansatz_base_neighbour = ansatz_space.base_function_set(neighbour);
          ansatz_space.mapper().globalIndices(neighbour, global_cols);
          // compute entity/neighbour
          for (size_t ii = 0; ii < test_base_entity.size(); ++ii) {
            auto& columns = pattern.inner(global_rows[ii]);
            for (size_t jj = 0; jj < ansatz_base_neighbour.size(); ++jj) {
              columns.insert(global_cols[jj]);
            }
          }
        } // get the neighbour
      } // walk the intersections
    } // walk the grid view
    return pattern;
  } // ... compute_face_pattern(...)

private:
  class BasisVisualization : public Dune::VTKFunction<GridViewType>
  {
    static_assert(dimRangeCols == 1, "Not implemented for matrixvalued spaces yet!");

  public:
    typedef typename BaseFunctionSetType::DomainType DomainType;
    typedef typename BaseFunctionSetType::RangeType RangeType;

    BasisVisualization(const derived_type& sp, const size_t ind, const std::string nm = "basis")
      : space_(sp)
      , index_(ind)
      , values_(space_.mapper().maxNumDofs(), RangeType(0))
      , name_(nm)
    {
      if (index_ >= space_.mapper().maxNumDofs())
        DUNE_THROW(Dune::RangeError,
                   "index has to be smaller than " << space_.mapper().maxNumDofs() << "(is " << index_ << ")!");
    }

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

    /** \defgroup vtk ´´Methods to comply with the Dune::VTKFunction interface.'' */
    /* @{ */
    virtual int ncomps() const
    {
      return dimRange;
    }

    virtual double evaluate(int component, const EntityType& entity, const DomainType& xx) const
    {
      const auto baseFunctionSet = space_.base_function_set(entity);
      if (component < 0)
        DUNE_THROW(Dune::RangeError, "component must not be negative (is " << component << ")!");
      if (component < int(baseFunctionSet.size())) {
        baseFunctionSet.evaluate(xx, values_);
        assert(component < int(values_.size()) && "This should not happen!");
        return values_[index_][component];
      } else if (component < int(space_.mapper().maxNumDofs()))
        return 0.0;
      else
        DUNE_THROW(Dune::RangeError,
                   "component has to be smaller than " << space_.mapper().maxNumDofs() << "(is " << component << ")!");
    }
    /* @} */

  private:
    const derived_type& space_;
    const size_t index_;
    mutable std::vector<RangeType> values_;
    const std::string name_;
  }; // class BasisVisualization

public:
  void visualize(const std::string filename_prefix = "") const
  {
    std::string filename = filename_prefix;
    if (filename.empty()) {
      filename = "dune.gdt.space";
    }
    VTKWriter<GridViewType> vtk_writer(*(grid_view()), Dune::VTK::nonconforming);
    for (size_t ii = 0; ii < mapper().maxNumDofs(); ++ii) {
      std::string number = "";
      if (ii == 1)
        number = "1st";
      else if (ii == 2)
        number = "2nd";
      else if (ii == 3)
        number = "3rd";
      else
        number                     = Stuff::Common::toString(ii) + "th";
      const auto iith_baseFunction = std::make_shared<BasisVisualization>(this->as_imp(*this), ii, number + " basis");
      vtk_writer.addVertexData(iith_baseFunction);
    }
    vtk_writer.write(filename);
  } // ... visualize(...)

  /* @} */

protected:
  mutable std::vector<typename BaseFunctionSetType::RangeType> tmp_basis_values_;
}; // class SpaceInterface

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACE_INTERFACE_HH
<|endoftext|>


<commit_before>/**
   *  \file   stuff.hh
   *  \brief  contains some stuff
   **/
#ifndef DUNE_STUFF_COMMON_STRING_HH
#define DUNE_STUFF_COMMON_STRING_HH

#ifdef HAVE_CMAKE_CONFIG
 #include "cmake_config.h"
#else
 #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <cstring>
#include <ctime>
#include <map>
#include <assert.h>
#include <algorithm>

#include <dune/common/array.hh>
#include <dune/common/deprecated.hh>
#include <dune/common/static_assert.hh>
#include <ostream>
#include <iomanip>
#include <vector>
#include <string>
#include <ctime>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>

namespace Dune {
namespace Stuff {
namespace Common {

//! simple and dumb std::string to anything conversion
template< class ReturnType >
inline ReturnType fromString(const std::string& s) {
  return boost::lexical_cast<ReturnType, std::string>(s);
} // fromString

//! simple and dumb anything to std::string conversion
template< class ReturnType >
inline std::string toString(const ReturnType& s) {
  return boost::lexical_cast<std::string, ReturnType>(s);
} // toString

/**
  \brief      Returns a string of lengths s' whitespace (or c chars).
  \param[in]  s
              std::string, defines the length of the return string
  \param[in]  whitespace
              char, optional argument, defines entries of return string
  \return     std::string
              Returns a string of lengths s' whitespace (or c chars).
  **/
template< class T >
std::string whitespaceify(const T& t, const char whitespace = ' ')
{
  const std::string s = toString< T >(t);
  std::string ret = "";
  for (unsigned int i = 0; i < s.size(); ++i) {
    ret += whitespace;
  }
  return ret;
} // std::string whitespaceify(const std::string s, const char whitespace = ' ')

#if HAS_LAMBDA_FUNCTIONS && HAS_STD_BEGIN_END
/** \brief convenience wrapper around boost::algorithm::split to split one string into a vector of strings
 * \param msg the spring to be split
 * \param seperators a list of seperaors, duh
 * \param mode token_compress_off --> potentially empty strings in return,
              token_compress_on --> empty tokens are discarded
 * \return all tokens in a vector, if msg contains no seperators, this'll contain msg as its only element
 **/
template < class T = std::string >
inline std::vector<T> tokenize( const std::string& msg,
                             const std::string& seperators,
                             const boost::algorithm::token_compress_mode_type mode = boost::algorithm::token_compress_off )
{
    std::vector<std::string> strings;
    boost::algorithm::split( strings, msg, boost::algorithm::is_any_of(seperators),
                             mode );
    std::vector<T> ret(strings.size());
    size_t i = 0;
    //special case for empty strings to avoid non-default init
    std::generate(std::begin(ret), std::end(ret), [&] (){ return strings[i++].empty() ? T() : fromString<T>(strings[i-1]); });
    return ret;
}
//! if the compiler isn't recent enough we make tokenize avalilable for string only
template < >
#endif //HAS_LAMBDA_FUNCTIONS && HAS_STD_BEGIN_END
inline std::vector<std::string> tokenize( const std::string& msg,
                             const std::string& seperators,
                             const boost::algorithm::token_compress_mode_type mode )
{
    std::vector<std::string> strings;
    boost::algorithm::split( strings, msg, boost::algorithm::is_any_of(seperators),
                             mode );
    return strings;
}

//! returns string with local time in current locale's format
inline std::string stringFromTime(time_t cur_time = time(NULL)) {
  return ctime(&cur_time);
}

//! helper struct for lexical cast
template <typename ElemT>
struct HexToString {
  // see http://stackoverflow.com/a/2079728
  ElemT value;
  operator ElemT() const {return value;}
  friend std::istream& operator>>(std::istream& in, HexToString& out) {
    in >> std::hex >> out.value;
    return in;
  }
};

// some legacy stuff I'd like to keep for a while
namespace String {

template< class T >
DUNE_DEPRECATED_MSG("use DSC::fromString instead, removal with stuff 2.3") T from(const std::string& s)
{
  std::stringstream ss;
  ss << s;
  T t;
  ss >> t;
  return t;
}

template< class T >
DUNE_DEPRECATED_MSG("use DSC::toString instead, removal with stuff 2.3") std::string to(const T& t)
{
  std::stringstream ss;
  ss << t;
  std::string s;
  ss >> s;
  return s;
}

bool equal(const std::string& first, const std::string& second)
{
  return !first.compare(second);
}

std::vector< std::string > mainArgsToVector(int argc, char** argv)
{
  return std::vector< std::string >(argv, argv + argc);
}

char** vectorToMainArgs(const std::vector< std::string > args)
{
  char** argv = new char* [args.size()];
  for (unsigned int ii = 0; ii < args.size(); ++ii) {
    argv[ii] = new char[args[ii].length() + 1];
    strcpy(argv[ii], args[ii].c_str());
  }
  return argv;
} // char** vectorToMainArgs(const std::vector< std::string > args)

} // namespace String

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_STRING_HH

/** Copyright (c) 2012, Rene Milk    , Sven Kaulmann
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * The views and conclusions contained in the software and documentation are those
   * of the authors and should not be interpreted as representing official policies,
   * either expressed or implied, of the FreeBSD Project.
   **/
<commit_msg>[common.string] new deprecation marks<commit_after>/**
   *  \file   stuff.hh
   *  \brief  contains some stuff
   **/
#ifndef DUNE_STUFF_COMMON_STRING_HH
#define DUNE_STUFF_COMMON_STRING_HH

#ifdef HAVE_CMAKE_CONFIG
 #include "cmake_config.h"
#else
 #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#include <cstring>
#include <ctime>
#include <map>
#include <assert.h>
#include <algorithm>

#include <dune/common/array.hh>
#include <dune/common/deprecated.hh>
#include <dune/common/static_assert.hh>
#include <ostream>
#include <iomanip>
#include <vector>
#include <string>
#include <ctime>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>

namespace Dune {
namespace Stuff {
namespace Common {

//! simple and dumb std::string to anything conversion
template< class ReturnType >
inline ReturnType fromString(const std::string& s) {
  return boost::lexical_cast<ReturnType, std::string>(s);
} // fromString

//! simple and dumb anything to std::string conversion
template< class ReturnType >
inline std::string toString(const ReturnType& s) {
  return boost::lexical_cast<std::string, ReturnType>(s);
} // toString

/**
  \brief      Returns a string of lengths s' whitespace (or c chars).
  \param[in]  s
              std::string, defines the length of the return string
  \param[in]  whitespace
              char, optional argument, defines entries of return string
  \return     std::string
              Returns a string of lengths s' whitespace (or c chars).
  **/
template< class T >
std::string whitespaceify(const T& t, const char whitespace = ' ')
{
  const std::string s = toString< T >(t);
  std::string ret = "";
  for (unsigned int i = 0; i < s.size(); ++i) {
    ret += whitespace;
  }
  return ret;
} // std::string whitespaceify(const std::string s, const char whitespace = ' ')

#if HAS_LAMBDA_FUNCTIONS && HAS_STD_BEGIN_END
/** \brief convenience wrapper around boost::algorithm::split to split one string into a vector of strings
 * \param msg the spring to be split
 * \param seperators a list of seperaors, duh
 * \param mode token_compress_off --> potentially empty strings in return,
              token_compress_on --> empty tokens are discarded
 * \return all tokens in a vector, if msg contains no seperators, this'll contain msg as its only element
 **/
template < class T = std::string >
inline std::vector<T> tokenize( const std::string& msg,
                             const std::string& seperators,
                             const boost::algorithm::token_compress_mode_type mode = boost::algorithm::token_compress_off )
{
    std::vector<std::string> strings;
    boost::algorithm::split( strings, msg, boost::algorithm::is_any_of(seperators),
                             mode );
    std::vector<T> ret(strings.size());
    size_t i = 0;
    //special case for empty strings to avoid non-default init
    std::generate(std::begin(ret), std::end(ret), [&] (){ return strings[i++].empty() ? T() : fromString<T>(strings[i-1]); });
    return ret;
}
//! if the compiler isn't recent enough we make tokenize avalilable for string only
template < >
#endif //HAS_LAMBDA_FUNCTIONS && HAS_STD_BEGIN_END
inline std::vector<std::string> tokenize( const std::string& msg,
                             const std::string& seperators,
                             const boost::algorithm::token_compress_mode_type mode )
{
    std::vector<std::string> strings;
    boost::algorithm::split( strings, msg, boost::algorithm::is_any_of(seperators),
                             mode );
    return strings;
}

//! returns string with local time in current locale's format
inline std::string stringFromTime(time_t cur_time = time(NULL)) {
  return ctime(&cur_time);
}

//! helper struct for lexical cast
template <typename ElemT>
struct HexToString {
  // see http://stackoverflow.com/a/2079728
  ElemT value;
  operator ElemT() const {return value;}
  friend std::istream& operator>>(std::istream& in, HexToString& out) {
    in >> std::hex >> out.value;
    return in;
  }
};

// some legacy stuff I'd like to keep for a while
namespace String {

template< class T >
DUNE_DEPRECATED_MSG("use DSC::fromString instead, removal with stuff 2.3") T from(const std::string& s)
{
  std::stringstream ss;
  ss << s;
  T t;
  ss >> t;
  return t;
}

template< class T >
DUNE_DEPRECATED_MSG("use DSC::toString instead, removal with stuff 2.3") std::string to(const T& t)
{
  std::stringstream ss;
  ss << t;
  std::string s;
  ss >> s;
  return s;
}

DUNE_DEPRECATED_MSG("nonsense function, to be removed immenently")
bool equal(const std::string& first, const std::string& second)
{
  return !first.compare(second);
}

DUNE_DEPRECATED_MSG("use the constructor call directly")
std::vector< std::string > mainArgsToVector(int argc, char** argv)
{
  return std::vector< std::string >(argv, argv + argc);
}

char** vectorToMainArgs(const std::vector< std::string > args)
{
  char** argv = new char* [args.size()];
  for (unsigned int ii = 0; ii < args.size(); ++ii) {
    argv[ii] = new char[args[ii].length() + 1];
    strcpy(argv[ii], args[ii].c_str());
  }
  return argv;
} // char** vectorToMainArgs(const std::vector< std::string > args)

} // namespace String

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_COMMON_STRING_HH

/** Copyright (c) 2012, Rene Milk    , Sven Kaulmann
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice, this
   *    list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * The views and conclusions contained in the software and documentation are those
   * of the authors and should not be interpreted as representing official policies,
   * either expressed or implied, of the FreeBSD Project.
   **/
<|endoftext|>


<commit_before>#include "Scene.hpp"

#include "../Entity/Entity.hpp"

Scene::Scene() {

}

Scene::~Scene() {
    Clear();
}

Entity* Scene::CreateEntity() {
    Entity* entity = new Entity(this);
    entities.push_back(entity);
    return entity;
}

void Scene::Clear() {

}
<commit_msg>Properly clear entities.<commit_after>#include "Scene.hpp"

#include "../Entity/Entity.hpp"

Scene::Scene() {

}

Scene::~Scene() {
    Clear();
}

Entity* Scene::CreateEntity() {
    Entity* entity = new Entity(this);
    entities.push_back(entity);
    return entity;
}

void Scene::Clear() {
    for (Entity* entity : entities)
        delete entity;
    entities.clear();
}
<|endoftext|>


<commit_before>// Aircraft.cpp
// Copyright (c) 2014 - The Foreseeable Future, zhiayang@gmail.com
// Licensed under the Apache License Version 2.0.

#include "Game.h"
#include <random>
#include "Config.h"
#include "Game/Scene.h"
#include "Game/Aircraft.h"

namespace Game
{
	Aircraft::Aircraft(Entity* p) : MovingEntity(p), ai(this)
	{

	}

	Aircraft::~Aircraft()
	{
	}

	void Aircraft::Render(SDL::Renderer* r)
	{
		Math::Circle c;
		c.origin = Math::Vector2(this->pos().x, this->pos().y);
		c.radius = 3;

		glPushMatrix();

		// r->SetColour(this->colour);
		// r->RenderCircle(c, true);

		glTranslated(this->pos().x, this->pos().y, 0);
		glRotated(30, 0, 0, 1);
		glTranslated(-this->pos().x, -this->pos().y, 0);
		r->SetColour(Util::Colour::blue());
		r->RenderEqTriangle(Math::Vector2(this->pos().x, this->pos().y), 100);

		glPopMatrix();

		// render our callsign
		r->SetColour(Util::Colour::white());
		SDL::Font* f = Util::Font::get("pixel", 8, false);
		r->RenderText(this->callsign, f, c.origin + Math::Vector2(3, 3));

		// render our children
		this->MovingEntity::Render(r);
	}

	void Aircraft::Update(float dt)
	{
		this->ai.UpdateAI(dt);
		this->MovingEntity::Update(dt);
	}
}

<commit_msg>rotating triangles...?<commit_after>// Aircraft.cpp
// Copyright (c) 2014 - The Foreseeable Future, zhiayang@gmail.com
// Licensed under the Apache License Version 2.0.

#include "Game.h"
#include <random>
#include "Config.h"
#include "Game/Scene.h"
#include "Game/Aircraft.h"

namespace Game
{
	Aircraft::Aircraft(Entity* p) : MovingEntity(p), ai(this)
	{

	}

	Aircraft::~Aircraft()
	{
	}

	void Aircraft::Render(SDL::Renderer* r)
	{
		Math::Circle c;
		c.origin = Math::Vector2(this->pos().x, this->pos().y);
		c.radius = 3;

		glPushMatrix();

		// r->SetColour(this->colour);
		// r->RenderCircle(c, true);

		glTranslated(this->pos().x, this->pos().y, 0);
		glRotated(30, 0, 0, 1);
		glTranslated(-this->pos().x, -this->pos().y, 0);
		r->SetColour(this->colour);
		r->RenderEqTriangle(Math::Vector2(this->pos().x, this->pos().y), 10);

		glPopMatrix();

		// render our callsign
		r->SetColour(Util::Colour::white());
		SDL::Font* f = Util::Font::get("pixel", 8, false);
		r->RenderText(this->callsign, f, c.origin + Math::Vector2(3, 3));

		// render our children
		this->MovingEntity::Render(r);
	}

	void Aircraft::Update(float dt)
	{
		this->ai.UpdateAI(dt);
		this->MovingEntity::Update(dt);
	}
}

<|endoftext|>


<commit_before>/********************************************************************************
File name: monster.cpp
Written by: Daniel Nguyen
Written on 08/27/2016
Purpose: This is a c++ file containing classes for all monsters

Class: CPSC 362
*********************************************************************************/

#include <string>
#include <cstdlib>
#include <ctime>
#include<iostream>

/*********************************************************************
This is the base class for all enemies. It include title, skills, hp,
exp. Item drops haven't been implemented.
*********************************************************************/
class Enemy{
	protected:
        std::string name;
		int hp;
		int exp;
		int min_atk;
		int max_atk;
        std::string description;
	public:
		//Accessor functions for hp
		void set_hp(int num){ hp = num;}
		int get_hp(){return hp;}

		//Accessor functions for exp
		int get_exp(){return exp;}

		//Accessor function for min_atk
		void set_min_atk(int num){min_atk = num;}

		//Accessor function for max_atk
		void set_max_atk(int num){max_atk = num;}

		//Function for attacks that randomize number between minimum atk and maximum atk
        //The function also ouputs the attack command
		int attack(){
			//Use time function to get a "seed" value for srand
			unsigned seed = time(0);
			srand(seed);
			//Generate and return a random number between min_atk and max_atk
			int range = max_atk - min_atk;
            int atk_damage = rand() % range + min_atk;
            return atk_damage;
		}

        //Function that takes an int as argument and subtract it from the monster's hp
        void take_damage(int damage){
            hp = hp - damage;
        }

        //Stores length of name and name, hp, exp, min atk, max atk, length of description
        //and description
        void pack(std::ostream & str)
        {
            //Write length and data for name
            int name_length = name.length();
            str.write(reinterpret_cast<char *>(&name_length),sizeof(int));
            str.write(name.data(), name_length);

            //Write hp
            str.write(reinterpret_cast<char *>(&hp),sizeof(hp));

            //Write exp
            str.write(reinterpret_cast<char *>(&exp),sizeof(exp));

            //write min_atk
            str.write(reinterpret_cast<char *>(&min_atk),sizeof(min_atk));

            //write max atk
            str.write(reinterpret_cast<char *>(&max_atk),sizeof(max_atk));

            //write length and data for description
            int description_length = description.length();
            str.write(reinterpret_cast<char *>(&description_length),sizeof(int));
            str.write(description.data(), description_length);
        }

        //Reads the data in the format written by Monster::pack
        void unpack(std::istream & str)
        {
            const int BUFFER_SIZE = 256;
            static char buffer[256];

            //Getting name's length, read the data into a local buffer and assign to name
            int name_length;
            str.read(reinterpret_cast<char *>(&name_length),sizeof(int));
            str.read(buffer, name_length);
            buffer[name_length] = '\0';
            name = buffer;

            //Getting hp
            str.read(reinterpret_cast<char *>(&hp),sizeof(hp));

            //Getting exp
            str.read(reinterpret_cast<char *> (&exp),sizeof(exp));

            //Getting min_atk
            str.read(reinterpret_cast<char *> (&min_atk),sizeof(min_atk));

            //Getting max atk
            str.read(reinterpret_cast<char *> (&max_atk),sizeof(max_atk));

            //Getting description's length, read the data into a local buffer and assign
            //to description
            int description_length;
            str.read(reinterpret_cast<char *>(&description_length),sizeof(int));
            str.read(buffer, description_length);
            buffer[description_length] = '\0';
            description = buffer;

        }
};

/************************************************************************
The following classes contain information about different monster.
Again, skills haven't been implemented.
*************************************************************************/
class Hedgehog : public Enemy
{
	public:
		Hedgehog(){
            this->name= "Hedgehog";
			this->hp = 50;
			this->exp = 2;
			this->min_atk = 7;
			this->max_atk = 10;
			this->description = "Small, spiny monster that shoots spiens at enemies";
		}
};

class Dead_Tree: public Enemy
{
	public:
		Dead_Tree(){
            this->name = "Dead_Tree";
			this->hp = 95;
			this->exp = 5;
			this->min_atk =9;
			this->max_atk =12;
			this->description = "A tree monster. The feature and sound that it makes "
								"are incredibly eerie";
			}
};

class Giant_Frog :public Enemy
{
	public:
		Giant_Frog(){
            this->name = "Giant Frog";
			this->hp = 133;
			this->exp = 6;
			this->min_atk = 11;
			this->max_atk =14;
			this->description="A mutant frog that is 5 times the size of normal frog."
                            " It makes annoying sounds.";
		}
};

class Roach_Egg : public Enemy
{
	public:
		Roach_Egg(){
            this->name = "Roach Egg";
			this->hp = 48;
			this->exp =8;
			this->min_atk = 0;
			this->max_atk = 0;
			this->description="It hatches into several Roaches It makes "
							"horrible omelette.";
		}
};

class CockRoach : public Enemy
{
	public:
		CockRoach(){
            this->name = "Cockroach";
			this->hp=126;
			this->exp = 17;
			this->min_atk = 18;
			this->max_atk =24;
			this->description="Dirty, filthy creatures that tend to work in swarms.";
		}
};

class Skeleton : public Enemy
{
	public:
		Skeleton(){
            this->name = "Skeleton";
			this->hp = 234;
			this->exp =18;
			this->min_atk = 39;
			this->max_atk = 47;
			this->description="A skeleton of a dead person who had died holding "
							"a grudge. It's undead so of course it hates living things.";
		}
};

class Violinist : public Enemy
{
	public:
		Violinist(){
            this->name = "Violinist";
			this->hp =198;
			this->exp =20;
			this->min_atk = 24;
			this->max_atk = 29;
			this->description = "A long-horned grass hopper of a romantic turn of mind,"
							" that always play a violin. Most consider him as the main "
							"culprit for noise.";
		}
};

class GruBat: public Enemy
{
	public:
		GruBat(){
            this->name="GruBat";
			this->hp=155;
			this->exp =28;
			this->min_atk = 20;
			this->max_atk = 28;
			this->description = "A gray bat that's not very strong, but annoying because"
							" it attacks very fast and relentlessly pursuits passerby";
		}
};

class Arthropod : public Enemy
{
	public:
		Arthropod(){
            this->name="Arthropod";
			this->hp = 507;
			this->exp =38;
			this->min_atk = 28;
			this->max_atk = 37;
			this->description = "Kukre is a small bug living near the beach.";
		}
};

class Zombie : public Enemy
{
	public:
		Zombie(){
            this->name="Zombie";
			this->hp = 534;
			this->exp =50;
			this->min_atk = 67;
			this->max_atk = 79;
			this->description = "A walking curse which has been cursed by an evil shaman."
								" Beware of its poisonous breath.";
		}
};

class Roddent_Tail : public Enemy
{
	public:
		Roddent_Tail(){
            this->name ="Roddent Tail";
			this->hp = 426;
			this->exp =59;
			this->min_atk = 42;
			this->max_atk = 51;
			this->description = "A roddent that uses whipping attacks with a "
								"tail that looks like a blade of grass.";
		}
};

class Poison_Hedgehog : public Enemy
{
	public:
		Poison_Hedgehog(){
            this->name = "Poison Hedgehog";
			this->hp = 344;
			this->exp =81;
			this->min_atk = 59;
			this->max_atk = 72;
			this->description = "A kind of Hedgehog living in the swarm. It is covered "
								"with poisonous elastic skins all around the body.";
		}
};

class Steel_Fly : public Enemy
{
	public:
		Steel_Fly(){
            this->name="Steel Fly";
			this->hp = 530;
			this->exp =109;
			this->min_atk = 54;
			this->max_atk = 65;
			this->description = "A kind of fly that has a firm shell covering its body.";
		}
};

class Crazy_Squirrel : public Enemy
{
	public:
		Crazy_Squirrel(){
            this->name="Crazy Squrirrel";
			this->hp = 817;
			this->exp =120;
			this->min_atk = 56;
			this->max_atk = 67;
			this->description = "A small squirrel that is not that strong but very fast."
								" It has dark piercing eyes and is always holding an Acorn.";
		}
};

class Horn : public Enemy
{
	public:
		Horn(){
            this->name="Horn";
			this->hp = 659;
			this->exp =134;
			this->min_atk = 58;
			this->max_atk = 69;
			this->description = "A giant ground beetle that never cares about things"
				" going around except its business. When it's threatened, it uses sciccor-like"
				" mandibles to attack enemies.";
		}
};

class Fire_Ant : public Enemy
{
	public:
		Fire_Ant(){
            this->name="Fire Ant";
			this->hp = 760;
			this->exp =135;
			this->min_atk = 68;
			this->max_atk = 79;
			this->description = "A kind of ant of red color. They live in group and are "
							"very cooperative to attack.";
		}
};

int main(){
    Horn newHorn;
    newHorn.attack();
    newHorn.take_damage(200);
    return 0;
}

<commit_msg>modify some functions<commit_after>/********************************************************************************
File name: monster.cpp
Written by: Daniel Nguyen
Written on 08/27/2016
Purpose: This is a c++ file containing classes for all monsters

Class: CPSC 362
*********************************************************************************/
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include<iostream>

/*********************************************************************
This is the base class for all enemies. It include title, skills, hp,
exp. Item drops haven't been implemented.
*********************************************************************/
class Enemy{
	protected:
        std::string name;
		int hp;
		int exp;
		int min_atk;
		int max_atk;
        std::string description;
	public:
		//Accessor functions for hp
		void set_hp(int num){ hp = num;}
		int get_hp(){return hp;}

		//Accessor functions for exp
		int get_exp(){return exp;}

		//Accessor function for min_atk
		void set_min_atk(int num){min_atk = num;}

		//Accessor function for max_atk
		void set_max_atk(int num){max_atk = num;}

		//Function for attacks that randomize number between minimum atk and maximum atk
        //The function also ouputs the attack command
		int attack(){
			//Use time function to get a "seed" value for srand
			unsigned seed = time(0);
			srand(seed);
			//Generate and return a random number between min_atk and max_atk
			int range = max_atk - min_atk;
            int atk_damage = rand() % range + min_atk;
            return atk_damage;
		}

        //Function that takes an int as argument and subtract it from the monster's hp
        void take_damage(int damage){
            hp = hp - damage;
        }

        //Stores length of name and name, hp, exp, min atk, max atk, length of description
        //and description
        void write_to_stream(std::ostream & str)
        {
            //Write length and data for name
            int name_length = name.length();
            str.write(reinterpret_cast<char *>(&name_length),sizeof(int));
            str.write(name.data(), name_length);

            //Write hp
            str.write(reinterpret_cast<char *>(&hp),sizeof(hp));

            //Write exp
            str.write(reinterpret_cast<char *>(&exp),sizeof(exp));

            //write min_atk
            str.write(reinterpret_cast<char *>(&min_atk),sizeof(min_atk));

            //write max atk
            str.write(reinterpret_cast<char *>(&max_atk),sizeof(max_atk));

            //write length and data for description
            int description_length = description.length();
            str.write(reinterpret_cast<char *>(&description_length),sizeof(int));
            str.write(description.data(), description_length);
        }

        //Reads the data in the format written by Monster::pack
        void read_to_file(std::istream & str)
        {
            const int BUFFER_SIZE = 256;
            static char buffer[256];

            //Getting name's length, read the data into a local buffer and assign to name
            int name_length;
            str.read(reinterpret_cast<char *>(&name_length),sizeof(int));
            str.read(buffer, name_length);
            buffer[name_length] = '\0';
            name = buffer;

            //Getting hp
            str.read(reinterpret_cast<char *>(&hp),sizeof(hp));

            //Getting exp
            str.read(reinterpret_cast<char *> (&exp),sizeof(exp));

            //Getting min_atk
            str.read(reinterpret_cast<char *> (&min_atk),sizeof(min_atk));

            //Getting max atk
            str.read(reinterpret_cast<char *> (&max_atk),sizeof(max_atk));

            //Getting description's length, read the data into a local buffer and assign
            //to description
            int description_length;
            str.read(reinterpret_cast<char *>(&description_length),sizeof(int));
            str.read(buffer, description_length);
            buffer[description_length] = '\0';
            description = buffer;

        }
    	template<typename T> std::string convert_to_string(T data){
    		std::stringstream stream;
    		std::string str;
    		stream << data;
    		stream >> str;
    		str += '/';
    		return str;
    	}

        std::string pack(){
            std::string retVal = "";
            //Add name and '/' following it to retVal string
            retVal += name;
            retVal += '/';

            //Convert hp to string, add hp string and '/' to reVal
            retVal+= convert_to_string(hp);

            //Convert exp to string, add exp string and '/' to retVal
            retVal += convert_to_string(exp);

            //Convert min_atk to string, add min_atk string and '/' to retVal
           	retVal += convert_to_string(min_atk);

            //Convert max_atk to string, add max_atk string and '/' to retVal
            retVal += convert_to_string(max_atk);

            //Add description to retVal string
            retVal+= description;
            retVal+='/';

            return retVal;
        }

        void unpack(std::string str)
        {
            std::string token;
            std::istringstream ss(str);
            int mem_var = 1;
            while(std::getline(ss, token, '/'))
            {
                std::istringstream stream(token);
                switch(mem_var){
                    case 1:
                        stream >> name;
                        mem_var++;
                        break;
                    case 2:
                        stream >> hp;
                        mem_var++;
                        break;
                    case 3:
                        stream >> exp;
                        mem_var++;
                        break;
                    case 4:
                        stream >> min_atk;
                        mem_var++;
                        break;
                    case 5:
                        stream >> max_atk;
                        mem_var++;
                        break;
                    case 6:
                        stream >> description;
                        break;

                }
            }
    	}
};

/************************************************************************
The following classes contain information about different monster.
Again, skills haven't been implemented.
*************************************************************************/
class Hedgehog : public Enemy
{
	public:
		Hedgehog(){
            this->name= "Hedgehog";
			this->hp = 50;
			this->exp = 2;
			this->min_atk = 7;
			this->max_atk = 10;
			this->description = "Small, spiny monster that shoots spiens at enemies";
		}
};

class Dead_Tree: public Enemy
{
	public:
		Dead_Tree(){
            this->name = "Dead_Tree";
			this->hp = 95;
			this->exp = 5;
			this->min_atk =9;
			this->max_atk =12;
			this->description = "A tree monster. The feature and sound that it makes "
								"are incredibly eerie";
			}
};

class Giant_Frog :public Enemy
{
	public:
		Giant_Frog(){
            this->name = "Giant Frog";
			this->hp = 133;
			this->exp = 6;
			this->min_atk = 11;
			this->max_atk =14;
			this->description="A mutant frog that is 5 times the size of normal frog."
                            " It makes annoying sounds.";
		}
};

class Roach_Egg : public Enemy
{
	public:
		Roach_Egg(){
            this->name = "Roach Egg";
			this->hp = 48;
			this->exp =8;
			this->min_atk = 0;
			this->max_atk = 0;
			this->description="It hatches into several Roaches It makes "
							"horrible omelette.";
		}
};

class CockRoach : public Enemy
{
	public:
		CockRoach(){
            this->name = "Cockroach";
			this->hp=126;
			this->exp = 17;
			this->min_atk = 18;
			this->max_atk =24;
			this->description="Dirty, filthy creatures that tend to work in swarms.";
		}
};

class Skeleton : public Enemy
{
	public:
		Skeleton(){
            this->name = "Skeleton";
			this->hp = 234;
			this->exp =18;
			this->min_atk = 39;
			this->max_atk = 47;
			this->description="A skeleton of a dead person who had died holding "
							"a grudge. It's undead so of course it hates living things.";
		}
};

class Violinist : public Enemy
{
	public:
		Violinist(){
            this->name = "Violinist";
			this->hp =198;
			this->exp =20;
			this->min_atk = 24;
			this->max_atk = 29;
			this->description = "A long-horned grass hopper of a romantic turn of mind,"
							" that always play a violin. Most consider him as the main "
							"culprit for noise.";
		}
};

class GruBat: public Enemy
{
	public:
		GruBat(){
            this->name="GruBat";
			this->hp=155;
			this->exp =28;
			this->min_atk = 20;
			this->max_atk = 28;
			this->description = "A gray bat that's not very strong, but annoying because"
							" it attacks very fast and relentlessly pursuits passerby";
		}
};

class Arthropod : public Enemy
{
	public:
		Arthropod(){
            this->name="Arthropod";
			this->hp = 507;
			this->exp =38;
			this->min_atk = 28;
			this->max_atk = 37;
			this->description = "Kukre is a small bug living near the beach.";
		}
};

class Zombie : public Enemy
{
	public:
		Zombie(){
            this->name="Zombie";
			this->hp = 534;
			this->exp =50;
			this->min_atk = 67;
			this->max_atk = 79;
			this->description = "A walking curse which has been cursed by an evil shaman."
								" Beware of its poisonous breath.";
		}
};

class Roddent_Tail : public Enemy
{
	public:
		Roddent_Tail(){
            this->name ="Roddent Tail";
			this->hp = 426;
			this->exp =59;
			this->min_atk = 42;
			this->max_atk = 51;
			this->description = "A roddent that uses whipping attacks with a "
								"tail that looks like a blade of grass.";
		}
};

class Poison_Hedgehog : public Enemy
{
	public:
		Poison_Hedgehog(){
            this->name = "Poison Hedgehog";
			this->hp = 344;
			this->exp =81;
			this->min_atk = 59;
			this->max_atk = 72;
			this->description = "A kind of Hedgehog living in the swarm. It is covered "
								"with poisonous elastic skins all around the body.";
		}
};

class Steel_Fly : public Enemy
{
	public:
		Steel_Fly(){
            this->name="Steel Fly";
			this->hp = 530;
			this->exp =109;
			this->min_atk = 54;
			this->max_atk = 65;
			this->description = "A kind of fly that has a firm shell covering its body.";
		}
};

class Crazy_Squirrel : public Enemy
{
	public:
		Crazy_Squirrel(){
            this->name="Crazy Squrirrel";
			this->hp = 817;
			this->exp =120;
			this->min_atk = 56;
			this->max_atk = 67;
			this->description = "A small squirrel that is not that strong but very fast."
								" It has dark piercing eyes and is always holding an Acorn.";
		}
};

class Horn : public Enemy
{
	public:
		Horn(){
            this->name="Horn";
			this->hp = 659;
			this->exp =134;
			this->min_atk = 58;
			this->max_atk = 69;
			this->description = "A giant ground beetle that never cares about things"
				" going around except its business. When it's threatened, it uses sciccor-like"
				" mandibles to attack enemies.";
		}
};

class Fire_Ant : public Enemy
{
	public:
		Fire_Ant(){
            this->name="Fire Ant";
			this->hp = 760;
			this->exp =135;
			this->min_atk = 68;
			this->max_atk = 79;
			this->description = "A kind of ant of red color. They live in group and are "
							"very cooperative to attack.";
		}
};

int main(){
    Horn newHorn;
    std::string testString = newHorn.pack();
    std::cout << testString << std::endl;
    std::string testInput= "ahah/23/34/45/65/I am crazy.";
    newHorn.unpack(testInput);
    std::cout << newHorn.get_exp() << " " << newHorn.get_hp() << std::endl;
}

<|endoftext|>


<commit_before>#include <memory>
#include <algorithm>
#include <stdexcept>
#include <system_error>
#include <random>

#include <realm/util/features.h>
#include <realm/util/assert.hpp>
#include <realm/util/basic_system_errors.hpp>
#include <realm/impl/simulated_failure.hpp>

#if REALM_PLATFORM_APPLE
#  define USE_PTHREADS_IMPL 1
#else
#  define USE_PTHREADS_IMPL 0
#endif

#if USE_PTHREADS_IMPL
#  include <pthread.h>
#endif

using namespace realm;
using namespace realm::_impl;

#ifdef REALM_ENABLE_SIMULATED_FAILURE

namespace {

const int num_failure_types = SimulatedFailure::_num_failure_types;

struct PrimeMode {
    virtual bool check_trigger() noexcept = 0;
    virtual ~PrimeMode() noexcept {}
};

struct PrimeState {
    std::unique_ptr<PrimeMode> slots[num_failure_types];
};

struct OneShotPrimeMode: PrimeMode {
    bool triggered = false;
    bool check_trigger() noexcept override
    {
        if (triggered)
            return false;
        triggered = true;
        return true;
    }
};

struct RandomPrimeMode: PrimeMode {
    std::mt19937_64 random;
    std::uniform_int_distribution<int> dist;
    int n;
    RandomPrimeMode(int n, int m, uint_fast64_t seed):
        random(seed),
        dist(0, m-1),
        n(n)
    {
        REALM_ASSERT(n >= 0 && m > 0);
    }
    bool check_trigger() noexcept override
    {
        int i = dist(random);
        return i < n;
    }
};

#  if !USE_PTHREADS_IMPL

thread_local PrimeState t_prime_state;

PrimeState& get() noexcept
{
    return t_prime_state;
}

#  else // USE_PTHREADS_IMPL

pthread_key_t key;
pthread_once_t key_once = PTHREAD_ONCE_INIT;

void destroy(void* ptr) noexcept
{
    PrimeState* prime_state = static_cast<PrimeState*>(ptr);
    delete prime_state;
}

void create() noexcept
{
    int ret = pthread_key_create(&key, &destroy);
    if (REALM_UNLIKELY(ret != 0)) {
        std::error_code ec = util::make_basic_system_error_code(errno);
        throw std::system_error(ec); // Termination intended
    }
}

PrimeState& get() noexcept
{
    pthread_once(&key_once, &create);
    void* ptr = pthread_getspecific(key);
    PrimeState* prime_state = static_cast<PrimeState*>(ptr);
    if (!prime_state) {
        prime_state = new PrimeState; // Throws with intended termination
        int ret = pthread_setspecific(key, prime_state);
        if (REALM_UNLIKELY(ret != 0)) {
            std::error_code ec = util::make_basic_system_error_code(errno);
            throw std::system_error(ec); // Termination intended
        }
    }
    return *prime_state;
}

#  endif // USE_PTHREADS_IMPL

} // unnamed namespace

void SimulatedFailure::do_prime_one_shot(FailureType failure_type)
{
    PrimeState& state = get();
    if (state.slots[failure_type])
        throw std::runtime_error("Already primed");
    state.slots[failure_type].reset(new OneShotPrimeMode); // Throws
}

void SimulatedFailure::do_prime_random(FailureType failure_type, int n, int m, uint_fast64_t seed)
{
    PrimeState& state = get();
    if (state.slots[failure_type])
        throw std::runtime_error("Already primed");
    state.slots[failure_type].reset(new RandomPrimeMode(n, m, seed)); // Throws
}

void SimulatedFailure::do_unprime(FailureType failure_type) noexcept
{
    PrimeState& state = get();
    state.slots[failure_type].reset();
}

bool SimulatedFailure::do_check_trigger(FailureType failure_type) noexcept
{
    PrimeState& state = get();
    if (PrimeMode* p = state.slots[failure_type].get())
        return p->check_trigger();
    return false;
}

#endif // REALM_ENABLE_SIMULATED_FAILURE

namespace {

class ErrorCategory: public std::error_category {
public:
    const char* name() const noexcept override;
    std::string message(int) const override;
};

const ErrorCategory g_error_category{};

const char* ErrorCategory::name() const noexcept
{
    return "realm.simulated_failure";
}

std::string ErrorCategory::message(int value) const
{
    switch (SimulatedFailure::FailureType(value)) {
        case SimulatedFailure::generic:
            return "Simulated failure (generic)";
        case SimulatedFailure::slab_alloc__reset_free_space_tracking:
            return "Simulated failure (slab_alloc__reset_free_space_tracking)";
        case SimulatedFailure::slab_alloc__remap:
            return "Simulated failure (slab_alloc__remap)";
        case SimulatedFailure::shared_group__grow_reader_mapping:
            return "Simulated failure (shared_group__grow_reader_mapping)";
        case SimulatedFailure::sync_client__read_head:
            return "Simulated failure (sync_client__read_head)";
        case SimulatedFailure::sync_server__read_head:
            return "Simulated failure (sync_server__read_head)";
        case SimulatedFailure::_num_failure_types:
            break;
    }
    REALM_ASSERT(false);
    return std::string();
}

} // unnamed namespace

namespace realm {
namespace _impl {

std::error_code make_error_code(SimulatedFailure::FailureType failure_type) noexcept
{
    return std::error_code(failure_type, g_error_category);
}

} // namespace _impl
} // namespace realm
<commit_msg>Use m_ for member variables in RandomPrimeMode for consistency and to avoid shadowing in the constructor.<commit_after>#include <memory>
#include <algorithm>
#include <stdexcept>
#include <system_error>
#include <random>

#include <realm/util/features.h>
#include <realm/util/assert.hpp>
#include <realm/util/basic_system_errors.hpp>
#include <realm/impl/simulated_failure.hpp>

#if REALM_PLATFORM_APPLE
#  define USE_PTHREADS_IMPL 1
#else
#  define USE_PTHREADS_IMPL 0
#endif

#if USE_PTHREADS_IMPL
#  include <pthread.h>
#endif

using namespace realm;
using namespace realm::_impl;

#ifdef REALM_ENABLE_SIMULATED_FAILURE

namespace {

const int num_failure_types = SimulatedFailure::_num_failure_types;

struct PrimeMode {
    virtual bool check_trigger() noexcept = 0;
    virtual ~PrimeMode() noexcept {}
};

struct PrimeState {
    std::unique_ptr<PrimeMode> slots[num_failure_types];
};

struct OneShotPrimeMode: PrimeMode {
    bool triggered = false;
    bool check_trigger() noexcept override
    {
        if (triggered)
            return false;
        triggered = true;
        return true;
    }
};

struct RandomPrimeMode: PrimeMode {
    std::mt19937_64 m_random;
    std::uniform_int_distribution<int> m_dist;
    int m_n;
    RandomPrimeMode(int n, int m, uint_fast64_t seed):
        m_random(seed),
        m_dist(0, m-1),
        m_n(n)
    {
        REALM_ASSERT(n >= 0 && m > 0);
    }
    bool check_trigger() noexcept override
    {
        int i = m_dist(m_random);
        return i < m_n;
    }
};

#  if !USE_PTHREADS_IMPL

thread_local PrimeState t_prime_state;

PrimeState& get() noexcept
{
    return t_prime_state;
}

#  else // USE_PTHREADS_IMPL

pthread_key_t key;
pthread_once_t key_once = PTHREAD_ONCE_INIT;

void destroy(void* ptr) noexcept
{
    PrimeState* prime_state = static_cast<PrimeState*>(ptr);
    delete prime_state;
}

void create() noexcept
{
    int ret = pthread_key_create(&key, &destroy);
    if (REALM_UNLIKELY(ret != 0)) {
        std::error_code ec = util::make_basic_system_error_code(errno);
        throw std::system_error(ec); // Termination intended
    }
}

PrimeState& get() noexcept
{
    pthread_once(&key_once, &create);
    void* ptr = pthread_getspecific(key);
    PrimeState* prime_state = static_cast<PrimeState*>(ptr);
    if (!prime_state) {
        prime_state = new PrimeState; // Throws with intended termination
        int ret = pthread_setspecific(key, prime_state);
        if (REALM_UNLIKELY(ret != 0)) {
            std::error_code ec = util::make_basic_system_error_code(errno);
            throw std::system_error(ec); // Termination intended
        }
    }
    return *prime_state;
}

#  endif // USE_PTHREADS_IMPL

} // unnamed namespace

void SimulatedFailure::do_prime_one_shot(FailureType failure_type)
{
    PrimeState& state = get();
    if (state.slots[failure_type])
        throw std::runtime_error("Already primed");
    state.slots[failure_type].reset(new OneShotPrimeMode); // Throws
}

void SimulatedFailure::do_prime_random(FailureType failure_type, int n, int m, uint_fast64_t seed)
{
    PrimeState& state = get();
    if (state.slots[failure_type])
        throw std::runtime_error("Already primed");
    state.slots[failure_type].reset(new RandomPrimeMode(n, m, seed)); // Throws
}

void SimulatedFailure::do_unprime(FailureType failure_type) noexcept
{
    PrimeState& state = get();
    state.slots[failure_type].reset();
}

bool SimulatedFailure::do_check_trigger(FailureType failure_type) noexcept
{
    PrimeState& state = get();
    if (PrimeMode* p = state.slots[failure_type].get())
        return p->check_trigger();
    return false;
}

#endif // REALM_ENABLE_SIMULATED_FAILURE

namespace {

class ErrorCategory: public std::error_category {
public:
    const char* name() const noexcept override;
    std::string message(int) const override;
};

const ErrorCategory g_error_category{};

const char* ErrorCategory::name() const noexcept
{
    return "realm.simulated_failure";
}

std::string ErrorCategory::message(int value) const
{
    switch (SimulatedFailure::FailureType(value)) {
        case SimulatedFailure::generic:
            return "Simulated failure (generic)";
        case SimulatedFailure::slab_alloc__reset_free_space_tracking:
            return "Simulated failure (slab_alloc__reset_free_space_tracking)";
        case SimulatedFailure::slab_alloc__remap:
            return "Simulated failure (slab_alloc__remap)";
        case SimulatedFailure::shared_group__grow_reader_mapping:
            return "Simulated failure (shared_group__grow_reader_mapping)";
        case SimulatedFailure::sync_client__read_head:
            return "Simulated failure (sync_client__read_head)";
        case SimulatedFailure::sync_server__read_head:
            return "Simulated failure (sync_server__read_head)";
        case SimulatedFailure::_num_failure_types:
            break;
    }
    REALM_ASSERT(false);
    return std::string();
}

} // unnamed namespace

namespace realm {
namespace _impl {

std::error_code make_error_code(SimulatedFailure::FailureType failure_type) noexcept
{
    return std::error_code(failure_type, g_error_category);
}

} // namespace _impl
} // namespace realm
<|endoftext|>


<commit_before>//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements LLVMContext, as a wrapper around the opaque
//  class LLVMContextImpl.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/LLVMContext.h"
#include "LLVMContextImpl.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/SourceMgr.h"
#include <cctype>
using namespace llvm;

static ManagedStatic<LLVMContext> GlobalContext;

LLVMContext& llvm::getGlobalContext() {
  return *GlobalContext;
}

LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
  // Create the fixed metadata kinds. This is done in the same order as the
  // MD_* enum values so that they correspond.

  // Create the 'dbg' metadata kind.
  unsigned DbgID = getMDKindID("dbg");
  assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;

  // Create the 'tbaa' metadata kind.
  unsigned TBAAID = getMDKindID("tbaa");
  assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;

  // Create the 'prof' metadata kind.
  unsigned ProfID = getMDKindID("prof");
  assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;

  // Create the 'fpmath' metadata kind.
  unsigned FPAccuracyID = getMDKindID("fpmath");
  assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
  (void)FPAccuracyID;

  // Create the 'range' metadata kind.
  unsigned RangeID = getMDKindID("range");
  assert(RangeID == MD_range && "range kind id drifted");
  (void)RangeID;

  // Create the 'tbaa.struct' metadata kind.
  unsigned TBAAStructID = getMDKindID("tbaa.struct");
  assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
  (void)TBAAStructID;

  // Create the 'invariant.load' metadata kind.
  unsigned InvariantLdId = getMDKindID("invariant.load");
  assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
  (void)InvariantLdId;
}
LLVMContext::~LLVMContext() { delete pImpl; }

void LLVMContext::addModule(Module *M) {
  pImpl->OwnedModules.insert(M);
}

void LLVMContext::removeModule(Module *M) {
  pImpl->OwnedModules.erase(M);
}

//===----------------------------------------------------------------------===//
// Recoverable Backend Errors
//===----------------------------------------------------------------------===//

void LLVMContext::
setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
                              void *DiagContext) {
  pImpl->InlineAsmDiagHandler = DiagHandler;
  pImpl->InlineAsmDiagContext = DiagContext;
}

/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
/// setInlineAsmDiagnosticHandler.
LLVMContext::InlineAsmDiagHandlerTy
LLVMContext::getInlineAsmDiagnosticHandler() const {
  return pImpl->InlineAsmDiagHandler;
}

/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
/// setInlineAsmDiagnosticHandler.
void *LLVMContext::getInlineAsmDiagnosticContext() const {
  return pImpl->InlineAsmDiagContext;
}

void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
                                       void *DiagnosticContext) {
  pImpl->DiagnosticHandler = DiagnosticHandler;
  pImpl->DiagnosticContext = DiagnosticContext;
}

LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
  return pImpl->DiagnosticHandler;
}

void *LLVMContext::getDiagnosticContext() const {
  return pImpl->DiagnosticContext;
}

void LLVMContext::emitError(const Twine &ErrorStr) {
  diagnose(DiagnosticInfoInlineAsm(ErrorStr));
}

void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
  assert (I && "Invalid instruction");
  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
}

void LLVMContext::diagnose(const DiagnosticInfo &DI) {
  // If there is a report handler, use it.
  if (pImpl->DiagnosticHandler) {
    pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);
    return;
  }
  // Otherwise, print the message with a prefix based on the severity.
  std::string MsgStorage;
  raw_string_ostream Stream(MsgStorage);
  DiagnosticPrinterRawOStream DP(Stream);
  DI.print(DP);
  Stream.flush();
  switch (DI.getSeverity()) {
  case DS_Error:
    errs() << "error: " << MsgStorage << "\n";
    exit(1);
  case DS_Warning:
    errs() << "warning: " << MsgStorage << "\n";
    break;
  case DS_Remark:
    errs() << "remark: " << MsgStorage << "\n";
    break;
  case DS_Note:
    errs() << "note: " << MsgStorage << "\n";
    break;
  }
}

void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
}

void LLVMContext::emitOptimizationRemark(const char *PassName,
                                         const Function &Fn,
                                         const DebugLoc &DLoc,
                                         const Twine &Msg) {
  if (pImpl->optimizationRemarksEnabledFor(PassName))
    diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
}

//===----------------------------------------------------------------------===//
// Metadata Kind Uniquing
//===----------------------------------------------------------------------===//

#ifndef NDEBUG
/// isValidName - Return true if Name is a valid custom metadata handler name.
static bool isValidName(StringRef MDName) {
  if (MDName.empty())
    return false;

  if (!std::isalpha(static_cast<unsigned char>(MDName[0])))
    return false;

  for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
       ++I) {
    if (!std::isalnum(static_cast<unsigned char>(*I)) && *I != '_' &&
        *I != '-' && *I != '.')
      return false;
  }
  return true;
}
#endif

/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
unsigned LLVMContext::getMDKindID(StringRef Name) const {
  assert(isValidName(Name) && "Invalid MDNode name");

  // If this is new, assign it its ID.
  return
    pImpl->CustomMDKindNames.GetOrCreateValue(
      Name, pImpl->CustomMDKindNames.size()).second;
}

/// getHandlerNames - Populate client supplied smallvector using custome
/// metadata name and ID.
void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
  Names.resize(pImpl->CustomMDKindNames.size());
  for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
       E = pImpl->CustomMDKindNames.end(); I != E; ++I)
    Names[I->second] = I->first();
}
<commit_msg>Allow diagnostic handlers to check for optimization remarks.<commit_after>//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements LLVMContext, as a wrapper around the opaque
//  class LLVMContextImpl.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/LLVMContext.h"
#include "LLVMContextImpl.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/SourceMgr.h"
#include <cctype>
using namespace llvm;

static ManagedStatic<LLVMContext> GlobalContext;

LLVMContext& llvm::getGlobalContext() {
  return *GlobalContext;
}

LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
  // Create the fixed metadata kinds. This is done in the same order as the
  // MD_* enum values so that they correspond.

  // Create the 'dbg' metadata kind.
  unsigned DbgID = getMDKindID("dbg");
  assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;

  // Create the 'tbaa' metadata kind.
  unsigned TBAAID = getMDKindID("tbaa");
  assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;

  // Create the 'prof' metadata kind.
  unsigned ProfID = getMDKindID("prof");
  assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;

  // Create the 'fpmath' metadata kind.
  unsigned FPAccuracyID = getMDKindID("fpmath");
  assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
  (void)FPAccuracyID;

  // Create the 'range' metadata kind.
  unsigned RangeID = getMDKindID("range");
  assert(RangeID == MD_range && "range kind id drifted");
  (void)RangeID;

  // Create the 'tbaa.struct' metadata kind.
  unsigned TBAAStructID = getMDKindID("tbaa.struct");
  assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
  (void)TBAAStructID;

  // Create the 'invariant.load' metadata kind.
  unsigned InvariantLdId = getMDKindID("invariant.load");
  assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
  (void)InvariantLdId;
}
LLVMContext::~LLVMContext() { delete pImpl; }

void LLVMContext::addModule(Module *M) {
  pImpl->OwnedModules.insert(M);
}

void LLVMContext::removeModule(Module *M) {
  pImpl->OwnedModules.erase(M);
}

//===----------------------------------------------------------------------===//
// Recoverable Backend Errors
//===----------------------------------------------------------------------===//

void LLVMContext::
setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
                              void *DiagContext) {
  pImpl->InlineAsmDiagHandler = DiagHandler;
  pImpl->InlineAsmDiagContext = DiagContext;
}

/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
/// setInlineAsmDiagnosticHandler.
LLVMContext::InlineAsmDiagHandlerTy
LLVMContext::getInlineAsmDiagnosticHandler() const {
  return pImpl->InlineAsmDiagHandler;
}

/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
/// setInlineAsmDiagnosticHandler.
void *LLVMContext::getInlineAsmDiagnosticContext() const {
  return pImpl->InlineAsmDiagContext;
}

void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
                                       void *DiagnosticContext) {
  pImpl->DiagnosticHandler = DiagnosticHandler;
  pImpl->DiagnosticContext = DiagnosticContext;
}

LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
  return pImpl->DiagnosticHandler;
}

void *LLVMContext::getDiagnosticContext() const {
  return pImpl->DiagnosticContext;
}

void LLVMContext::emitError(const Twine &ErrorStr) {
  diagnose(DiagnosticInfoInlineAsm(ErrorStr));
}

void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
  assert (I && "Invalid instruction");
  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
}

void LLVMContext::diagnose(const DiagnosticInfo &DI) {
  // If there is a report handler, use it.
  if (pImpl->DiagnosticHandler) {
    pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);
    return;
  }

  // Optimization remarks are selective. They need to check whether
  // the regexp pattern, passed via -pass-remarks, matches the name
  // of the pass that is emitting the diagnostic. If there is no match,
  // ignore the diagnostic and return.
  if (DI.getKind() == llvm::DK_OptimizationRemark &&
      !pImpl->optimizationRemarksEnabledFor(
          cast<DiagnosticInfoOptimizationRemark>(DI).getPassName()))
    return;

  // Otherwise, print the message with a prefix based on the severity.
  std::string MsgStorage;
  raw_string_ostream Stream(MsgStorage);
  DiagnosticPrinterRawOStream DP(Stream);
  DI.print(DP);
  Stream.flush();
  switch (DI.getSeverity()) {
  case DS_Error:
    errs() << "error: " << MsgStorage << "\n";
    exit(1);
  case DS_Warning:
    errs() << "warning: " << MsgStorage << "\n";
    break;
  case DS_Remark:
    errs() << "remark: " << MsgStorage << "\n";
    break;
  case DS_Note:
    errs() << "note: " << MsgStorage << "\n";
    break;
  }
}

void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
}

void LLVMContext::emitOptimizationRemark(const char *PassName,
                                         const Function &Fn,
                                         const DebugLoc &DLoc,
                                         const Twine &Msg) {
  diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
}

//===----------------------------------------------------------------------===//
// Metadata Kind Uniquing
//===----------------------------------------------------------------------===//

#ifndef NDEBUG
/// isValidName - Return true if Name is a valid custom metadata handler name.
static bool isValidName(StringRef MDName) {
  if (MDName.empty())
    return false;

  if (!std::isalpha(static_cast<unsigned char>(MDName[0])))
    return false;

  for (StringRef::iterator I = MDName.begin() + 1, E = MDName.end(); I != E;
       ++I) {
    if (!std::isalnum(static_cast<unsigned char>(*I)) && *I != '_' &&
        *I != '-' && *I != '.')
      return false;
  }
  return true;
}
#endif

/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
unsigned LLVMContext::getMDKindID(StringRef Name) const {
  assert(isValidName(Name) && "Invalid MDNode name");

  // If this is new, assign it its ID.
  return
    pImpl->CustomMDKindNames.GetOrCreateValue(
      Name, pImpl->CustomMDKindNames.size()).second;
}

/// getHandlerNames - Populate client supplied smallvector using custome
/// metadata name and ID.
void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
  Names.resize(pImpl->CustomMDKindNames.size());
  for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
       E = pImpl->CustomMDKindNames.end(); I != E; ++I)
    Names[I->second] = I->first();
}
<|endoftext|>