<commit_before>
#include "impl.hh"
#include "persistence.hh"
#include <Utils/error_handling.hh>
#include <Utils/statistics.hh>
#include <Geo/vector.hh>
#include <Geo/iterate.hh>

namespace Topo {

bool EE<Type::BODY>::insert_child(IBase* _el, size_t _pos)
{
  auto res = UpEntity<Type::BODY>::insert_child(_el, _pos);
  ordered_children_ &= !res;
  return res;
}

bool EE<Type::BODY>::replace_child(size_t _pos, IBase* _new_obj)
{
  auto res = UpEntity<Type::BODY>::replace_child(_pos, _new_obj);
  ordered_children_ &= !res;
  return res;
}

namespace {
bool compare_i_base(const IBase* _a, const IBase* _b) { return _a->id() < _b->id(); };
}//namespace

 // search for an element in the range [0, _end[ in reverse order.
size_t EE<Type::BODY>::find_child(const IBase* _el, size_t _end) const
{
  if (_end < low_elems_.size() || !ordered_children_)
    return UpEntity<Type::BODY>::find_child(_el, _end);

  auto it_pos = std::lower_bound(
    low_elems_.cbegin(), low_elems_.cend(), _el, compare_i_base);
  if (it_pos == low_elems_.end() || *it_pos != _el)
    return SIZE_MAX;

  return it_pos - low_elems_.begin();
}

void EE<Type::BODY>::optimize()
{
  if (ordered_children_)
    return;
  std::sort(low_elems_.begin(), low_elems_.end(), compare_i_base);
  ordered_children_ = true;
}

bool EE<Type::BODY>::remove()
{
  auto res = UpEntity<Type::BODY>::remove();
  ordered_children_ |= res;
  return res;
}

// Bodies have an optimized functions to remove childrens.
bool EE<Type::BODY>::remove_children(
  std::vector<IBase*>& _faces_to_remove)
{
  optimize();
  std::vector<IBase*> low_elems;

  std::set_difference(
    low_elems_.cbegin(), low_elems_.cend(),
    _faces_to_remove.cbegin(), _faces_to_remove.cend(),
    std::back_inserter(low_elems), compare_i_base);
  low_elems_ = std::move(low_elems);
  return true;
}

bool EE<Type::FACE>::reverse()
{
  std::reverse(low_elems_.begin(), low_elems_.end());
  return true;
}

Geo::Point EE<Type::FACE>::internal_point() const
{
  Geo::Point pt = {};
  if (!low_elems_.empty())
  {
    for (const auto el : low_elems_)
      pt += el->internal_point();
    pt /= double(low_elems_.size());
  }
  return pt;
}

Geo::Range<3> EE<Type::FACE>::box() const
{
  Utils::FindMax<double> max_tol;
  Geo::Range<3> b;
  for (const auto el : low_elems_)
  {
    max_tol.add(el->tolerance());
    auto pt = el->internal_point();
    max_tol.add(Geo::epsilon(pt));
    b += el->internal_point();
  }
  b.fatten(1.e-5);
  return b;
}

// A face can have all loops or all not loops.
bool EE<Type::FACE>::check()
{
  if (low_elems_.empty())
    return true;
  size_t loop_nmbr = 0;
  for (const auto el : low_elems_)
    loop_nmbr += el->type() == Type::LOOP;
  return loop_nmbr == 0 || loop_nmbr == low_elems_.size();
}

bool EE<Type::EDGE>::geom(Geo::Segment& /*_seg*/) const
{
  return false;
}

bool EE<Type::EDGE>::set_geom(const Geo::Segment&)
{
  return false;
}

double EE<Type::VERTEX>::tolerance() const
{
  return std::max(tol_, Geo::epsilon(pt_));
}

Geo::Range<3> EE<Type::VERTEX>::box() const
{
  Geo::Range<3> b;
  b += pt_;
  b.fatten(std::max(tol_, Geo::epsilon(pt_)));
  return b;
}

bool EdgeRef::geom(Geo::Segment& _seg) const
{
  return verts_[0]->geom(_seg[0]) && verts_[1]->geom(_seg[1]);
}

double EdgeRef::tolerance() const
{
  return std::max(verts_[0]->tolerance(), verts_[1]->tolerance());
}

Geo::Point EdgeRef::internal_point() const
{
  Geo::Segment seg;
  geom(seg);
  return (seg[0] + seg[1]) * 0.5;
}

Geo::Range<3> EdgeRef::box() const
{
  Geo::Range<3> b;
  Geo::Segment seg;
  geom(seg);
  for (const auto& pt : seg)
    b += pt;
  b.fatten(tolerance());
  return b;
}

bool EdgeRef::operator<(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::EDGE_REF)
    return E<Type::EDGE>::operator<(_oth);
  auto oth = static_cast<const EdgeRef&>(_oth);
  return verts_[0] < oth.verts_[0] ||
    (verts_[0] == oth.verts_[0] && verts_[1] < oth.verts_[1]);
}

bool EdgeRef::operator==(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::EDGE_REF)
    return E<Type::EDGE>::operator==(_oth);
  auto oth = static_cast<const EdgeRef&>(_oth);
  return verts_[0] == oth.verts_[0] && verts_[1] == oth.verts_[1];
}

void EdgeRef::finalise()
{
  if (verts_[1] < verts_[0])
    std::swap(verts_[0], verts_[1]);
}

namespace {

struct Vertices
{
  Vertices(const IBase* _loop, size_t _ind)
  {
    auto sz = _loop->size(Topo::Direction::Down);
    THROW_IF(_ind >= sz, "Bad toplogy access");
    auto add_vertex = [this, &_loop](size_t _i, size_t _ind)
    {
      auto vert = _loop->get(Topo::Direction::Down, _ind);
      THROW_IF(vert->type() != Topo::Type::VERTEX, "Unexpected type");
      verts_[_i].reset(static_cast<E<Type::VERTEX> *>(vert));
    };
    add_vertex(0, _ind);
    if (++_ind >= sz)
      _ind = 0;
    add_vertex(1, _ind);
  }
  Wrap<Type::VERTEX> verts_[2];
};
}//namespace

CoEdgeRef::~CoEdgeRef()
{
  if (loop_) loop_->release_ref();
}

void CoEdgeRef::set_loop(IBase* _loop)
{
  if (loop_ == _loop)
    return;
  if (loop_)
    loop_->release_ref();
  loop_ = _loop;
  if (loop_)
    loop_->add_ref();
}

bool CoEdgeRef::geom(Geo::Segment& _seg) const
{
  Vertices verts(loop_, ind_);
  return verts.verts_[0]->geom(_seg[0]) && verts.verts_[1]->geom(_seg[1]);
}

double CoEdgeRef::tolerance() const
{
  Vertices verts(loop_, ind_);
  return std::max(verts.verts_[0]->tolerance(), verts.verts_[1]->tolerance());
}

bool CoEdgeRef::operator<(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::COEDGE_REF)
    return E<Type::COEDGE>::operator<(_oth);
  auto oth = static_cast<const CoEdgeRef&>(_oth);
  return loop_ < oth.loop_ || loop_ == oth.loop_ && ind_ < oth.ind_;
}

bool CoEdgeRef::operator==(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::COEDGE_REF)
    return false;
  auto oth = static_cast<const CoEdgeRef&>(_oth);
  return loop_ == oth.loop_ && ind_ == oth.ind_;
}

template<Type typeT>
void save_base_entity(std::ostream& _ostr, const Base<typeT>* _base_ent, ISaver* _psav)
{
  const auto elem_nmbr = _base_ent->size(Direction::Down);
  _ostr << Utils::BinData<size_t>(elem_nmbr);
  for (size_t i = 0; i < elem_nmbr; ++i)
  {
    auto up_el = _base_ent->get(Direction::Down, i);
    _psav->save(up_el);
  }
}

void load_base_entity(std::istream& _istr, IBase* _base_ent, ILoader* _pload)
{
  size_t elem_nmbr;
  _istr >> Utils::BinData<size_t>(elem_nmbr);
  for (size_t i = 0; i < elem_nmbr; ++i)
  {
    auto obj = _pload->load();
    _base_ent->insert_child(static_cast<IBase*>(obj.get()));
  }
}

template <> void object_saver<SubType::VERTEX>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  auto vert = static_cast<const EE<Type::VERTEX>*>(_obj);
  save_base_entity<Type::VERTEX>(_ostr, vert, _psav);
  Geo::Point pt;
  vert->geom(pt);
  _ostr << pt;
  _ostr << Utils::BinData<double>(vert->tolerance());
}

template <> WrapObject
object_loader<SubType::VERTEX>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::VERTEX> vert;
  load_base_entity(_istr, vert.make<EE<Type::VERTEX>>(), _pload);

  Geo::Point pt;
  _istr >> pt;
  vert->set_geom(pt);
  double tol;
  _istr >> Utils::BinData<double>(tol);
  vert->set_tolerance(tol);
  return WrapObject(vert.get());
}

template <> void object_saver<SubType::EDGE>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::EDGE>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::EDGE_REF>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::EDGE_REF>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::COEDGE>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::COEDGE>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::COEDGE_REF>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::COEDGE_REF>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::LOOP>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  save_base_entity<Type::LOOP>(
    _ostr, static_cast<const EE<Type::LOOP>*>(_obj), _psav);
}

template <> WrapObject
object_loader<SubType::LOOP>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::LOOP> lp;
  load_base_entity(_istr, lp.make<EE<Type::LOOP>>(), _pload);
  return lp.get();
}

template <> void object_saver<SubType::LOOP_REF>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::LOOP_REF>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::FACE>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  save_base_entity<Type::FACE>(
    _ostr, static_cast<const EE<Type::FACE>*>(_obj), _psav);
}

template <> WrapObject
object_loader<SubType::FACE>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::FACE> face;
  load_base_entity(_istr, face.make<EE<Type::FACE>>(), _pload);
  return face.get();
}

template <> void object_saver<SubType::BODY>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  save_base_entity<Type::BODY>(
    _ostr, static_cast<const EE<Type::BODY>*>(_obj), _psav);
}

template <> WrapObject
object_loader<SubType::BODY>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::BODY> body;
  load_base_entity(_istr, body.make<EE<Type::BODY>>(), _pload);
  return body.get();
}
}//namespace Topo
<commit_msg>Loop element integration.<commit_after>
#include "impl.hh"
#include "persistence.hh"
#include <Utils/error_handling.hh>
#include <Utils/statistics.hh>
#include <Geo/vector.hh>
#include <Geo/iterate.hh>

namespace Topo {

bool EE<Type::BODY>::insert_child(IBase* _el, size_t _pos)
{
  auto res = UpEntity<Type::BODY>::insert_child(_el, _pos);
  ordered_children_ &= !res;
  return res;
}

bool EE<Type::BODY>::replace_child(size_t _pos, IBase* _new_obj)
{
  auto res = UpEntity<Type::BODY>::replace_child(_pos, _new_obj);
  ordered_children_ &= !res;
  return res;
}

namespace {
bool compare_i_base(const IBase* _a, const IBase* _b) { return _a->id() < _b->id(); };
}//namespace

 // search for an element in the range [0, _end[ in reverse order.
size_t EE<Type::BODY>::find_child(const IBase* _el, size_t _end) const
{
  if (_end < low_elems_.size() || !ordered_children_)
    return UpEntity<Type::BODY>::find_child(_el, _end);

  auto it_pos = std::lower_bound(
    low_elems_.cbegin(), low_elems_.cend(), _el, compare_i_base);
  if (it_pos == low_elems_.end() || *it_pos != _el)
    return SIZE_MAX;

  return it_pos - low_elems_.begin();
}

void EE<Type::BODY>::optimize()
{
  if (ordered_children_)
    return;
  std::sort(low_elems_.begin(), low_elems_.end(), compare_i_base);
  ordered_children_ = true;
}

bool EE<Type::BODY>::remove()
{
  auto res = UpEntity<Type::BODY>::remove();
  ordered_children_ |= res;
  return res;
}

// Bodies have an optimized functions to remove childrens.
bool EE<Type::BODY>::remove_children(
  std::vector<IBase*>& _faces_to_remove)
{
  optimize();
  std::vector<IBase*> low_elems;

  std::set_difference(
    low_elems_.cbegin(), low_elems_.cend(),
    _faces_to_remove.cbegin(), _faces_to_remove.cend(),
    std::back_inserter(low_elems), compare_i_base);
  low_elems_ = std::move(low_elems);
  return true;
}

bool EE<Type::FACE>::reverse()
{
  std::reverse(low_elems_.begin(), low_elems_.end());
  return true;
}

Geo::Point EE<Type::FACE>::internal_point() const
{
  Geo::Point pt = {};
  if (!low_elems_.empty())
  {
    for (const auto el : low_elems_)
      pt += el->internal_point();
    pt /= double(low_elems_.size());
  }
  return pt;
}

Geo::Range<3> EE<Type::FACE>::box() const
{
  Utils::FindMax<double> max_tol;
  Geo::Range<3> b;
  for (const auto el : low_elems_)
  {
    max_tol.add(el->tolerance());
    auto pt = el->internal_point();
    max_tol.add(Geo::epsilon(pt));
    b += el->internal_point();
  }
  b.fatten(1.e-5);
  return b;
}

// A face can have all loops or all not loops.
bool EE<Type::FACE>::check()
{
  if (low_elems_.empty())
    return true;
  size_t loop_nmbr = 0;
  for (const auto el : low_elems_)
    loop_nmbr += el->type() == Type::LOOP;
  return loop_nmbr == 0 || loop_nmbr == low_elems_.size();
}

bool EE<Type::EDGE>::geom(Geo::Segment& /*_seg*/) const
{
  return false;
}

bool EE<Type::EDGE>::set_geom(const Geo::Segment&)
{
  return false;
}

double EE<Type::VERTEX>::tolerance() const
{
  return std::max(tol_, Geo::epsilon(pt_));
}

Geo::Range<3> EE<Type::VERTEX>::box() const
{
  Geo::Range<3> b;
  b += pt_;
  b.fatten(std::max(tol_, Geo::epsilon(pt_)));
  return b;
}

bool EdgeRef::geom(Geo::Segment& _seg) const
{
  return verts_[0]->geom(_seg[0]) && verts_[1]->geom(_seg[1]);
}

double EdgeRef::tolerance() const
{
  return std::max(verts_[0]->tolerance(), verts_[1]->tolerance());
}

Geo::Point EdgeRef::internal_point() const
{
  Geo::Segment seg;
  geom(seg);
  return (seg[0] + seg[1]) * 0.5;
}

Geo::Range<3> EdgeRef::box() const
{
  Geo::Range<3> b;
  Geo::Segment seg;
  geom(seg);
  for (const auto& pt : seg)
    b += pt;
  b.fatten(tolerance());
  return b;
}

bool EdgeRef::operator<(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::EDGE_REF)
    return E<Type::EDGE>::operator<(_oth);
  auto oth = static_cast<const EdgeRef&>(_oth);
  return verts_[0] < oth.verts_[0] ||
    (verts_[0] == oth.verts_[0] && verts_[1] < oth.verts_[1]);
}

bool EdgeRef::operator==(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::EDGE_REF)
    return E<Type::EDGE>::operator==(_oth);
  auto oth = static_cast<const EdgeRef&>(_oth);
  return verts_[0] == oth.verts_[0] && verts_[1] == oth.verts_[1];
}

void EdgeRef::finalise()
{
  if (verts_[1] < verts_[0])
    std::swap(verts_[0], verts_[1]);
}

namespace {

struct Vertices
{
  Vertices(const IBase* _loop, size_t _ind)
  {
    auto sz = _loop->size(Topo::Direction::Down);
    THROW_IF(_ind >= sz, "Bad toplogy access");
    auto add_vertex = [this, &_loop](size_t _i, size_t _ind)
    {
      auto vert = _loop->get(Topo::Direction::Down, _ind);
      THROW_IF(vert->type() != Topo::Type::VERTEX, "Unexpected type");
      verts_[_i].reset(static_cast<E<Type::VERTEX> *>(vert));
    };
    add_vertex(0, _ind);
    if (++_ind >= sz)
      _ind = 0;
    add_vertex(1, _ind);
  }
  Wrap<Type::VERTEX> verts_[2];
};

void assign_ibase(IBase*& _to, IBase* _from)
{
  if (_to == _from)
    return;
  if (_to)
    _to->release_ref();
  _to = _from;
  if (_to)
    _to->add_ref();
}

}//namespace

CoEdgeRef::~CoEdgeRef()
{
  if (loop_) loop_->release_ref();
}

void CoEdgeRef::set_loop(IBase* _loop)
{
  assign_ibase(loop_, _loop);
}

bool CoEdgeRef::geom(Geo::Segment& _seg) const
{
  Vertices verts(loop_, ind_);
  return verts.verts_[0]->geom(_seg[0]) && verts.verts_[1]->geom(_seg[1]);
}

double CoEdgeRef::tolerance() const
{
  Vertices verts(loop_, ind_);
  return std::max(verts.verts_[0]->tolerance(), verts.verts_[1]->tolerance());
}

bool CoEdgeRef::operator<(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::COEDGE_REF)
    return E<Type::COEDGE>::operator<(_oth);
  auto oth = static_cast<const CoEdgeRef&>(_oth);
  return loop_ < oth.loop_ || loop_ == oth.loop_ && ind_ < oth.ind_;
}

bool CoEdgeRef::operator==(const Object& _oth) const
{
  if (_oth.sub_type() != SubType::COEDGE_REF)
    return false;
  auto oth = static_cast<const CoEdgeRef&>(_oth);
  return loop_ == oth.loop_ && ind_ == oth.ind_;
}

LoopRef::~LoopRef()
{
  if (loop_) loop_->release_ref();
}

IBase* LoopRef::loop() const { return loop_; }

void LoopRef::set_loop(IBase* _loop)
{
  assign_ibase(loop_, _loop);
}

template<Type typeT>
void save_base_entity(std::ostream& _ostr, const Base<typeT>* _base_ent, ISaver* _psav)
{
  const auto elem_nmbr = _base_ent->size(Direction::Down);
  _ostr << Utils::BinData<size_t>(elem_nmbr);
  for (size_t i = 0; i < elem_nmbr; ++i)
  {
    auto up_el = _base_ent->get(Direction::Down, i);
    _psav->save(up_el);
  }
}

void load_base_entity(std::istream& _istr, IBase* _base_ent, ILoader* _pload)
{
  size_t elem_nmbr;
  _istr >> Utils::BinData<size_t>(elem_nmbr);
  for (size_t i = 0; i < elem_nmbr; ++i)
  {
    auto obj = _pload->load();
    _base_ent->insert_child(static_cast<IBase*>(obj.get()));
  }
}

template <> void object_saver<SubType::VERTEX>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  auto vert = static_cast<const EE<Type::VERTEX>*>(_obj);
  save_base_entity<Type::VERTEX>(_ostr, vert, _psav);
  Geo::Point pt;
  vert->geom(pt);
  _ostr << pt;
  _ostr << Utils::BinData<double>(vert->tolerance());
}

template <> WrapObject
object_loader<SubType::VERTEX>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::VERTEX> vert;
  load_base_entity(_istr, vert.make<EE<Type::VERTEX>>(), _pload);

  Geo::Point pt;
  _istr >> pt;
  vert->set_geom(pt);
  double tol;
  _istr >> Utils::BinData<double>(tol);
  vert->set_tolerance(tol);
  return WrapObject(vert.get());
}

template <> void object_saver<SubType::EDGE>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::EDGE>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::EDGE_REF>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::EDGE_REF>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::COEDGE>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::COEDGE>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::COEDGE_REF>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::COEDGE_REF>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::LOOP>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  save_base_entity<Type::LOOP>(
    _ostr, static_cast<const EE<Type::LOOP>*>(_obj), _psav);
}

template <> WrapObject
object_loader<SubType::LOOP>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::LOOP> lp;
  load_base_entity(_istr, lp.make<EE<Type::LOOP>>(), _pload);
  return lp.get();
}

template <> void object_saver<SubType::LOOP_REF>(std::ostream&, const Object*, ISaver*)
{
}

template <> WrapObject
object_loader<SubType::LOOP_REF>(std::istream&, ILoader*)
{
  return nullptr;
}

template <> void object_saver<SubType::FACE>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  save_base_entity<Type::FACE>(
    _ostr, static_cast<const EE<Type::FACE>*>(_obj), _psav);
}

template <> WrapObject
object_loader<SubType::FACE>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::FACE> face;
  load_base_entity(_istr, face.make<EE<Type::FACE>>(), _pload);
  return face.get();
}

template <> void object_saver<SubType::BODY>(
  std::ostream& _ostr, const Object* _obj, ISaver* _psav)
{
  save_base_entity<Type::BODY>(
    _ostr, static_cast<const EE<Type::BODY>*>(_obj), _psav);
}

template <> WrapObject
object_loader<SubType::BODY>(std::istream& _istr, ILoader* _pload)
{
  Topo::Wrap<Type::BODY> body;
  load_base_entity(_istr, body.make<EE<Type::BODY>>(), _pload);
  return body.get();
}
}//namespace Topo
<|endoftext|>


<commit_before>#ifndef HAVE_LLVM
#error "This code needs LLVM enabled"
#endif

#include <set>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>

// ignore unused parameters in LLVM libraries
#if (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/IRReader/IRReader.h>

#if LLVM_VERSION_MAJOR >= 4
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#else
#include <llvm/Bitcode/ReaderWriter.h>
#endif

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
#else
#pragma GCC diagnostic pop
#endif

#include "analysis/PointsTo/PointsToFlowInsensitive.h"
#include "analysis/PointsTo/PointsToFlowSensitive.h"
#include "analysis/PointsTo/Pointer.h"

#include "llvm/analysis/PointsTo/PointsTo.h"
#include "llvm/analysis/ReachingDefinitions/ReachingDefinitions.h"

#include "TimeMeasure.h"

using namespace dg;
using namespace dg::analysis;
using namespace dg::analysis::rd;
using llvm::errs;

static bool verbose = false;

static std::string
getInstName(const llvm::Value *val)
{
    std::ostringstream ostr;
    llvm::raw_os_ostream ro(ostr);

    assert(val);
    ro << *val;
    ro.flush();

    // break the string if it is too long
    return ostr.str();
}

static void printRDNodeType(enum RDNodeType type)
{
#define ELEM(t) case(t): do {printf("%s", #t); }while(0); break;
    switch(type) {
        ELEM(RDNodeType::ALLOC)
        ELEM(RDNodeType::DYN_ALLOC)
        ELEM(RDNodeType::STORE)
        ELEM(RDNodeType::PHI)
        ELEM(RDNodeType::CALL)
        ELEM(RDNodeType::CALL_RETURN)
        ELEM(RDNodeType::RETURN)
        ELEM(RDNodeType::NOOP)
        ELEM(RDNodeType::NONE)
        default:
            printf("unknown reaching definitions subgraph type");
    };
#undef ELEM
}

static inline void printAddress(RDNode *node, bool dot)
{
    if (dot)
        printf(" [%p]\\n", node);
    else
        printf(" [%p]\n", node);
}

static void
printName(RDNode *node, bool dot)
{
    if (node == rd::UNKNOWN_MEMORY) {
        printf("UNKNOWN MEMORY");
        return;
    }

    const char *name = nullptr;
#if 0
#ifdef DEBUG_ENABLED
    name = node->getName();
#endif
#endif
    std::string nm;
    if (!name) {
        if (!node->getUserData<llvm::Value>()) {
            printRDNodeType(node->getType());
            printAddress(node, dot);
            return;
        }

        nm = getInstName(node->getUserData<llvm::Value>());
        name = nm.c_str();
    }

    // escape the " character
    for (int i = 0; name[i] != '\0'; ++i) {
        // crop long names
        if (i >= 70) {
            printf(" ...");
            break;
        }

        if (name[i] == '"')
            putchar('\\');

        putchar(name[i]);
    }
}

static void
dumpMap(RDNode *node, bool dot = false)
{
    RDMap& map = node->getReachingDefinitions();
    for (const auto& it : map) {
        for (RDNode *site : it.second) {
            printName(it.first.target, dot);
            // don't print offsets with unknown memory
            if (it.first.target == rd::UNKNOWN_MEMORY) {
                printf(" => ");
            } else {
                if (it.first.offset.isUnknown())
                    printf(" | UNKNOWN | => ");
                else if (it.first.len.isUnknown())
                    printf(" | %lu - UNKNOWN | => ", *it.first.offset);
                else
                    printf(" | %lu - %lu | => ", *it.first.offset,
                           *it.first.offset + *it.first.len - 1);
            }

            printName(site, dot);
            if (dot)
                printf("\\n");
            else
                putchar('\n');
        }
    }
}

static void
dumpDefSites(const std::set<DefSite>& defs, const char *kind, bool dot = false)
{
    for (const DefSite& def : defs) {
        printf("%s: ", kind);
        printName(def.target, dot);
            if (def.offset.isUnknown())
                printf(" [ UNKNOWN ]");
            else
                printf(" [ %lu - %lu ]", *def.offset,
                       *def.offset + *def.len - 1);

            if (dot)
                printf("\\n");
            else
                putchar('\n');
    }
}

static void
dumpDefines(RDNode *node, bool dot = false)
{
    dumpDefSites(node->getDefines(), "DEF", dot);
}

static void
dumpOverwrites(RDNode *node, bool dot = false)
{
    dumpDefSites(node->getOverwrites(), "DEF strong", dot);
}

static void
dumpUses(RDNode *node, bool dot = false)
{
    dumpDefSites(node->getUses(), "USE", dot);
}

static void
dumpRDNode(RDNode *n)
{
    printf("NODE: ");
    printName(n, false);
    if (n->getSize() > 0)
        printf(" [size: %lu]", n->getSize());
    putchar('\n');
    dumpMap(n);
    printf("---\n");
}

static void
dumpRDdot(LLVMReachingDefinitions *RD)
{
    std::set<RDNode *> nodes;
    RD->getNodes(nodes);

    printf("digraph \"Reaching Definitions Subgraph\" {\n");

    /* dump nodes */
    for(RDNode *node : nodes) {
        printf("\tNODE%p [label=\"", node);
        printName(node, true);
        if (node->getSize() > 0)
            printf("\\n[size: %lu]\\n", node->getSize());
        printf("\\n-------------\\n");
        if (verbose) {
            dumpDefines(node, true);
            printf("-------------\\n");
            dumpOverwrites(node, true);
            printf("-------------\\n");
            dumpUses(node, true);
        }
            dumpMap(node, true /* dot */);

        printf("\" shape=box]\n");
    }

    /* dump edges */
    for (RDNode *node : nodes) {
        for (RDNode *succ : node->getSuccessors())
            printf("\tNODE%p -> NODE%p [penwidth=2]\n", node, succ);
    }

    std::unordered_map<RDNode*, unsigned> colors;
    for (auto& pair : RD->getSrg()) {
        RDNode *source = pair.first;
        for (auto& var_where: pair.second) {
            DefSite var = var_where.first;
            RDNode *dest = var_where.second;
            if (colors.find(var.target) == colors.end())
                colors[var.target] = rand();
            printf("\tNODE%p -> NODE%p [color=\"#%X\" style=\"dotted\"]", source, dest, colors[var.target]);
        }
    }

    printf("}\n");
}

static void
dumpRD(LLVMReachingDefinitions *RD, bool todot)
{
    assert(RD);

    if (todot)
        dumpRDdot(RD);
    else {
        std::set<RDNode *> nodes;
        RD->getNodes(nodes);

        for (RDNode *node : nodes)
            dumpRDNode(node);
    }
}

static void
dumpRDBlocksDot(LLVMReachingDefinitions &RD)
{
    const auto& blocks = RD.getBlocks();

    printf("digraph \"RDBlocks\" {\n");

    /* dump nodes */
    for (const auto& pair : blocks) {
        for (const auto& block : pair.second) {
            printf("\tNODE%p", block.get());
            printf("[label=\"%p\"shape=box]\n", block.get());
        }
    }

    for (const auto& pair : blocks) {
        for (const auto& block : pair.second) {
            for (const auto& edge : block->successors()) {
                printf("\tNODE%p -> NODE%p\n", block.get(), edge.target);
            }
        }
    }

    printf("}\n");

}

int main(int argc, char *argv[])
{
    llvm::Module *M;
    llvm::LLVMContext context;
    llvm::SMDiagnostic SMD;
    bool todot = false;
    bool blocks = false;
    const char *module = nullptr;
    uint64_t field_senitivity = UNKNOWN_OFFSET;
    bool rd_strong_update_unknown = false;
    uint32_t max_set_size = ~((uint32_t) 0);

    enum {
        FLOW_SENSITIVE = 1,
        FLOW_INSENSITIVE,
    } type = FLOW_INSENSITIVE;

    enum class RdaType {
        DENSE,
        SEMISPARSE
    } rda = RdaType::DENSE;

    // parse options
    for (int i = 1; i < argc; ++i) {
        // run given points-to analysis
        if (strcmp(argv[i], "-pta") == 0) {
            if (strcmp(argv[i+1], "fs") == 0)
                type = FLOW_SENSITIVE;
        } else if (strcmp(argv[i], "-rda") == 0) {
            if (strcmp(argv[i+1], "ss") == 0)
                rda = RdaType::SEMISPARSE;
        } else if (strcmp(argv[i], "-pta-field-sensitive") == 0) {
            field_senitivity = (uint64_t) atoll(argv[i + 1]);
        } else if (strcmp(argv[i], "-rd-max-set-size") == 0) {
            max_set_size = (uint64_t) atoll(argv[i + 1]);
            if (max_set_size == 0) {
                llvm::errs() << "Invalid -rd-max-set-size argument\n";
                abort();
            }
        } else if (strcmp(argv[i], "-rd-strong-update-unknown") == 0) {
            rd_strong_update_unknown = true;
        } else if (strcmp(argv[i], "-dot") == 0) {
            todot = true;
        } else if (strcmp(argv[i], "-v") == 0) {
            verbose = true;
        } else if (strcmp(argv[i], "-blocks") == 0) {
            blocks = true;
        } else {
            module = argv[i];
        }
    }

    if (!module) {
        errs() << "Usage: % IR_module [-pts fs|fi] [-dot] [-v] [output_file]\n";
        return 1;
    }

#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 5))
    M = llvm::ParseIRFile(module, SMD, context);
#else
    auto _M = llvm::parseIRFile(module, SMD, context);
    // _M is unique pointer, we need to get Module *
    M = _M.get();
#endif

    if (!M) {
        llvm::errs() << "Failed parsing '" << module << "' file:\n";
        SMD.print(argv[0], errs());
        return 1;
    }

    debug::TimeMeasure tm;

    LLVMPointerAnalysis PTA(M, field_senitivity);

    tm.start();

    if (type == FLOW_INSENSITIVE) {
        PTA.run<pta::PointsToFlowInsensitive>();
    } else {
        PTA.run<pta::PointsToFlowSensitive>();
    }

    tm.stop();
    tm.report("INFO: Points-to analysis took");

    LLVMReachingDefinitions RD(M, &PTA, rd_strong_update_unknown, max_set_size);
    tm.start();
    if (rda == RdaType::SEMISPARSE) {
        RD.run<dg::analysis::rd::SemisparseRda, true>();
    } else
        RD.run<dg::analysis::rd::ReachingDefinitionsAnalysis, false>();
    tm.stop();
    tm.report("INFO: Reaching definitions analysis took");

    if (blocks) {
        if (!todot) {
            errs() << "warning: -dot not specified, but -blocks only supports dot format. overriding...\n";
        }
        dumpRDBlocksDot(RD);
    } else
        dumpRD(&RD, todot);

    return 0;
}
<commit_msg>llvm-rd-dump: -blocks option dumps all nodes<commit_after>#ifndef HAVE_LLVM
#error "This code needs LLVM enabled"
#endif

#include <set>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>

// ignore unused parameters in LLVM libraries
#if (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/IRReader/IRReader.h>

#if LLVM_VERSION_MAJOR >= 4
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#else
#include <llvm/Bitcode/ReaderWriter.h>
#endif

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
#else
#pragma GCC diagnostic pop
#endif

#include "analysis/PointsTo/PointsToFlowInsensitive.h"
#include "analysis/PointsTo/PointsToFlowSensitive.h"
#include "analysis/PointsTo/Pointer.h"

#include "llvm/analysis/PointsTo/PointsTo.h"
#include "llvm/analysis/ReachingDefinitions/ReachingDefinitions.h"

#include "TimeMeasure.h"

using namespace dg;
using namespace dg::analysis;
using namespace dg::analysis::rd;
using llvm::errs;

static bool verbose = false;

static std::string
getInstName(const llvm::Value *val)
{
    std::ostringstream ostr;
    llvm::raw_os_ostream ro(ostr);

    assert(val);
    ro << *val;
    ro.flush();

    // break the string if it is too long
    return ostr.str();
}

static void printRDNodeType(enum RDNodeType type)
{
#define ELEM(t) case(t): do {printf("%s", #t); }while(0); break;
    switch(type) {
        ELEM(RDNodeType::ALLOC)
        ELEM(RDNodeType::DYN_ALLOC)
        ELEM(RDNodeType::STORE)
        ELEM(RDNodeType::PHI)
        ELEM(RDNodeType::CALL)
        ELEM(RDNodeType::CALL_RETURN)
        ELEM(RDNodeType::RETURN)
        ELEM(RDNodeType::NOOP)
        ELEM(RDNodeType::NONE)
        default:
            printf("unknown reaching definitions subgraph type");
    };
#undef ELEM
}

static inline void printAddress(RDNode *node, bool dot)
{
    if (dot)
        printf(" [%p]\\n", node);
    else
        printf(" [%p]\n", node);
}

static void
printName(RDNode *node, bool dot)
{
    if (node == rd::UNKNOWN_MEMORY) {
        printf("UNKNOWN MEMORY");
        return;
    }

    const char *name = nullptr;
#if 0
#ifdef DEBUG_ENABLED
    name = node->getName();
#endif
#endif
    std::string nm;
    if (!name) {
        if (!node->getUserData<llvm::Value>()) {
            printRDNodeType(node->getType());
            printAddress(node, dot);
            return;
        }

        nm = getInstName(node->getUserData<llvm::Value>());
        name = nm.c_str();
    }

    // escape the " character
    for (int i = 0; name[i] != '\0'; ++i) {
        // crop long names
        if (i >= 70) {
            printf(" ...");
            break;
        }

        if (name[i] == '"')
            putchar('\\');

        putchar(name[i]);
    }
}

static void
dumpMap(RDNode *node, bool dot = false)
{
    RDMap& map = node->getReachingDefinitions();
    for (const auto& it : map) {
        for (RDNode *site : it.second) {
            printName(it.first.target, dot);
            // don't print offsets with unknown memory
            if (it.first.target == rd::UNKNOWN_MEMORY) {
                printf(" => ");
            } else {
                if (it.first.offset.isUnknown())
                    printf(" | UNKNOWN | => ");
                else if (it.first.len.isUnknown())
                    printf(" | %lu - UNKNOWN | => ", *it.first.offset);
                else
                    printf(" | %lu - %lu | => ", *it.first.offset,
                           *it.first.offset + *it.first.len - 1);
            }

            printName(site, dot);
            if (dot)
                printf("\\n");
            else
                putchar('\n');
        }
    }
}

static void
dumpDefSites(const std::set<DefSite>& defs, const char *kind, bool dot = false)
{
    for (const DefSite& def : defs) {
        printf("%s: ", kind);
        printName(def.target, dot);
            if (def.offset.isUnknown())
                printf(" [ UNKNOWN ]");
            else
                printf(" [ %lu - %lu ]", *def.offset,
                       *def.offset + *def.len - 1);

            if (dot)
                printf("\\n");
            else
                putchar('\n');
    }
}

static void
dumpDefines(RDNode *node, bool dot = false)
{
    dumpDefSites(node->getDefines(), "DEF", dot);
}

static void
dumpOverwrites(RDNode *node, bool dot = false)
{
    dumpDefSites(node->getOverwrites(), "DEF strong", dot);
}

static void
dumpUses(RDNode *node, bool dot = false)
{
    dumpDefSites(node->getUses(), "USE", dot);
}

static void
dumpRDNode(RDNode *n)
{
    printf("NODE: ");
    printName(n, false);
    if (n->getSize() > 0)
        printf(" [size: %lu]", n->getSize());
    putchar('\n');
    dumpMap(n);
    printf("---\n");
}

static void
dumpRDdot(LLVMReachingDefinitions *RD)
{
    std::set<RDNode *> nodes;
    RD->getNodes(nodes);

    printf("digraph \"Reaching Definitions Subgraph\" {\n");

    /* dump nodes */
    for(RDNode *node : nodes) {
        printf("\tNODE%p [label=\"", node);
        printName(node, true);
        if (node->getSize() > 0)
            printf("\\n[size: %lu]\\n", node->getSize());
        printf("\\n-------------\\n");
        if (verbose) {
            dumpDefines(node, true);
            printf("-------------\\n");
            dumpOverwrites(node, true);
            printf("-------------\\n");
            dumpUses(node, true);
        }
            dumpMap(node, true /* dot */);

        printf("\" shape=box]\n");
    }

    /* dump edges */
    for (RDNode *node : nodes) {
        for (RDNode *succ : node->getSuccessors())
            printf("\tNODE%p -> NODE%p [penwidth=2]\n", node, succ);
    }

    std::unordered_map<RDNode*, unsigned> colors;
    for (auto& pair : RD->getSrg()) {
        RDNode *source = pair.first;
        for (auto& var_where: pair.second) {
            DefSite var = var_where.first;
            RDNode *dest = var_where.second;
            if (colors.find(var.target) == colors.end())
                colors[var.target] = rand();
            printf("\tNODE%p -> NODE%p [color=\"#%X\" style=\"dotted\"]", source, dest, colors[var.target]);
        }
    }

    printf("}\n");
}

static void
dumpRD(LLVMReachingDefinitions *RD, bool todot)
{
    assert(RD);

    if (todot)
        dumpRDdot(RD);
    else {
        std::set<RDNode *> nodes;
        RD->getNodes(nodes);

        for (RDNode *node : nodes)
            dumpRDNode(node);
    }
}

static void
dumpRDBlocksDot(LLVMReachingDefinitions &RD)
{
    const auto& blocks = RD.getBlocks();

    printf("digraph \"RDBlocks\" {\n");

    /* dump nodes */
    for (const auto& pair : blocks) {
        for (const auto& block : pair.second) {
            printf("\tNODE%p", block.get());
            printf("[label=\"");

            /* dump nodes */
            for(RDNode *node : block->getNodes()) {
                printName(node, true);
                if (node->getSize() > 0)
                    printf("\\n[size: %lu]\\n", node->getSize());
                printf("\\n-------------\\n");
                if (verbose) {
                    dumpDefines(node, true);
                    printf("-------------\\n");
                    dumpOverwrites(node, true);
                    printf("-------------\\n");
                    dumpUses(node, true);
                }
                dumpMap(node, true /* dot */);

            }

            printf("\"shape=box]\n");
        }
    }

    for (const auto& pair : blocks) {
        for (const auto& block : pair.second) {
            for (const auto& edge : block->successors()) {
                printf("\tNODE%p -> NODE%p\n", block.get(), edge.target);
            }
        }
    }

    printf("}\n");

}

int main(int argc, char *argv[])
{
    llvm::Module *M;
    llvm::LLVMContext context;
    llvm::SMDiagnostic SMD;
    bool todot = false;
    bool blocks = false;
    const char *module = nullptr;
    uint64_t field_senitivity = UNKNOWN_OFFSET;
    bool rd_strong_update_unknown = false;
    uint32_t max_set_size = ~((uint32_t) 0);

    enum {
        FLOW_SENSITIVE = 1,
        FLOW_INSENSITIVE,
    } type = FLOW_INSENSITIVE;

    enum class RdaType {
        DENSE,
        SEMISPARSE
    } rda = RdaType::DENSE;

    // parse options
    for (int i = 1; i < argc; ++i) {
        // run given points-to analysis
        if (strcmp(argv[i], "-pta") == 0) {
            if (strcmp(argv[i+1], "fs") == 0)
                type = FLOW_SENSITIVE;
        } else if (strcmp(argv[i], "-rda") == 0) {
            if (strcmp(argv[i+1], "ss") == 0)
                rda = RdaType::SEMISPARSE;
        } else if (strcmp(argv[i], "-pta-field-sensitive") == 0) {
            field_senitivity = (uint64_t) atoll(argv[i + 1]);
        } else if (strcmp(argv[i], "-rd-max-set-size") == 0) {
            max_set_size = (uint64_t) atoll(argv[i + 1]);
            if (max_set_size == 0) {
                llvm::errs() << "Invalid -rd-max-set-size argument\n";
                abort();
            }
        } else if (strcmp(argv[i], "-rd-strong-update-unknown") == 0) {
            rd_strong_update_unknown = true;
        } else if (strcmp(argv[i], "-dot") == 0) {
            todot = true;
        } else if (strcmp(argv[i], "-v") == 0) {
            verbose = true;
        } else if (strcmp(argv[i], "-blocks") == 0) {
            blocks = true;
        } else {
            module = argv[i];
        }
    }

    if (!module) {
        errs() << "Usage: % IR_module [-pts fs|fi] [-dot] [-v] [output_file]\n";
        return 1;
    }

#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 5))
    M = llvm::ParseIRFile(module, SMD, context);
#else
    auto _M = llvm::parseIRFile(module, SMD, context);
    // _M is unique pointer, we need to get Module *
    M = _M.get();
#endif

    if (!M) {
        llvm::errs() << "Failed parsing '" << module << "' file:\n";
        SMD.print(argv[0], errs());
        return 1;
    }

    debug::TimeMeasure tm;

    LLVMPointerAnalysis PTA(M, field_senitivity);

    tm.start();

    if (type == FLOW_INSENSITIVE) {
        PTA.run<pta::PointsToFlowInsensitive>();
    } else {
        PTA.run<pta::PointsToFlowSensitive>();
    }

    tm.stop();
    tm.report("INFO: Points-to analysis took");

    LLVMReachingDefinitions RD(M, &PTA, rd_strong_update_unknown, max_set_size);
    tm.start();
    if (rda == RdaType::SEMISPARSE) {
        RD.run<dg::analysis::rd::SemisparseRda, true>();
    } else
        RD.run<dg::analysis::rd::ReachingDefinitionsAnalysis, false>();
    tm.stop();
    tm.report("INFO: Reaching definitions analysis took");

    if (blocks) {
        if (!todot) {
            errs() << "warning: -dot not specified, but -blocks only supports dot format. overriding...\n";
        }
        dumpRDBlocksDot(RD);
    } else
        dumpRD(&RD, todot);

    return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** SoundManager.cpp
**
** Copyright (C) September 2015 Hotride
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
*****************************************************************************
*/
//---------------------------------------------------------------------------
#include "stdafx.h"
#include <fstream>
#include <string>

//---------------------------------------------------------------------------
#pragma region BASS.DLL error code descriptions

struct BASS_ErrorDescription
{
	int errorCode;
	char desc[64];
};
//------------------------------------------------------------------------------
BASS_ErrorDescription BASS_ErrorTable[] = {
	{ -2, "unspecified error" },
	{ BASS_OK, "OK" },
	{ BASS_ERROR_MEM, "memory error" },
	{ BASS_ERROR_FILEOPEN, "can't open the file" },
	{ BASS_ERROR_DRIVER, "can't find a free/valid driver" },
	{ BASS_ERROR_BUFLOST, "the sample buffer was lost" },
	{ BASS_ERROR_HANDLE, "invalid handle" },
	{ BASS_ERROR_FORMAT, "unsupported sample format" },
	{ BASS_ERROR_POSITION, "invalid position" },
	{ BASS_ERROR_INIT, "BASS_Init has not been successfully called" },
	{ BASS_ERROR_START, "BASS_Start has not been successfully called" },
	{ BASS_ERROR_SSL, "SSL/HTTPS support isn't available" },
	{ BASS_ERROR_ALREADY, "already initialized/paused/whatever" },
	{ BASS_ERROR_NOCHAN, "can't get a free channel" },
	{ BASS_ERROR_ILLTYPE, "an illegal type was specified" },
	{ BASS_ERROR_ILLPARAM, "an illegal parameter was specified" },
	{ BASS_ERROR_NO3D, "no 3D support" },
	{ BASS_ERROR_NOEAX, "no EAX support" },
	{ BASS_ERROR_DEVICE, "illegal device number" },
	{ BASS_ERROR_NOPLAY, "not playing" },
	{ BASS_ERROR_FREQ, "illegal sample rate" },
	{ BASS_ERROR_NOTFILE, "the stream is not a file stream" },
	{ BASS_ERROR_NOHW, "no hardware voices available" },
	{ BASS_ERROR_EMPTY, "the MOD music has no sequence data" },
	{ BASS_ERROR_NONET, "no internet connection could be opened" },
	{ BASS_ERROR_CREATE, "couldn't create the file" },
	{ BASS_ERROR_NOFX, "effects are not available" },
	{ BASS_ERROR_NOTAVAIL, "requested data is not available" },
	{ BASS_ERROR_DECODE, "the channel is/isn't a \"decoding channel\"" },
	{ BASS_ERROR_DX, "a sufficient DirectX version is not installed" },
	{ BASS_ERROR_TIMEOUT, "connection timedout" },
	{ BASS_ERROR_FILEFORM, "unsupported file format" },
	{ BASS_ERROR_SPEAKER, "unavailable speaker" },
	{ BASS_ERROR_VERSION, "invalid BASS version (used by add-ons)" },
	{ BASS_ERROR_CODEC, "codec is not available/supported" },
	{ BASS_ERROR_ENDED, "the channel/file has ended" },
	{ BASS_ERROR_BUSY, "the device is busy" },
	{ BASS_ERROR_UNKNOWN, "some other mystery problem" },
};
//------------------------------------------------------------------------------
char* BASS_ErrorGetDescription()
{
	auto currentErrorCode = BASS_ErrorGetCode();

	for (auto &bassError : BASS_ErrorTable) {
		if (bassError.errorCode == currentErrorCode)
			return bassError.desc;
	}
	return BASS_ErrorTable[0].desc;
}
#pragma endregion
//---------------------------------------------------------------------------
TSoundManager SoundManager;
//---------------------------------------------------------------------------
TSoundManager::TSoundManager()
: m_Music(0)
{
}
//---------------------------------------------------------------------------
TSoundManager::~TSoundManager()
{
}
//---------------------------------------------------------------------------
bool TSoundManager::Init()
{
	TPRINT("Initializing bass sound system.\n");
	// initialize default output device
	if (!BASS_Init(-1, 48000, BASS_DEVICE_3D, g_hWnd, NULL))
	{
		TPRINT("Can't initialize device: %s\n", BASS_ErrorGetDescription());
		return false;
	}
	else
	{
		TPRINT("Sound init successfull.\n");
		BASS_SetConfig(BASS_CONFIG_SRC, 3); // interpolation method

		if (!BASS_SetConfig(BASS_CONFIG_3DALGORITHM, BASS_3DALG_FULL))
			TPRINT("Error setting 3d sound: %s\n", BASS_ErrorGetDescription());
	}
	return true;
}
//---------------------------------------------------------------------------
void TSoundManager::Free()
{
	StopMusic();
	BASS_Free();
}

void TSoundManager::PauseSound()
{
	BASS_Pause();
}

void TSoundManager::ResumeSound()
{
	BASS_Start();
}

///
///     .
/// <param name="distance">  .
///  -1   .</param>
/// <returns>  BASS .</returns>
float TSoundManager::GetVolumeValue(int distance, bool music)
{
	float volume = BASS_GetVolume();
	WORD clientConfigVolume = music ? ConfigManager.MusicVolume : ConfigManager.SoundVolume;
	if (volume == 0 || clientConfigVolume == 0) return 0;
	float clientsVolumeValue = (static_cast<float>(255) / static_cast<float>(clientConfigVolume));
	volume /= clientsVolumeValue;
	if (distance > g_UpdateRange || distance < 1)
		return volume;
	else
	{
		float soundValuePerDistance = volume  / g_UpdateRange;
		return volume - (soundValuePerDistance * distance);
	}

}

///    16  wave
/// .
/// <param name="is">     MUL </param>
/// <returns>Wave     </returns>
std::vector<BYTE> TSoundManager::CreateWaveFile(TIndexSound &is)
{
	size_t dataSize = is.Size - sizeof(SOUND_BLOCK);
	auto waveSound = std::vector<BYTE>(dataSize + sizeof(WaveHeader));
	auto waveHeader = reinterpret_cast<WaveHeader*>(waveSound.data());

	strcpy(waveHeader->chunkId, "RIFF");
	strcpy(waveHeader->format, "WAVE");
	strcpy(waveHeader->subChunkId, "fmt ");
	strcpy(waveHeader->dataChunkId, "data");

	waveHeader->chunkSize = waveSound.size();
	waveHeader->subChunkSize = 16;
	waveHeader->audioFormat = 1;
	waveHeader->numChannels = 1;
	waveHeader->sampleRate = 22050;
	waveHeader->bitsPerSample = 16;
	waveHeader->bytesPerSecond = 88200;
	waveHeader->blockAlign = 4;
	waveHeader->dataSize = dataSize;

	is.Timer = static_cast<DWORD>((dataSize - 16) / 88.2f);

	auto sndDataPtr = reinterpret_cast<PBYTE>(is.Address + sizeof(SOUND_BLOCK));
	std::copy_n(sndDataPtr + 16, dataSize - 16, waveSound.begin() + sizeof(WaveHeader));

	return waveSound;
}

HSTREAM TSoundManager::LoadSoundEffect(TIndexSound &is)
{
	if (is.waveFile.empty())
	{
		auto waveSound = this->CreateWaveFile(is);
		is.waveFile.swap(waveSound);
	}

	size_t waveFileSize = is.Size - sizeof(SOUND_BLOCK) +sizeof(WaveHeader);

	auto hStream = BASS_StreamCreateFile(true, is.waveFile.data(), 0,
		is.waveFile.size() - 16, BASS_SAMPLE_FLOAT | BASS_SAMPLE_3D | BASS_SAMPLE_SOFTWARE);

	if (hStream == 0)
	{
		TPRINT("BASS create stream error: %s\n", BASS_ErrorGetDescription());
		is.waveFile.clear();
	}

	return hStream;
}

void TSoundManager::PlaySoundEffect(HSTREAM hStream, float volume)
{
	if (hStream == 0 || GetForegroundWindow() != g_hWnd)
		return;

	BASS_ChannelSetAttribute(hStream, BASS_ATTRIB_VOL, volume);

	if (!BASS_ChannelPlay(hStream, false))
		TPRINT("Bass sound play error: %s\n", BASS_ErrorGetDescription());

}
//---------------------------------------------------------------------------
///      .
/// <param name="hSteam">stream handle</param>
bool TSoundManager::FreeStream(HSTREAM hSteam)
{
	auto res = BASS_StreamFree(hSteam);
	return res;
}
//---------------------------------------------------------------------------
void TSoundManager::PlayMidi(int index)
{
	const char *musicSubCat[3] =
	{
		"",
		"\\512K",
		"\\4MB"
	};

	if (index >= 0 && index < MIDI_MUSIC_COUNT)
	{
		StopMusic();

		MCI_OPEN_PARMS openParm = {0};
		openParm.dwCallback = (DWORD)g_hWnd;
		openParm.lpstrDeviceType = L"sequencer";
		DWORD flags = MCI_OPEN_ELEMENT;

		char musicPath[100] = {0};
		sprintf(musicPath, "music%s\\%s", musicSubCat[1], m_MusicName[index]);

		wstring midiName = ToWString(musicPath);
		openParm.lpstrElementName = midiName.c_str();

		MCIERROR error = mciSendCommand(0, MCI_OPEN, flags,(DWORD)&openParm);

		if (!error)
		{
			m_Music = openParm.wDeviceID;

			SetMusicVolume(ConfigManager.MusicVolume);

			MCI_PLAY_PARMS playParm = {0};
			playParm.dwCallback = (DWORD)g_hWnd;
			playParm.dwFrom = 0;

			error = mciSendCommand(m_Music, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD)&playParm);

			if (error)
				TraceMusicError(error);
		}
		else
			TraceMusicError(error);
	}
	else
		TPRINT("Music ID is out of range: %i\n", index);
}

void TSoundManager::PlayMP3(std::string fileName, bool loop)
{
		if (m_Music != 0)
			BASS_ChannelStop(m_Music);

		HSTREAM streamHandle = BASS_StreamCreateFile(FALSE, fileName.c_str(), 0, 0, 0);
		BASS_ChannelSetAttribute(streamHandle, BASS_ATTRIB_VOL, GetVolumeValue(-1, true));
		BASS_ChannelPlay(streamHandle, loop ? 1 : 0);
		m_Music = streamHandle;
}
//---------------------------------------------------------------------------
void TSoundManager::StopMusic()
{
	if (m_Music != 0)
	{
		//midi music stopping code via mci.
		/*MCI_GENERIC_PARMS mciGen;
		DWORD error = mciSendCommand(m_Music, MCI_STOP, MCI_WAIT, (DWORD)(LPMCI_GENERIC_PARMS)&mciGen);

		TraceMusicError(error);*/
		BASS_ChannelStop(m_Music);
		m_Music = 0;
	}
}
//---------------------------------------------------------------------------
void TSoundManager::SetMusicVolume(float volume)
{
	if (m_Music != 0)
	{
		BASS_ChannelSetAttribute(m_Music, BASS_ATTRIB_VOL, volume);
	}
}
//---------------------------------------------------------------------------
void TSoundManager::TraceMusicError(DWORD error)
{
	if (error)
	{
		wchar_t szBuf[MAXERRORLENGTH];

		if (mciGetErrorString(error, szBuf, MAXERRORLENGTH))
			TPRINT("Midi error: %s\n", ToString(szBuf).c_str());
		else
			TPRINT("Midi error: #%i\n", error);
	}
}
//---------------------------------------------------------------------------
const char *TSoundManager::m_MusicName[MIDI_MUSIC_COUNT] =
{
	"oldult01.mid",
	"create1.mid",
	"dragflit.mid",
	"oldult02.mid",
	"oldult03.mid",
	"oldult04.mid",
	"oldult05.mid",
	"oldult06.mid",
	"stones2.mid",
	"britain1.mid",
	"britain2.mid",
	"bucsden.mid",
	"jhelom.mid",
	"lbcastle.mid",
	"linelle.mid",
	"magincia.mid",
	"minoc.mid",
	"ocllo.mid",
	"samlethe.mid",
	"serpents.mid",
	"skarabra.mid",
	"trinsic.mid",
	"vesper.mid",
	"wind.mid",
	"yew.mid",
	"cave01.mid",
	"dungeon9.mid",
	"forest_a.mid",
	"intown01.mid",
	"jungle_a.mid",
	"mountn_a.mid",
	"plains_a.mid",
	"sailing.mid",
	"swamp_a.mid",
	"tavern01.mid",
	"tavern02.mid",
	"tavern03.mid",
	"tavern04.mid",
	"combat1.mid",
	"combat2.mid",
	"combat3.mid",
	"approach.mid",
	"death.mid",
	"victory.mid",
	"btcastle.mid",
	"nujelm.mid",
	"dungeon2.mid",
	"cove.mid",
	"moonglow.mid",
	"oldult02.mid",
	"serpents.mid",
	"oldult04.mid",
	"dragflit.mid",
	"create1.mid",
	"approach.mid",
	"combat3.mid",
	"jungle_a.mid"
};
//---------------------------------------------------------------------------<commit_msg>Сделал что-бы звуки полностью ресетились при сворачивании окна, а музыка встаёт на паузу, как в оригинальном клиенте. Так-же исправил баг в StopMusic(). Через БАСС нет никаких эвентов, которые говорят о том когда закончил играть трек, поэтому всегда лучше пробовать освободить канал с музыкой.<commit_after>/****************************************************************************
**
** SoundManager.cpp
**
** Copyright (C) September 2015 Hotride
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program 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 General Public License for more details.
**
*****************************************************************************
*/
//---------------------------------------------------------------------------
#include "stdafx.h"
#include <fstream>
#include <string>

//---------------------------------------------------------------------------
#pragma region BASS.DLL error code descriptions

struct BASS_ErrorDescription
{
	int errorCode;
	char desc[64];
};
//------------------------------------------------------------------------------
BASS_ErrorDescription BASS_ErrorTable[] = {
	{ -2, "unspecified error" },
	{ BASS_OK, "OK" },
	{ BASS_ERROR_MEM, "memory error" },
	{ BASS_ERROR_FILEOPEN, "can't open the file" },
	{ BASS_ERROR_DRIVER, "can't find a free/valid driver" },
	{ BASS_ERROR_BUFLOST, "the sample buffer was lost" },
	{ BASS_ERROR_HANDLE, "invalid handle" },
	{ BASS_ERROR_FORMAT, "unsupported sample format" },
	{ BASS_ERROR_POSITION, "invalid position" },
	{ BASS_ERROR_INIT, "BASS_Init has not been successfully called" },
	{ BASS_ERROR_START, "BASS_Start has not been successfully called" },
	{ BASS_ERROR_SSL, "SSL/HTTPS support isn't available" },
	{ BASS_ERROR_ALREADY, "already initialized/paused/whatever" },
	{ BASS_ERROR_NOCHAN, "can't get a free channel" },
	{ BASS_ERROR_ILLTYPE, "an illegal type was specified" },
	{ BASS_ERROR_ILLPARAM, "an illegal parameter was specified" },
	{ BASS_ERROR_NO3D, "no 3D support" },
	{ BASS_ERROR_NOEAX, "no EAX support" },
	{ BASS_ERROR_DEVICE, "illegal device number" },
	{ BASS_ERROR_NOPLAY, "not playing" },
	{ BASS_ERROR_FREQ, "illegal sample rate" },
	{ BASS_ERROR_NOTFILE, "the stream is not a file stream" },
	{ BASS_ERROR_NOHW, "no hardware voices available" },
	{ BASS_ERROR_EMPTY, "the MOD music has no sequence data" },
	{ BASS_ERROR_NONET, "no internet connection could be opened" },
	{ BASS_ERROR_CREATE, "couldn't create the file" },
	{ BASS_ERROR_NOFX, "effects are not available" },
	{ BASS_ERROR_NOTAVAIL, "requested data is not available" },
	{ BASS_ERROR_DECODE, "the channel is/isn't a \"decoding channel\"" },
	{ BASS_ERROR_DX, "a sufficient DirectX version is not installed" },
	{ BASS_ERROR_TIMEOUT, "connection timedout" },
	{ BASS_ERROR_FILEFORM, "unsupported file format" },
	{ BASS_ERROR_SPEAKER, "unavailable speaker" },
	{ BASS_ERROR_VERSION, "invalid BASS version (used by add-ons)" },
	{ BASS_ERROR_CODEC, "codec is not available/supported" },
	{ BASS_ERROR_ENDED, "the channel/file has ended" },
	{ BASS_ERROR_BUSY, "the device is busy" },
	{ BASS_ERROR_UNKNOWN, "some other mystery problem" },
};
//------------------------------------------------------------------------------
char* BASS_ErrorGetDescription()
{
	auto currentErrorCode = BASS_ErrorGetCode();

	for (auto &bassError : BASS_ErrorTable) {
		if (bassError.errorCode == currentErrorCode)
			return bassError.desc;
	}
	return BASS_ErrorTable[0].desc;
}
#pragma endregion
//---------------------------------------------------------------------------
TSoundManager SoundManager;
//---------------------------------------------------------------------------
TSoundManager::TSoundManager()
: m_Music(0)
{
}
//---------------------------------------------------------------------------
TSoundManager::~TSoundManager()
{
}
//---------------------------------------------------------------------------
bool TSoundManager::Init()
{
	TPRINT("Initializing bass sound system.\n");
	// initialize default output device
	if (!BASS_Init(-1, 48000, BASS_DEVICE_3D, g_hWnd, NULL))
	{
		TPRINT("Can't initialize device: %s\n", BASS_ErrorGetDescription());
		return false;
	}
	else
	{
		TPRINT("Sound init successfull.\n");
		BASS_SetConfig(BASS_CONFIG_SRC, 3); // interpolation method

		if (!BASS_SetConfig(BASS_CONFIG_3DALGORITHM, BASS_3DALG_FULL))
			TPRINT("Error setting 3d sound: %s\n", BASS_ErrorGetDescription());
	}
	return true;
}
//---------------------------------------------------------------------------
void TSoundManager::Free()
{
	StopMusic();
	BASS_Free();
}

void TSoundManager::PauseSound()
{
	BASS_Pause();
	UO->AdjustSoundEffects(GetTickCount() + 100000);
}

void TSoundManager::ResumeSound()
{
	BASS_Start();
}

///
///     .
/// <param name="distance">  .
///  -1   .</param>
/// <returns>  BASS .</returns>
float TSoundManager::GetVolumeValue(int distance, bool music)
{
	float volume = BASS_GetVolume();
	WORD clientConfigVolume = music ? ConfigManager.MusicVolume : ConfigManager.SoundVolume;
	if (volume == 0 || clientConfigVolume == 0) return 0;
	float clientsVolumeValue = (static_cast<float>(255) / static_cast<float>(clientConfigVolume));
	volume /= clientsVolumeValue;
	if (distance > g_UpdateRange || distance < 1)
		return volume;
	else
	{
		float soundValuePerDistance = volume  / g_UpdateRange;
		return volume - (soundValuePerDistance * distance);
	}

}

///    16  wave
/// .
/// <param name="is">     MUL </param>
/// <returns>Wave     </returns>
std::vector<BYTE> TSoundManager::CreateWaveFile(TIndexSound &is)
{
	size_t dataSize = is.Size - sizeof(SOUND_BLOCK);
	auto waveSound = std::vector<BYTE>(dataSize + sizeof(WaveHeader));
	auto waveHeader = reinterpret_cast<WaveHeader*>(waveSound.data());

	strcpy(waveHeader->chunkId, "RIFF");
	strcpy(waveHeader->format, "WAVE");
	strcpy(waveHeader->subChunkId, "fmt ");
	strcpy(waveHeader->dataChunkId, "data");

	waveHeader->chunkSize = waveSound.size();
	waveHeader->subChunkSize = 16;
	waveHeader->audioFormat = 1;
	waveHeader->numChannels = 1;
	waveHeader->sampleRate = 22050;
	waveHeader->bitsPerSample = 16;
	waveHeader->bytesPerSecond = 88200;
	waveHeader->blockAlign = 4;
	waveHeader->dataSize = dataSize;

	is.Timer = static_cast<DWORD>((dataSize - 16) / 88.2f);

	auto sndDataPtr = reinterpret_cast<PBYTE>(is.Address + sizeof(SOUND_BLOCK));
	std::copy_n(sndDataPtr + 16, dataSize - 16, waveSound.begin() + sizeof(WaveHeader));

	return waveSound;
}

HSTREAM TSoundManager::LoadSoundEffect(TIndexSound &is)
{
	if (is.waveFile.empty())
	{
		auto waveSound = this->CreateWaveFile(is);
		is.waveFile.swap(waveSound);
	}

	size_t waveFileSize = is.Size - sizeof(SOUND_BLOCK) +sizeof(WaveHeader);

	auto hStream = BASS_StreamCreateFile(true, is.waveFile.data(), 0,
		is.waveFile.size() - 16, BASS_SAMPLE_FLOAT | BASS_SAMPLE_3D | BASS_SAMPLE_SOFTWARE);

	if (hStream == 0)
	{
		TPRINT("BASS create stream error: %s\n", BASS_ErrorGetDescription());
		is.waveFile.clear();
	}

	return hStream;
}

void TSoundManager::PlaySoundEffect(HSTREAM hStream, float volume)
{
	if (hStream == 0 || GetForegroundWindow() != g_hWnd)
		return;

	BASS_ChannelSetAttribute(hStream, BASS_ATTRIB_VOL, volume);

	if (!BASS_ChannelPlay(hStream, false))
		TPRINT("Bass sound play error: %s\n", BASS_ErrorGetDescription());

}
//---------------------------------------------------------------------------
///      .
/// <param name="hSteam">stream handle</param>
bool TSoundManager::FreeStream(HSTREAM hSteam)
{
	auto res = BASS_StreamFree(hSteam);
	return res;
}
//---------------------------------------------------------------------------
void TSoundManager::PlayMidi(int index)
{
	const char *musicSubCat[3] =
	{
		"",
		"\\512K",
		"\\4MB"
	};

	if (index >= 0 && index < MIDI_MUSIC_COUNT)
	{
		StopMusic();

		MCI_OPEN_PARMS openParm = {0};
		openParm.dwCallback = (DWORD)g_hWnd;
		openParm.lpstrDeviceType = L"sequencer";
		DWORD flags = MCI_OPEN_ELEMENT;

		char musicPath[100] = {0};
		sprintf(musicPath, "music%s\\%s", musicSubCat[1], m_MusicName[index]);

		wstring midiName = ToWString(musicPath);
		openParm.lpstrElementName = midiName.c_str();

		MCIERROR error = mciSendCommand(0, MCI_OPEN, flags,(DWORD)&openParm);

		if (!error)
		{
			m_Music = openParm.wDeviceID;

			SetMusicVolume(ConfigManager.MusicVolume);

			MCI_PLAY_PARMS playParm = {0};
			playParm.dwCallback = (DWORD)g_hWnd;
			playParm.dwFrom = 0;

			error = mciSendCommand(m_Music, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD)&playParm);

			if (error)
				TraceMusicError(error);
		}
		else
			TraceMusicError(error);
	}
	else
		TPRINT("Music ID is out of range: %i\n", index);
}

void TSoundManager::PlayMP3(std::string fileName, bool loop)
{
	StopMusic();
	HSTREAM streamHandle = BASS_StreamCreateFile(FALSE, fileName.c_str(), 0, 0, 0);
	BASS_ChannelSetAttribute(streamHandle, BASS_ATTRIB_VOL, GetVolumeValue(-1, true));
	BASS_ChannelPlay(streamHandle, loop ? 1 : 0);
	m_Music = streamHandle;
}
//---------------------------------------------------------------------------
void TSoundManager::StopMusic()
{
	//midi music stopping code via mci.
	/*MCI_GENERIC_PARMS mciGen;
	DWORD error = mciSendCommand(m_Music, MCI_STOP, MCI_WAIT, (DWORD)(LPMCI_GENERIC_PARMS)&mciGen);

	TraceMusicError(error);*/
	BASS_ChannelStop(m_Music);
	m_Music = 0;
}
//---------------------------------------------------------------------------
void TSoundManager::SetMusicVolume(float volume)
{
	if (m_Music != 0)
	{
		BASS_ChannelSetAttribute(m_Music, BASS_ATTRIB_VOL, volume);
	}
}
//---------------------------------------------------------------------------
void TSoundManager::TraceMusicError(DWORD error)
{
	if (error)
	{
		wchar_t szBuf[MAXERRORLENGTH];

		if (mciGetErrorString(error, szBuf, MAXERRORLENGTH))
			TPRINT("Midi error: %s\n", ToString(szBuf).c_str());
		else
			TPRINT("Midi error: #%i\n", error);
	}
}
//---------------------------------------------------------------------------
const char *TSoundManager::m_MusicName[MIDI_MUSIC_COUNT] =
{
	"oldult01.mid",
	"create1.mid",
	"dragflit.mid",
	"oldult02.mid",
	"oldult03.mid",
	"oldult04.mid",
	"oldult05.mid",
	"oldult06.mid",
	"stones2.mid",
	"britain1.mid",
	"britain2.mid",
	"bucsden.mid",
	"jhelom.mid",
	"lbcastle.mid",
	"linelle.mid",
	"magincia.mid",
	"minoc.mid",
	"ocllo.mid",
	"samlethe.mid",
	"serpents.mid",
	"skarabra.mid",
	"trinsic.mid",
	"vesper.mid",
	"wind.mid",
	"yew.mid",
	"cave01.mid",
	"dungeon9.mid",
	"forest_a.mid",
	"intown01.mid",
	"jungle_a.mid",
	"mountn_a.mid",
	"plains_a.mid",
	"sailing.mid",
	"swamp_a.mid",
	"tavern01.mid",
	"tavern02.mid",
	"tavern03.mid",
	"tavern04.mid",
	"combat1.mid",
	"combat2.mid",
	"combat3.mid",
	"approach.mid",
	"death.mid",
	"victory.mid",
	"btcastle.mid",
	"nujelm.mid",
	"dungeon2.mid",
	"cove.mid",
	"moonglow.mid",
	"oldult02.mid",
	"serpents.mid",
	"oldult04.mid",
	"dragflit.mid",
	"create1.mid",
	"approach.mid",
	"combat3.mid",
	"jungle_a.mid"
};
//---------------------------------------------------------------------------<|endoftext|>


<commit_before>/* The libMesh Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */
/* License as published by the Free Software Foundation; either */
/* version 2.1 of the License, or (at your option) any later version. */

/* 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 */

 //
Introduction Example 1 - Creation of a Mesh Object

 //
 // This is the first example program.  It simply demonstrates
 // how to create a mesh object.  A mesh is read from file,
 // information is printed to the screen, and the mesh is then
 // written.

 // C++ include files that we need
#include <iostream>
// Functions to initialize the library.
#include "libmesh/libmesh.h"
// Basic include files needed for the mesh functionality.
#include "libmesh/mesh.h"

// Bring in everything from the libMesh namespace
using namespace libMesh;

int main (int argc, char** argv)
{
  // Initialize the library.  This is necessary because the library
  // may depend on a number of other libraries (i.e. MPI and PETSc)
  // that require initialization before use.  When the LibMeshInit
  // object goes out of scope, other libraries and resources are
  // finalized.
  LibMeshInit init (argc, argv);

  // Check for proper usage. The program is designed to be run
  // as follows:
  // ./ex1 -d DIM input_mesh_name [-o output_mesh_name]
  // where [output_mesh_name] is an optional parameter giving
  // a filename to write the mesh into.
  if (argc < 4)
    {
      if (libMesh::processor_id() == 0)
        std::cerr << "Usage: " << argv[0] << " -d 2 in.mesh [-o out.mesh]"
                  << std::endl;

      // This handy function will print the file name, line number,
      // and then abort.  Currently the library does not use C++
      // exception handling.
      libmesh_error();
    }

  // Get the dimensionality of the mesh from argv[2]
  const unsigned int dim = std::atoi(argv[2]);

  // Skip higher-dimensional examples on a lower-dimensional libMesh build
  libmesh_example_assert(dim <= LIBMESH_DIM, "2D/3D support");

  // Create a mesh, with dimension to be overridden later, on the
  // default MPI communicator.
  Mesh mesh(init.comm());

  // Read the input mesh.
  mesh.read (argv[3]);

  // Print information about the mesh to the screen.
  mesh.print_info();

  // Write the output mesh if the user specified an
  // output file name.
  if (argc >= 6 && std::string("-o") == argv[4])
    mesh.write (argv[5]);

  // All done.  libMesh objects are destroyed here.  Because the
  // LibMeshInit object was created first, its destruction occurs
  // last, and it's destructor finalizes any external libraries and
  // checks for leaked memory.
  return 0;
}
<commit_msg>Disable xdr when we don't support xdr<commit_after>/* The libMesh Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */
/* License as published by the Free Software Foundation; either */
/* version 2.1 of the License, or (at your option) any later version. */

/* 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 */

 //
Introduction Example 1 - Creation of a Mesh Object

 //
 // This is the first example program.  It simply demonstrates
 // how to create a mesh object.  A mesh is read from file,
 // information is printed to the screen, and the mesh is then
 // written.

 // C++ include files that we need
#include <iostream>
// Functions to initialize the library.
#include "libmesh/libmesh.h"
// Basic include files needed for the mesh functionality.
#include "libmesh/mesh.h"

// Bring in everything from the libMesh namespace
using namespace libMesh;

int main (int argc, char** argv)
{
  // Initialize the library.  This is necessary because the library
  // may depend on a number of other libraries (i.e. MPI and PETSc)
  // that require initialization before use.  When the LibMeshInit
  // object goes out of scope, other libraries and resources are
  // finalized.
  LibMeshInit init (argc, argv);

  // Check for proper usage. The program is designed to be run
  // as follows:
  // ./ex1 -d DIM input_mesh_name [-o output_mesh_name]
  // where [output_mesh_name] is an optional parameter giving
  // a filename to write the mesh into.
  if (argc < 4)
    {
      if (libMesh::processor_id() == 0)
        std::cerr << "Usage: " << argv[0] << " -d 2 in.mesh [-o out.mesh]"
                  << std::endl;

      // This handy function will print the file name, line number,
      // and then abort.  Currently the library does not use C++
      // exception handling.
      libmesh_error();
    }

  // Get the dimensionality of the mesh from argv[2]
  const unsigned int dim = std::atoi(argv[2]);

  // Skip higher-dimensional examples on a lower-dimensional libMesh build
  libmesh_example_assert(dim <= LIBMESH_DIM, "2D/3D support");

  // Create a mesh, with dimension to be overridden later, on the
  // default MPI communicator.
  Mesh mesh(init.comm());

  // We may need XDR support compiled in to read binary .xdr files
  std::string input_filename = argv[3];
  libmesh_example_assert(LIBMESH_HAVE_XDR ||
                         input_filename.rfind(".xdr") >=
                         input_filename.size(), "XDR support");

  // Read the input mesh.
  mesh.read (argv[3]);

  // Print information about the mesh to the screen.
  mesh.print_info();

  // Write the output mesh if the user specified an
  // output file name.
  if (argc >= 6 && std::string("-o") == argv[4])
    {
      // We may need XDR support compiled in to read binary .xdr files
      std::string output_filename = argv[5];
      libmesh_example_assert(LIBMESH_HAVE_XDR ||
                             output_filename.rfind(".xdr") >=
                             output_filename.size(), "XDR support");

      mesh.write (argv[5]);
    }

  // All done.  libMesh objects are destroyed here.  Because the
  // LibMeshInit object was created first, its destruction occurs
  // last, and it's destructor finalizes any external libraries and
  // checks for leaked memory.
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Create proper error when dividing by zero<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cellvaluebinding.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2003-10-21 08:50:58 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_CELLVALUEBINDING_HXX
#define SC_CELLVALUEBINDING_HXX

#ifndef _DRAFTS_COM_SUN_STAR_FORM_XVALUEBINDING_HPP_
#include <drafts/com/sun/star/form/XValueBinding.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYBROADCASTER_HPP_
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#endif
#ifndef _CPPUHELPER_COMPBASE5_HXX_
#include <cppuhelper/compbase5.hxx>
#endif
#ifndef _COMPHELPER_PROPERTYCONTAINER_HXX_
#include <comphelper/propertycontainer.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif
#ifndef _COM_SUN_STAR_TABLE_XCELL_HPP_
#include <com/sun/star/table/XCell.hpp>
#endif
#ifndef _COM_SUN_STAR_TABLE_CELLADDRESS_HPP_
#include <com/sun/star/table/CellAddress.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXTRANGE_HPP_
#include <com/sun/star/text/XTextRange.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif

//.........................................................................
namespace calc
{
//.........................................................................

    //=====================================================================
    //= OCellValueBinding
    //=====================================================================
    class OCellValueBinding;
    // the base for our interfaces
    typedef ::cppu::WeakAggComponentImplHelper5 <   ::drafts::com::sun::star::form::XValueBinding
                                                ,   ::com::sun::star::lang::XServiceInfo
                                                ,   ::com::sun::star::util::XModifyBroadcaster
                                                ,   ::com::sun::star::util::XModifyListener
                                                ,   ::com::sun::star::lang::XInitialization
                                                >   OCellValueBinding_Base;
    // the base for the property handling
    typedef ::comphelper::OPropertyContainer        OCellValueBinding_PBase;
    // the second base for property handling
    typedef ::comphelper::OPropertyArrayUsageHelper< OCellValueBinding >
                                                    OCellValueBinding_PABase;

    class OCellValueBinding :public ::comphelper::OBaseMutex
                            ,public OCellValueBinding_Base      // order matters! before OCellValueBinding_PBase, so rBHelper gets initialized
                            ,public OCellValueBinding_PBase
                            ,public OCellValueBinding_PABase
    {
    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
                    m_xDocument;            /// the document where our cell lives
        ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
                    m_xCell;                /// the cell we're bound to, for double value access
        ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >
                    m_xCellText;            /// the cell we're bound to, for text access
        ::cppu::OInterfaceContainerHelper
                    m_aModifyListeners;     /// our modify listeners
        sal_Bool    m_bInitialized;         /// has XInitialization::initialize been called?
        sal_Bool    m_bListPos;             /// constructed as ListPositionCellBinding?

    public:
        OCellValueBinding(
            const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& _rxDocument,
            sal_Bool _bListPos
        );

    protected:
        ~OCellValueBinding( );

    protected:
        // XInterface
        DECLARE_XINTERFACE()

        // XTypeProvider
        DECLARE_XTYPEPROVIDER()

        // XValueBinding
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getSupportedValueTypes(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsType( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::com::sun::star::uno::Type& aType ) throw (::drafts::com::sun::star::form::IncompatibleTypesException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& aValue ) throw (::drafts::com::sun::star::form::IncompatibleTypesException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);

        // OComponentHelper/XComponent
        virtual void SAL_CALL disposing();

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);

        // XPropertySet
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);

        // OPropertySetHelper
        virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
        virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const;

        // ::comphelper::OPropertyArrayUsageHelper
        virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

        // XModifyBroadcaster
        virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);

        // XModifyListener
        virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

        // XInitialization
        virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);

    private:
        void    checkDisposed( ) const
                    SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
        void    checkValueType( const ::com::sun::star::uno::Type& _rType ) const
                    SAL_THROW( ( ::drafts::com::sun::star::form::IncompatibleTypesException ) );
        void    checkInitialized()
                    SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) );

        /** notifies our modify listeners
            @precond
                our mutex is not locked
        */
        void    notifyModified();

        void    setBooleanFormat();

    private:
        OCellValueBinding();                                        // never implemented
        OCellValueBinding( const OCellValueBinding& );              // never implemented
        OCellValueBinding& operator=( const OCellValueBinding& );   // never implemented

#ifdef DBG_UTIL
    private:
        static  const char* checkConsistency_static( const void* _pThis );
                const char* checkConsistency( ) const;
#endif
    };

//.........................................................................
}   // namespace calc
//.........................................................................

#endif // SC_CELLVALUEBINDING_HXX
<commit_msg>INTEGRATION: CWS frmvalidation (1.2.112); FILE MERGED 2004/03/12 09:02:59 fs 1.2.112.1: moved the services/interfaces related to binding controls to external values from drafts.com.sun.star.form/component to com.sun.star.form.binding<commit_after>/*************************************************************************
 *
 *  $RCSfile: cellvaluebinding.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-04-02 10:20:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_CELLVALUEBINDING_HXX
#define SC_CELLVALUEBINDING_HXX

#ifndef _COM_SUN_STAR_FORM_BINDING_XVALUEBINDING_HPP_
#include <com/sun/star/form/binding/XValueBinding.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYBROADCASTER_HPP_
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#endif
#ifndef _CPPUHELPER_COMPBASE5_HXX_
#include <cppuhelper/compbase5.hxx>
#endif
#ifndef _COMPHELPER_PROPERTYCONTAINER_HXX_
#include <comphelper/propertycontainer.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
#include <comphelper/proparrhlp.hxx>
#endif
#ifndef _COM_SUN_STAR_TABLE_XCELL_HPP_
#include <com/sun/star/table/XCell.hpp>
#endif
#ifndef _COM_SUN_STAR_TABLE_CELLADDRESS_HPP_
#include <com/sun/star/table/CellAddress.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXTRANGE_HPP_
#include <com/sun/star/text/XTextRange.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif

//.........................................................................
namespace calc
{
//.........................................................................

    //=====================================================================
    //= OCellValueBinding
    //=====================================================================
    class OCellValueBinding;
    // the base for our interfaces
    typedef ::cppu::WeakAggComponentImplHelper5 <   ::com::sun::star::form::binding::XValueBinding
                                                ,   ::com::sun::star::lang::XServiceInfo
                                                ,   ::com::sun::star::util::XModifyBroadcaster
                                                ,   ::com::sun::star::util::XModifyListener
                                                ,   ::com::sun::star::lang::XInitialization
                                                >   OCellValueBinding_Base;
    // the base for the property handling
    typedef ::comphelper::OPropertyContainer        OCellValueBinding_PBase;
    // the second base for property handling
    typedef ::comphelper::OPropertyArrayUsageHelper< OCellValueBinding >
                                                    OCellValueBinding_PABase;

    class OCellValueBinding :public ::comphelper::OBaseMutex
                            ,public OCellValueBinding_Base      // order matters! before OCellValueBinding_PBase, so rBHelper gets initialized
                            ,public OCellValueBinding_PBase
                            ,public OCellValueBinding_PABase
    {
    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
                    m_xDocument;            /// the document where our cell lives
        ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell >
                    m_xCell;                /// the cell we're bound to, for double value access
        ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >
                    m_xCellText;            /// the cell we're bound to, for text access
        ::cppu::OInterfaceContainerHelper
                    m_aModifyListeners;     /// our modify listeners
        sal_Bool    m_bInitialized;         /// has XInitialization::initialize been called?
        sal_Bool    m_bListPos;             /// constructed as ListPositionCellBinding?

    public:
        OCellValueBinding(
            const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& _rxDocument,
            sal_Bool _bListPos
        );

    protected:
        ~OCellValueBinding( );

    protected:
        // XInterface
        DECLARE_XINTERFACE()

        // XTypeProvider
        DECLARE_XTYPEPROVIDER()

        // XValueBinding
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getSupportedValueTypes(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsType( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);

        // OComponentHelper/XComponent
        virtual void SAL_CALL disposing();

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException);

        // XPropertySet
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);

        // OPropertySetHelper
        virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
        virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& _rValue, sal_Int32 _nHandle ) const;

        // ::comphelper::OPropertyArrayUsageHelper
        virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

        // XModifyBroadcaster
        virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);

        // XModifyListener
        virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);

        // XInitialization
        virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);

    private:
        void    checkDisposed( ) const
                    SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
        void    checkValueType( const ::com::sun::star::uno::Type& _rType ) const
                    SAL_THROW( ( ::com::sun::star::form::binding::IncompatibleTypesException ) );
        void    checkInitialized()
                    SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) );

        /** notifies our modify listeners
            @precond
                our mutex is not locked
        */
        void    notifyModified();

        void    setBooleanFormat();

    private:
        OCellValueBinding();                                        // never implemented
        OCellValueBinding( const OCellValueBinding& );              // never implemented
        OCellValueBinding& operator=( const OCellValueBinding& );   // never implemented

#ifdef DBG_UTIL
    private:
        static  const char* checkConsistency_static( const void* _pThis );
                const char* checkConsistency( ) const;
#endif
    };

//.........................................................................
}   // namespace calc
//.........................................................................

#endif // SC_CELLVALUEBINDING_HXX
<|endoftext|>


<commit_before>nclude <iostream>
#include <climits>
using namespace std;

class edge;

class vertex
{
public:
  int value;
  edge *arry[6];
  bool visited;

  vertex()
  {
    value = INT_MAX;
    visited = false;
    for(int i = 0; i < 6; i++)
    {
      arry[i] = NULL;
    }
  }
};

class edge
{
public:
  int weight;
  vertex *to;

  edge()
  {
    to = NULL;
  }
};

bool FindSmallest(vertex *vrry[6], int &index)
{
   bool allvisited = true;
   int smallest;
   bool onlyonce = false;
   for(int i = 0; i < 6; i++)
   {
      if(vrry[i]->visited == false)
      {
        allvisited = false;
        if(onlyonce == false)
        {
          smallest = vrry[i]->value;

          onlyonce = true;
          index = i;
        }

        if(vrry[i]->value < smallest)
        {
          index = i;
          smallest = vrry[i]->value;
        }

      }
   }
   return !allvisited;
}

int main()
{
  //Array to hold vertex
  vertex *vrry[6];

  //Create the graph
  //Create f
  vertex *f = new vertex();
  //Add f
  vrry[0] = f;

  //Create d
  vertex *d = new vertex();
  edge *ed1 = new edge();
  ed1->weight = 2;
  ed1->to = f;
  d->arry[0] = ed1;
  //Add d
  vrry[1] = d;

  //Create e
  vertex *e = new vertex();
  edge *ee1 = new edge();
  ee1->weight = 2;
  ee1->to = f;
  e->arry[0] = ee1;
  edge *ee2 = new edge();
  ee2->weight = 3;
  ee2->to = d;
  e->arry[1] = ee2;
  //Add e
  vrry[2] = e;

  //Create c
  vertex *c = new vertex();
  edge *ec1 = new edge();
  ec1->weight = 3;
  ec1->to = e;
  c->arry[0] = ec1;
  //Add c
  vrry[3] = c;

  //Create b
  vertex *b = new vertex();
  edge *eb1 = new edge();
  eb1->weight = 4;
  eb1->to = d;
  b->arry[0] = eb1;
  edge *eb2 = new edge();
  eb2->weight = 2;
  eb2->to = e;
  b->arry[1] = eb2;
  edge *eb3 = new edge();
  eb3->weight = 1;
  eb3->to = c;
  b->arry[2] = eb3;
  //Add b
  vrry[4] = b;

  //Create a
  vertex *a = new vertex();
  a->value = 0;
  edge *ea1 = new edge();
  ea1->weight = 2;
  ea1->to = b;
  a->arry[0] = ea1;
  edge *ea2 = new edge();
  ea2->weight = 4;
  ea2->to = c;
  a->arry[1] = ea2;
  //Add d
  vrry[5] = a;

  //while array is not all visited
  bool allvisited = false;
  while(allvisited == false)
  {
     //find the smallest value vertex
     int smallest = 0;

     if(FindSmallest(vrry, smallest))
     {
       vrry[smallest]->visited = true;

       //relax the values of vertex
       int j = 0;
       while(vrry[smallest]->arry[j] != NULL)
       {
          if(vrry[smallest]->value + vrry[smallest]->arry[j]->weight < vrry[smallest]->arry[j]->to->value)
          {
            vrry[smallest]->arry[j]->to->value = vrry[smallest]->value + vrry[smallest]->arry[j]->weight;
          }
          j++;
       }

     }
     else
     {
      allvisited = true;
     }
  }
  cout<<"Done finding shortest paths"<<endl;
  cout<<c->value;
  return 0;
}
<commit_msg>Update dijkstra_simple.cpp<commit_after>include <iostream>
#include <climits>
using namespace std;

class edge;

class vertex
{
public:
  int value;
  edge *arry[6];
  bool visited;

  vertex()
  {
    value = INT_MAX;
    visited = false;
    for(int i = 0; i < 6; i++)
    {
      arry[i] = NULL;
    }
  }
};

class edge
{
public:
  int weight;
  vertex *to;

  edge()
  {
    to = NULL;
  }
};

bool FindSmallest(vertex *vrry[6], int &index)
{
   bool allvisited = true;
   int smallest;
   bool onlyonce = false;
   for(int i = 0; i < 6; i++)
   {
      if(vrry[i]->visited == false)
      {
        allvisited = false;
        if(onlyonce == false)
        {
          smallest = vrry[i]->value;

          onlyonce = true;
          index = i;
        }

        if(vrry[i]->value < smallest)
        {
          index = i;
          smallest = vrry[i]->value;
        }

      }
   }
   return !allvisited;
}

int main()
{
  //Array to hold vertex
  vertex *vrry[6];

  //Create the graph
  //Create f
  vertex *f = new vertex();
  //Add f
  vrry[0] = f;

  //Create d
  vertex *d = new vertex();
  edge *ed1 = new edge();
  ed1->weight = 2;
  ed1->to = f;
  d->arry[0] = ed1;
  //Add d
  vrry[1] = d;

  //Create e
  vertex *e = new vertex();
  edge *ee1 = new edge();
  ee1->weight = 2;
  ee1->to = f;
  e->arry[0] = ee1;
  edge *ee2 = new edge();
  ee2->weight = 3;
  ee2->to = d;
  e->arry[1] = ee2;
  //Add e
  vrry[2] = e;

  //Create c
  vertex *c = new vertex();
  edge *ec1 = new edge();
  ec1->weight = 3;
  ec1->to = e;
  c->arry[0] = ec1;
  //Add c
  vrry[3] = c;

  //Create b
  vertex *b = new vertex();
  edge *eb1 = new edge();
  eb1->weight = 4;
  eb1->to = d;
  b->arry[0] = eb1;
  edge *eb2 = new edge();
  eb2->weight = 2;
  eb2->to = e;
  b->arry[1] = eb2;
  edge *eb3 = new edge();
  eb3->weight = 1;
  eb3->to = c;
  b->arry[2] = eb3;
  //Add b
  vrry[4] = b;

  //Create a
  vertex *a = new vertex();
  a->value = 0;
  edge *ea1 = new edge();
  ea1->weight = 2;
  ea1->to = b;
  a->arry[0] = ea1;
  edge *ea2 = new edge();
  ea2->weight = 4;
  ea2->to = c;
  a->arry[1] = ea2;
  //Add d
  vrry[5] = a;

  //while array is not all visited
  bool allvisited = false;
  while(allvisited == false)
  {
     //find the smallest value vertex
     int smallest = 0;

     if(FindSmallest(vrry, smallest))
     {
       vrry[smallest]->visited = true;

       //relax the values of vertex
       int j = 0;
       while(vrry[smallest]->arry[j] != NULL)
       {
          if(vrry[smallest]->value + vrry[smallest]->arry[j]->weight < vrry[smallest]->arry[j]->to->value)
          {
            vrry[smallest]->arry[j]->to->value = vrry[smallest]->value + vrry[smallest]->arry[j]->weight;
          }
          j++;
       }

     }
     else
     {
      allvisited = true;
     }
  }
  cout<<"Done finding shortest paths"<<endl;
  cout<<c->value;
  return 0;
}
<|endoftext|>