<commit_before>/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2019, OpenROAD
// All rights reserved.
//
// BSD 3-Clause License
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////

#include "openroad/OpenRoad.hh"
#include "openroad/Version.hh" // BUILD_OPENPHYSYN

#include "opendb/db.h"
#include "opendb/wOrder.h"
#include "opendb/lefin.h"
#include "opendb/defin.h"
#include "opendb/defout.h"

#include "sta/VerilogWriter.hh"
#include "sta/StaMain.hh"

#include "db_sta/dbSta.hh"
#include "db_sta/MakeDbSta.hh"

#include "db_sta/dbReadVerilog.hh"
#include "db_sta/dbNetwork.hh"

#include "openroad/InitOpenRoad.hh"
#include "flute3/flute.h"

#include "init_fp//MakeInitFloorplan.hh"
#include "ioplacer/MakeIoplacer.h"
#include "resizer/MakeResizer.hh"
#include "gui/MakeGui.h"
#include "opendp/MakeOpendp.h"
#include "finale/MakeFinale.h"
#include "tritonmp/MakeTritonMp.h"
#include "replace/MakeReplace.h"
#include "fastroute/MakeFastRoute.h"
#include "TritonCTS/src/MakeTritoncts.h"
#include "tapcell/MakeTapcell.h"
#include "OpenRCX/MakeOpenRCX.h"
#include "triton_route/MakeTritonRoute.h"
#include "pdnsim/MakePDNSim.hh"
#include "antennachecker/MakeAntennaChecker.hh"
#ifdef BUILD_OPENPHYSYN
  #include "OpenPhySyn/MakeOpenPhySyn.hpp"
#endif

namespace sta {
extern const char *openroad_tcl_inits[];
}

// Swig uses C linkage for init functions.
extern "C" {
extern int Openroad_Init(Tcl_Interp *interp);
extern int Opendbtcl_Init(Tcl_Interp *interp);
}

namespace ord {

using std::min;
using std::max;

using odb::dbLib;
using odb::dbTech;
using odb::dbChip;
using odb::dbDatabase;
using odb::dbBlock;
using odb::Rect;
using odb::Point;

using sta::evalTclInit;
using sta::dbSta;
using sta::Resizer;

OpenRoad *OpenRoad::openroad_ = nullptr;

OpenRoad::OpenRoad()
  : tcl_interp_(nullptr),
    db_(nullptr),
    verilog_network_(nullptr),
    sta_(nullptr),
    resizer_(nullptr),
    ioPlacer_(nullptr),
    opendp_(nullptr),
    tritonMp_(nullptr),
    fastRoute_(nullptr),
    tritonCts_(nullptr),
    tapcell_(nullptr),
    extractor_(nullptr),
    antennaChecker_(nullptr),
#ifdef BUILD_OPENPHYSYN
    psn_(nullptr),
#endif
    replace_(nullptr),
    pdnsim_(nullptr)
{
  openroad_ = this;
  db_ = dbDatabase::create();
}

OpenRoad::~OpenRoad()
{
  deleteDbVerilogNetwork(verilog_network_);
  deleteDbSta(sta_);
  deleteIoplacer(ioPlacer_);
  deleteResizer(resizer_);
  deleteOpendp(opendp_);
  deleteFastRoute(fastRoute_);
  deleteTritonCts(tritonCts_);
  deleteTapcell(tapcell_);
  deleteTritonMp(tritonMp_);
  deleteOpenRCX(extractor_);
  deleteTritonRoute(detailed_router_);
  deleteReplace(replace_);
  deleteFinale(finale_);
#ifdef BUILD_OPENPHYSYN
  deletePsn(psn_);
#endif
  deleteAntennaChecker(antennaChecker_);
  odb::dbDatabase::destroy(db_);
  Flute::deleteLUT();
}

void
deleteAllMemory()
{
  delete OpenRoad::openRoad();
  sta::Sta::setSta(nullptr);
  sta::deleteAllMemory();
}

sta::dbNetwork *
OpenRoad::getDbNetwork()
{
  return sta_->getDbNetwork();
}

/* static */
OpenRoad *OpenRoad::openRoad()
{
  if (openroad_ == nullptr) {
    openroad_ = new OpenRoad;
  }
  return openroad_;
}

////////////////////////////////////////////////////////////////

void
initOpenRoad(Tcl_Interp *interp)
{
  OpenRoad::openRoad()->init(interp);
}

void
OpenRoad::init(Tcl_Interp *tcl_interp)
{
  tcl_interp_ = tcl_interp;

  // Make components.
  sta_ = makeDbSta();
  verilog_network_ = makeDbVerilogNetwork();
  ioPlacer_ = makeIoplacer();
  resizer_ = makeResizer();
  opendp_ = makeOpendp();
  finale_ = makeFinale();
  fastRoute_ = makeFastRoute();
  tritonCts_ = makeTritonCts();
  tapcell_ = makeTapcell();
  tritonMp_ = makeTritonMp();
  extractor_ = makeOpenRCX();
  detailed_router_ = makeTritonRoute();
  replace_ = makeReplace();
  pdnsim_ = makePDNSim();
  antennaChecker_ = makeAntennaChecker();
#ifdef BUILD_OPENPHYSYN
  psn_ = makePsn();
#endif

  // Init components.
  Openroad_Init(tcl_interp);
  // Import TCL scripts.
  evalTclInit(tcl_interp, sta::openroad_tcl_inits);

  Opendbtcl_Init(tcl_interp);
  initInitFloorplan(this);
  Flute::readLUT();
  initDbSta(this);
  initResizer(this);
  initGui(this);
  initDbVerilogNetwork(this);
  initIoplacer(this);
  initReplace(this);
  initOpendp(this);
  initFinale(this);
  initFastRoute(this);
  initTritonCts(this);
  initTapcell(this);
  initTritonMp(this);
  initOpenRCX(this);
  initTritonRoute(this);
  initPDNSim(this);
  initAntennaChecker(this);
#ifdef BUILD_OPENPHYSYN
    initPsn(this);
#endif

  // Import exported commands to global namespace.
  Tcl_Eval(tcl_interp, "sta::define_sta_cmds");
  Tcl_Eval(tcl_interp, "namespace import sta::*");
}

////////////////////////////////////////////////////////////////

void
OpenRoad::readLef(const char *filename,
		  const char *lib_name,
		  bool make_tech,
		  bool make_library)
{
  odb::lefin lef_reader(db_, false);
  dbLib *lib = nullptr;
  dbTech *tech = nullptr;
  if (make_tech && make_library) {
    lib = lef_reader.createTechAndLib(lib_name, filename);
    tech = db_->getTech();
  } else if (make_tech) {
    tech = lef_reader.createTech(filename);
  } else if (make_library) {
    lib = lef_reader.createLib(lib_name, filename);
  }

  // both are null on parser failure
  if (lib != nullptr || tech != nullptr) {
    for (Observer* observer : observers_) {
      observer->postReadLef(tech, lib);
    }
  }
}

void
OpenRoad::readDef(const char *filename,
		  bool order_wires,
		  bool continue_on_errors)
{
  odb::defin def_reader(db_);
  std::vector<odb::dbLib *> search_libs;
  for (odb::dbLib *lib : db_->getLibs())
    search_libs.push_back(lib);
  if (continue_on_errors) {
    def_reader.continueOnErrors();
  }
  dbChip* chip = def_reader.createChip(search_libs, filename);
  if (chip) {
    dbBlock* block = chip->getBlock();
    if (order_wires) {
      odb::orderWires(block,
                      nullptr /* net_name_or_id*/,
                      false /* force */,
                      false /* verbose */,
                      true /* quiet */);
    }

    for (Observer* observer : observers_) {
      observer->postReadDef(block);
    }
  }
}

static odb::defout::Version
stringToDefVersion(string version)
{
  if (version == "5.8")
    return odb::defout::Version::DEF_5_8;
  else if (version == "5.6")
    return odb::defout::Version::DEF_5_6;
  else if (version == "5.5")
    return odb::defout::Version::DEF_5_5;
  else if (version == "5.4")
    return odb::defout::Version::DEF_5_4;
  else if (version == "5.3")
    return odb::defout::Version::DEF_5_3;
  else
    return odb::defout::Version::DEF_5_8;
}

void
OpenRoad::writeDef(const char *filename,
		   string version)
{
  odb::dbChip *chip = db_->getChip();
  if (chip) {
    odb::dbBlock *block = chip->getBlock();
    if (block) {
      odb::defout def_writer;
      def_writer.setVersion(stringToDefVersion(version));
      def_writer.writeBlock(block, filename);
    }
  }
}

void
OpenRoad::readDb(const char *filename)
{
  FILE *stream = fopen(filename, "r");
  if (stream == nullptr) {
    return;
  }

  db_->read(stream);
  fclose(stream);

  for (Observer* observer : observers_) {
    observer->postReadDb(db_);
  }
}

void
OpenRoad::writeDb(const char *filename)
{
  FILE *stream = fopen(filename, "w");
  if (stream) {
    db_->write(stream);
    fclose(stream);
  }
}

void
OpenRoad::readVerilog(const char *filename)
{
  dbReadVerilog(filename, verilog_network_);
}

void
OpenRoad::linkDesign(const char *design_name)

{
  dbLinkDesign(design_name, verilog_network_, db_);
  for (Observer* observer : observers_) {
    observer->postReadDb(db_);
  }
}

void
OpenRoad::writeVerilog(const char *filename,
		       bool sort,
		       bool include_pwr_gnd,
		       std::vector<sta::LibertyCell*> *remove_cells)
{
  sta::writeVerilog(filename, sort, include_pwr_gnd,
		    remove_cells, sta_->network());
}

bool
OpenRoad::unitsInitialized()
{
  // Units are set by the first liberty library read.
  return getDbNetwork()->defaultLibertyLibrary() != nullptr;
}

odb::Rect
OpenRoad::getCore()
{
  return ord::getCore(db_->getChip()->getBlock());
}

void OpenRoad::addObserver(Observer *observer)
{
  assert(observer->owner_ == nullptr);
  observer->owner_ = this;
  observers_.insert(observer);
}

void OpenRoad::removeObserver(Observer *observer)
{
  observer->owner_ = nullptr;
  observers_.erase(observer);
}

OpenRoad::Observer::~Observer()
{
  if (owner_) {
    owner_->removeObserver(this);
  }
}

////////////////////////////////////////////////////////////////

// Need a header for these functions cherry uses in
// InitFloorplan, Resizer, OpenDP.

Rect
getCore(dbBlock *block)
{
  odb::Rect core;
  block->getCoreArea(core);
  return core;
}

// Return the point inside rect that is closest to pt.
Point
closestPtInRect(Rect rect,
		Point pt)
{
  return Point(min(max(pt.getX(), rect.xMin()), rect.xMax()),
               min(max(pt.getY(), rect.yMin()), rect.yMax()));
}

Point
closestPtInRect(Rect rect,
		int x,
		int y)
{
  return Point(min(max(x, rect.xMin()), rect.xMax()),
               min(max(y, rect.yMin()), rect.yMax()));
}

} // namespace
<commit_msg>initialize fields in OpenRoad<commit_after>/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2019, OpenROAD
// All rights reserved.
//
// BSD 3-Clause License
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////

#include "openroad/OpenRoad.hh"
#include "openroad/Version.hh" // BUILD_OPENPHYSYN

#include "opendb/db.h"
#include "opendb/wOrder.h"
#include "opendb/lefin.h"
#include "opendb/defin.h"
#include "opendb/defout.h"

#include "sta/VerilogWriter.hh"
#include "sta/StaMain.hh"

#include "db_sta/dbSta.hh"
#include "db_sta/MakeDbSta.hh"

#include "db_sta/dbReadVerilog.hh"
#include "db_sta/dbNetwork.hh"

#include "openroad/InitOpenRoad.hh"
#include "flute3/flute.h"

#include "init_fp//MakeInitFloorplan.hh"
#include "ioplacer/MakeIoplacer.h"
#include "resizer/MakeResizer.hh"
#include "gui/MakeGui.h"
#include "opendp/MakeOpendp.h"
#include "finale/MakeFinale.h"
#include "tritonmp/MakeTritonMp.h"
#include "replace/MakeReplace.h"
#include "fastroute/MakeFastRoute.h"
#include "TritonCTS/src/MakeTritoncts.h"
#include "tapcell/MakeTapcell.h"
#include "OpenRCX/MakeOpenRCX.h"
#include "triton_route/MakeTritonRoute.h"
#include "pdnsim/MakePDNSim.hh"
#include "antennachecker/MakeAntennaChecker.hh"
#ifdef BUILD_OPENPHYSYN
  #include "OpenPhySyn/MakeOpenPhySyn.hpp"
#endif

namespace sta {
extern const char *openroad_tcl_inits[];
}

// Swig uses C linkage for init functions.
extern "C" {
extern int Openroad_Init(Tcl_Interp *interp);
extern int Opendbtcl_Init(Tcl_Interp *interp);
}

namespace ord {

using std::min;
using std::max;

using odb::dbLib;
using odb::dbTech;
using odb::dbChip;
using odb::dbDatabase;
using odb::dbBlock;
using odb::Rect;
using odb::Point;

using sta::evalTclInit;
using sta::dbSta;
using sta::Resizer;

OpenRoad *OpenRoad::openroad_ = nullptr;

OpenRoad::OpenRoad()
  : tcl_interp_(nullptr),
    db_(nullptr),
    verilog_network_(nullptr),
    sta_(nullptr),
    resizer_(nullptr),
    ioPlacer_(nullptr),
    opendp_(nullptr),
    finale_(nullptr),
    tritonMp_(nullptr),
    fastRoute_(nullptr),
    tritonCts_(nullptr),
    tapcell_(nullptr),
    extractor_(nullptr),
    detailed_router_(nullptr),
    antennaChecker_(nullptr),
    psn_(nullptr),
    replace_(nullptr),
    pdnsim_(nullptr)
{
  openroad_ = this;
  db_ = dbDatabase::create();
}

OpenRoad::~OpenRoad()
{
  deleteDbVerilogNetwork(verilog_network_);
  deleteDbSta(sta_);
  deleteIoplacer(ioPlacer_);
  deleteResizer(resizer_);
  deleteOpendp(opendp_);
  deleteFastRoute(fastRoute_);
  deleteTritonCts(tritonCts_);
  deleteTapcell(tapcell_);
  deleteTritonMp(tritonMp_);
  deleteOpenRCX(extractor_);
  deleteTritonRoute(detailed_router_);
  deleteReplace(replace_);
  deleteFinale(finale_);
#ifdef BUILD_OPENPHYSYN
  deletePsn(psn_);
#endif
  deleteAntennaChecker(antennaChecker_);
  odb::dbDatabase::destroy(db_);
  Flute::deleteLUT();
}

void
deleteAllMemory()
{
  delete OpenRoad::openRoad();
  sta::Sta::setSta(nullptr);
  sta::deleteAllMemory();
}

sta::dbNetwork *
OpenRoad::getDbNetwork()
{
  return sta_->getDbNetwork();
}

/* static */
OpenRoad *OpenRoad::openRoad()
{
  if (openroad_ == nullptr) {
    openroad_ = new OpenRoad;
  }
  return openroad_;
}

////////////////////////////////////////////////////////////////

void
initOpenRoad(Tcl_Interp *interp)
{
  OpenRoad::openRoad()->init(interp);
}

void
OpenRoad::init(Tcl_Interp *tcl_interp)
{
  tcl_interp_ = tcl_interp;

  // Make components.
  sta_ = makeDbSta();
  verilog_network_ = makeDbVerilogNetwork();
  ioPlacer_ = makeIoplacer();
  resizer_ = makeResizer();
  opendp_ = makeOpendp();
  finale_ = makeFinale();
  fastRoute_ = makeFastRoute();
  tritonCts_ = makeTritonCts();
  tapcell_ = makeTapcell();
  tritonMp_ = makeTritonMp();
  extractor_ = makeOpenRCX();
  detailed_router_ = makeTritonRoute();
  replace_ = makeReplace();
  pdnsim_ = makePDNSim();
  antennaChecker_ = makeAntennaChecker();
#ifdef BUILD_OPENPHYSYN
  psn_ = makePsn();
#endif

  // Init components.
  Openroad_Init(tcl_interp);
  // Import TCL scripts.
  evalTclInit(tcl_interp, sta::openroad_tcl_inits);

  Opendbtcl_Init(tcl_interp);
  initInitFloorplan(this);
  Flute::readLUT();
  initDbSta(this);
  initResizer(this);
  initGui(this);
  initDbVerilogNetwork(this);
  initIoplacer(this);
  initReplace(this);
  initOpendp(this);
  initFinale(this);
  initFastRoute(this);
  initTritonCts(this);
  initTapcell(this);
  initTritonMp(this);
  initOpenRCX(this);
  initTritonRoute(this);
  initPDNSim(this);
  initAntennaChecker(this);
#ifdef BUILD_OPENPHYSYN
    initPsn(this);
#endif

  // Import exported commands to global namespace.
  Tcl_Eval(tcl_interp, "sta::define_sta_cmds");
  Tcl_Eval(tcl_interp, "namespace import sta::*");
}

////////////////////////////////////////////////////////////////

void
OpenRoad::readLef(const char *filename,
		  const char *lib_name,
		  bool make_tech,
		  bool make_library)
{
  odb::lefin lef_reader(db_, false);
  dbLib *lib = nullptr;
  dbTech *tech = nullptr;
  if (make_tech && make_library) {
    lib = lef_reader.createTechAndLib(lib_name, filename);
    tech = db_->getTech();
  } else if (make_tech) {
    tech = lef_reader.createTech(filename);
  } else if (make_library) {
    lib = lef_reader.createLib(lib_name, filename);
  }

  // both are null on parser failure
  if (lib != nullptr || tech != nullptr) {
    for (Observer* observer : observers_) {
      observer->postReadLef(tech, lib);
    }
  }
}

void
OpenRoad::readDef(const char *filename,
		  bool order_wires,
		  bool continue_on_errors)
{
  odb::defin def_reader(db_);
  std::vector<odb::dbLib *> search_libs;
  for (odb::dbLib *lib : db_->getLibs())
    search_libs.push_back(lib);
  if (continue_on_errors) {
    def_reader.continueOnErrors();
  }
  dbChip* chip = def_reader.createChip(search_libs, filename);
  if (chip) {
    dbBlock* block = chip->getBlock();
    if (order_wires) {
      odb::orderWires(block,
                      nullptr /* net_name_or_id*/,
                      false /* force */,
                      false /* verbose */,
                      true /* quiet */);
    }

    for (Observer* observer : observers_) {
      observer->postReadDef(block);
    }
  }
}

static odb::defout::Version
stringToDefVersion(string version)
{
  if (version == "5.8")
    return odb::defout::Version::DEF_5_8;
  else if (version == "5.6")
    return odb::defout::Version::DEF_5_6;
  else if (version == "5.5")
    return odb::defout::Version::DEF_5_5;
  else if (version == "5.4")
    return odb::defout::Version::DEF_5_4;
  else if (version == "5.3")
    return odb::defout::Version::DEF_5_3;
  else
    return odb::defout::Version::DEF_5_8;
}

void
OpenRoad::writeDef(const char *filename,
		   string version)
{
  odb::dbChip *chip = db_->getChip();
  if (chip) {
    odb::dbBlock *block = chip->getBlock();
    if (block) {
      odb::defout def_writer;
      def_writer.setVersion(stringToDefVersion(version));
      def_writer.writeBlock(block, filename);
    }
  }
}

void
OpenRoad::readDb(const char *filename)
{
  FILE *stream = fopen(filename, "r");
  if (stream == nullptr) {
    return;
  }

  db_->read(stream);
  fclose(stream);

  for (Observer* observer : observers_) {
    observer->postReadDb(db_);
  }
}

void
OpenRoad::writeDb(const char *filename)
{
  FILE *stream = fopen(filename, "w");
  if (stream) {
    db_->write(stream);
    fclose(stream);
  }
}

void
OpenRoad::readVerilog(const char *filename)
{
  dbReadVerilog(filename, verilog_network_);
}

void
OpenRoad::linkDesign(const char *design_name)

{
  dbLinkDesign(design_name, verilog_network_, db_);
  for (Observer* observer : observers_) {
    observer->postReadDb(db_);
  }
}

void
OpenRoad::writeVerilog(const char *filename,
		       bool sort,
		       bool include_pwr_gnd,
		       std::vector<sta::LibertyCell*> *remove_cells)
{
  sta::writeVerilog(filename, sort, include_pwr_gnd,
		    remove_cells, sta_->network());
}

bool
OpenRoad::unitsInitialized()
{
  // Units are set by the first liberty library read.
  return getDbNetwork()->defaultLibertyLibrary() != nullptr;
}

odb::Rect
OpenRoad::getCore()
{
  return ord::getCore(db_->getChip()->getBlock());
}

void OpenRoad::addObserver(Observer *observer)
{
  assert(observer->owner_ == nullptr);
  observer->owner_ = this;
  observers_.insert(observer);
}

void OpenRoad::removeObserver(Observer *observer)
{
  observer->owner_ = nullptr;
  observers_.erase(observer);
}

OpenRoad::Observer::~Observer()
{
  if (owner_) {
    owner_->removeObserver(this);
  }
}

////////////////////////////////////////////////////////////////

// Need a header for these functions cherry uses in
// InitFloorplan, Resizer, OpenDP.

Rect
getCore(dbBlock *block)
{
  odb::Rect core;
  block->getCoreArea(core);
  return core;
}

// Return the point inside rect that is closest to pt.
Point
closestPtInRect(Rect rect,
		Point pt)
{
  return Point(min(max(pt.getX(), rect.xMin()), rect.xMax()),
               min(max(pt.getY(), rect.yMin()), rect.yMax()));
}

Point
closestPtInRect(Rect rect,
		int x,
		int y)
{
  return Point(min(max(x, rect.xMin()), rect.xMax()),
               min(max(y, rect.yMin()), rect.yMax()));
}

} // namespace
<|endoftext|>


<commit_before><?hh // strict
namespace Usox\Sharesta;

final class Response implements ResponseInterface {

	private Map<int, string> $codes = Map {
		200 => 'OK',
		201 => 'Created',
		202 => 'Accepted',
		204 => 'No Content',
		301 => 'Moved Permanently',
		302 => 'Found',
		304 => 'Not Modified',
		307 => 'Temporary Redirect',
		308 => 'Permanent Redirect',
		400 => 'Bad Request',
		401 => 'Unauthorized',
		403 => 'Forbidden',
		404 => 'Not Found',
		405 => 'Method Not Allowed',
		406 => 'Not Acceptable',
		410 => 'Gone',
		415 => 'Unsupported Media Type',
		417 => 'Expectation Failed',
		429 => 'Too Many Requests',
		500 => 'Internal Server Error',
		501 => 'Not Implemented'
	};

	public function __construct(
		private int $code,
		private mixed $body
	) {}

	public function send(): void {
		if ($this->codes->contains($this->code)) {
			if (!$this->body) {
				$this->body = $this->codes->get($this->code);
			}
		} else {
			$this->code = 500;
			$this->body = 'API attempted to return an unknown HTTP status.';
		}

		header(
			sprintf(
				'HTTP/1.1 %d %s' ,
				$this->code,
				$this->codes->get($this->code)
			)
		);
		header('Content-type: application/json');
		echo json_encode($this->body);
	}
}
<commit_msg>Remove unused http status messages<commit_after><?hh // strict
namespace Usox\Sharesta;

final class Response implements ResponseInterface {

	private Map<int, string> $codes = Map {
		Application::HTTP_OK => 'OK',
		Application::HTTP_BAD_REQUEST => 'Bad Request',
		Application::HTTP_NOT_FOUND => 'Not Found',
		Application::HTTP_INTERNAL_SERVER_ERROR => 'Internal Server Error',
	};

	public function __construct(
		private int $code,
		private mixed $body
	) {}

	public function send(): void {
		if ($this->codes->contains($this->code)) {
			if (!$this->body) {
				$this->body = $this->codes->get($this->code);
			}
		} else {
			$this->code = 500;
			$this->body = 'API attempted to return an unknown HTTP status.';
		}

		header(
			sprintf(
				'HTTP/1.1 %d %s' ,
				$this->code,
				$this->codes->get($this->code)
			)
		);
		header('Content-type: application/json');
		echo json_encode($this->body);
	}
}
<|endoftext|>


<commit_before>///
/// @file  PiTable.cpp
/// @brief The PiTable class is a compressed lookup table for
///        prime counts. Each bit in the lookup table corresponds
///        to an odd integer and that bit is set to 1 if the
///        integer is a prime. PiTable uses only (n / 8) bytes of
///        memory and returns the number of primes <= n in O(1)
///        operations.
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <PiTable.hpp>
#include <primesieve.hpp>

#include <stdint.h>
#include <array>
#include <vector>

namespace {

constexpr uint64_t bitmask(uint64_t n)
{
  return ((n + 1) / 2 == 64) ? 0xffffffffffffffffull
         : (1ull << ((n + 1) / 2)) - 1;
}

} // namespace

namespace primecount {

const std::array<uint64_t, 128>  PiTable::unset_bits_ =
{
  bitmask(0),   bitmask(1),   bitmask(2),   bitmask(3),
  bitmask(4),   bitmask(5),   bitmask(6),   bitmask(7),
  bitmask(8),   bitmask(9),   bitmask(10),  bitmask(11),
  bitmask(12),  bitmask(13),  bitmask(14),  bitmask(15),
  bitmask(16),  bitmask(17),  bitmask(18),  bitmask(19),
  bitmask(20),  bitmask(21),  bitmask(22),  bitmask(23),
  bitmask(24),  bitmask(25),  bitmask(26),  bitmask(27),
  bitmask(28),  bitmask(29),  bitmask(30),  bitmask(31),
  bitmask(32),  bitmask(33),  bitmask(34),  bitmask(35),
  bitmask(36),  bitmask(37),  bitmask(38),  bitmask(39),
  bitmask(40),  bitmask(41),  bitmask(42),  bitmask(43),
  bitmask(44),  bitmask(45),  bitmask(46),  bitmask(47),
  bitmask(48),  bitmask(49),  bitmask(50),  bitmask(51),
  bitmask(52),  bitmask(53),  bitmask(54),  bitmask(55),
  bitmask(56),  bitmask(57),  bitmask(58),  bitmask(59),
  bitmask(60),  bitmask(61),  bitmask(62),  bitmask(63),
  bitmask(64),  bitmask(65),  bitmask(66),  bitmask(67),
  bitmask(68),  bitmask(69),  bitmask(70),  bitmask(71),
  bitmask(72),  bitmask(73),  bitmask(74),  bitmask(75),
  bitmask(76),  bitmask(77),  bitmask(78),  bitmask(79),
  bitmask(80),  bitmask(81),  bitmask(82),  bitmask(83),
  bitmask(84),  bitmask(85),  bitmask(86),  bitmask(87),
  bitmask(88),  bitmask(89),  bitmask(90),  bitmask(91),
  bitmask(92),  bitmask(93),  bitmask(94),  bitmask(95),
  bitmask(96),  bitmask(97),  bitmask(98),  bitmask(99),
  bitmask(100), bitmask(101), bitmask(102), bitmask(103),
  bitmask(104), bitmask(105), bitmask(106), bitmask(107),
  bitmask(108), bitmask(109), bitmask(110), bitmask(111),
  bitmask(112), bitmask(113), bitmask(114), bitmask(115),
  bitmask(116), bitmask(117), bitmask(118), bitmask(119),
  bitmask(120), bitmask(121), bitmask(122), bitmask(123),
  bitmask(124), bitmask(125), bitmask(126), bitmask(127)
};

PiTable::PiTable(uint64_t max) :
  max_(max)
{
  pi_.resize(max / 128 + 1);
  primesieve::iterator it(2, max);

  uint64_t pix = 0;
  uint64_t prime = 0;

  // Since we store only odd numbers in our lookup table,
  // we cannot store 2 which is the only even prime.
  // As a workaround we mark 1 as a prime (1st bit) and
  // add a check to return 0 for pi[1].
  pi_[0].bits = 1;

  while ((prime = it.next_prime()) <= max)
    pi_[prime / 128].bits |= 1ull << (prime % 128 / 2);

  for (auto& i : pi_)
  {
    i.prime_count = pix;
    pix += popcnt64(i.bits);
  }
}

} // namespace
<commit_msg>Remove empty space<commit_after>///
/// @file  PiTable.cpp
/// @brief The PiTable class is a compressed lookup table for
///        prime counts. Each bit in the lookup table corresponds
///        to an odd integer and that bit is set to 1 if the
///        integer is a prime. PiTable uses only (n / 8) bytes of
///        memory and returns the number of primes <= n in O(1)
///        operations.
///
/// Copyright (C) 2019 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <PiTable.hpp>
#include <primesieve.hpp>

#include <stdint.h>
#include <array>
#include <vector>

namespace {

constexpr uint64_t bitmask(uint64_t n)
{
  return ((n + 1) / 2 == 64) ? 0xffffffffffffffffull
         : (1ull << ((n + 1) / 2)) - 1;
}

} // namespace

namespace primecount {

const std::array<uint64_t, 128> PiTable::unset_bits_ =
{
  bitmask(0),   bitmask(1),   bitmask(2),   bitmask(3),
  bitmask(4),   bitmask(5),   bitmask(6),   bitmask(7),
  bitmask(8),   bitmask(9),   bitmask(10),  bitmask(11),
  bitmask(12),  bitmask(13),  bitmask(14),  bitmask(15),
  bitmask(16),  bitmask(17),  bitmask(18),  bitmask(19),
  bitmask(20),  bitmask(21),  bitmask(22),  bitmask(23),
  bitmask(24),  bitmask(25),  bitmask(26),  bitmask(27),
  bitmask(28),  bitmask(29),  bitmask(30),  bitmask(31),
  bitmask(32),  bitmask(33),  bitmask(34),  bitmask(35),
  bitmask(36),  bitmask(37),  bitmask(38),  bitmask(39),
  bitmask(40),  bitmask(41),  bitmask(42),  bitmask(43),
  bitmask(44),  bitmask(45),  bitmask(46),  bitmask(47),
  bitmask(48),  bitmask(49),  bitmask(50),  bitmask(51),
  bitmask(52),  bitmask(53),  bitmask(54),  bitmask(55),
  bitmask(56),  bitmask(57),  bitmask(58),  bitmask(59),
  bitmask(60),  bitmask(61),  bitmask(62),  bitmask(63),
  bitmask(64),  bitmask(65),  bitmask(66),  bitmask(67),
  bitmask(68),  bitmask(69),  bitmask(70),  bitmask(71),
  bitmask(72),  bitmask(73),  bitmask(74),  bitmask(75),
  bitmask(76),  bitmask(77),  bitmask(78),  bitmask(79),
  bitmask(80),  bitmask(81),  bitmask(82),  bitmask(83),
  bitmask(84),  bitmask(85),  bitmask(86),  bitmask(87),
  bitmask(88),  bitmask(89),  bitmask(90),  bitmask(91),
  bitmask(92),  bitmask(93),  bitmask(94),  bitmask(95),
  bitmask(96),  bitmask(97),  bitmask(98),  bitmask(99),
  bitmask(100), bitmask(101), bitmask(102), bitmask(103),
  bitmask(104), bitmask(105), bitmask(106), bitmask(107),
  bitmask(108), bitmask(109), bitmask(110), bitmask(111),
  bitmask(112), bitmask(113), bitmask(114), bitmask(115),
  bitmask(116), bitmask(117), bitmask(118), bitmask(119),
  bitmask(120), bitmask(121), bitmask(122), bitmask(123),
  bitmask(124), bitmask(125), bitmask(126), bitmask(127)
};

PiTable::PiTable(uint64_t max) :
  max_(max)
{
  pi_.resize(max / 128 + 1);
  primesieve::iterator it(2, max);

  uint64_t pix = 0;
  uint64_t prime = 0;

  // Since we store only odd numbers in our lookup table,
  // we cannot store 2 which is the only even prime.
  // As a workaround we mark 1 as a prime (1st bit) and
  // add a check to return 0 for pi[1].
  pi_[0].bits = 1;

  while ((prime = it.next_prime()) <= max)
    pi_[prime / 128].bits |= 1ull << (prime % 128 / 2);

  for (auto& i : pi_)
  {
    i.prime_count = pix;
    pix += popcnt64(i.bits);
  }
}

} // namespace
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/software/license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "Sampler.h"
#include "Parameter.h"
#include <cassert>

namespace madai {

Sampler
::Sampler( const Model *model ) :
  m_Model(model),
  m_CurrentParameters(model->GetNumberOfParameters(),0.0),
  m_OutputScalarToOptimizeIndex( 0 ),
  m_ActiveParameterIndices(model->GetNumberOfParameters(), true),
  m_OptimizeOnLikelihood(false)
{
  assert(model != NULL);
  unsigned int np = this->m_Model->GetNumberOfParameters();
  unsigned int nt = this->m_Model->GetNumberOfScalarOutputs();
  assert(this->m_OutputScalarToOptimizeIndex < nt);

  // Initialize the vector for current parameters.
  m_CurrentParameters.resize( m_Model->GetNumberOfParameters() );

  // Activate all parameters by default.
  const std::vector< Parameter > & params = this->m_Model->GetParameters();
  assert(np == params.size());

  for (unsigned int i = 0; (i < np); ++i)
    {
    this->m_ActiveParameters.insert( params[i].m_Name );
    }

  this->m_OutputScalarToOptimize
    = this->m_Model->GetScalarOutputNames().at(
      this->m_OutputScalarToOptimizeIndex);
}

Sampler
::~Sampler()
{
}

const Model *
Sampler
::GetModel() const
{
  return m_Model;
}

std::set< std::string >
Sampler
::GetActiveParameters()
{
  return m_ActiveParameters;
}

void
Sampler
::ActivateParameter( const std::string & parameterName )
{
  bool found = false;
  unsigned int np = this->GetNumberOfParameters();
  const std::vector< Parameter > & params = this->GetParameters();
  assert(np == params.size());
  for (unsigned int i = 0; (i < np) && (! found); ++i) {
    const std::string & name = params[i].m_Name;
    if (parameterName == name) {
      this->m_ActiveParameterIndices[i] = true;
      m_ActiveParameters.insert( parameterName );
      found = true;
    }
  }
  assert(found); // should return an error, but this is a void function :(
}

void
Sampler
::ActivateParameter( unsigned int parameterIndex ) {
  assert(parameterIndex < this->GetNumberOfParameters());
  assert(this->GetNumberOfParameters() == this->GetParameters().size());
  assert(this->GetNumberOfParameters() == this->m_ActiveParameterIndices.size());
  this->m_ActiveParameterIndices[parameterIndex] = true;
  this->m_ActiveParameters.insert(this->GetParameters()[parameterIndex].m_Name);
}

void
Sampler
::DeactivateParameter( const std::string & parameterName )
{
  bool found = false;
  unsigned int np = this->GetNumberOfParameters();
  const std::vector< Parameter > & params = this->GetParameters();
  assert(np == params.size());
  for (unsigned int i = 0; (i < np) && (! found); ++i) {
    const std::string & name = params[i].m_Name;
    if (parameterName == name) {
      this->m_ActiveParameterIndices[i] = false;
      m_ActiveParameters.erase( parameterName );
      found = true;
    }
  }
  assert(found); // should return an error, but this is a void function :(

}

void
Sampler
::DeactivateParameter( unsigned int parameterIndex ) {
  assert(parameterIndex < this->GetNumberOfParameters());
  assert(this->GetNumberOfParameters() == this->GetParameters().size());
  assert(this->GetNumberOfParameters() == this->m_ActiveParameterIndices.size());
  this->m_ActiveParameterIndices[parameterIndex] = false;
  this->m_ActiveParameters.erase(this->GetParameters()[parameterIndex].m_Name);
}

unsigned int
Sampler
::GetNumberOfParameters() const {
  if (this->GetModel() != NULL)
    return this->GetModel()->GetNumberOfParameters();
  else
    return 0;
}

const std::vector< Parameter > &
Sampler
::GetParameters() const {
  assert (this->GetModel() != NULL);
  return this->GetModel()->GetParameters();
}

unsigned int
Sampler
::GetNumberOfActiveParameters() const
{
  return static_cast< unsigned int >( m_ActiveParameters.size() );
}

Sampler::ErrorType
Sampler
::SetParameterValue( const std::string & parameterName, double value )
{
  unsigned int parameterIndex = this->GetParameterIndex( parameterName );

  if ( parameterIndex == static_cast< unsigned int >( -1 ) )
    {
    // Error. Parameter not found.
    return INVALID_PARAMETER_INDEX_ERROR;
    }

  m_CurrentParameters[parameterIndex] = value;

  // TODO - set dirty flag

  return NO_ERROR;
}

Sampler::ErrorType
Sampler
::SetOutputScalarToOptimize( const std::string & scalarName )
{
  unsigned int idx = this->GetOutputScalarIndex( scalarName );
  if ( idx == static_cast< unsigned int >( -1 ) )
    return INVALID_PARAMETER_INDEX_ERROR;
  this->m_OutputScalarToOptimize = scalarName;
  this->m_OutputScalarToOptimizeIndex = idx;
  return NO_ERROR;
}

Sampler::ErrorType
Sampler
::SetOutputScalarToOptimize( unsigned int idx )
{
  if (idx >= m_Model->GetNumberOfScalarOutputs())
    return INVALID_PARAMETER_INDEX_ERROR;
  this->m_OutputScalarToOptimizeIndex = idx;
  this->m_OutputScalarToOptimize = this->m_Model->GetScalarOutputNames()[idx];
  return NO_ERROR;
}

std::string
Sampler
::GetOutputScalarToOptimizeName()
{
  return this->m_OutputScalarToOptimize;
}

unsigned int
Sampler
::GetOutputScalarToOptimizeIndex() const
{
  return this->m_OutputScalarToOptimizeIndex;
}

const std::vector< double > &
Sampler
::GetCurrentParameters() const
{
  return m_CurrentParameters;
}

unsigned int
Sampler
::GetOutputScalarIndex( const std::string & scalarName ) const
{
  std::vector< std::string > const & outputs = this->m_Model->GetScalarOutputNames();
  for ( unsigned int i = 0; i < outputs.size(); i++ )
    {
    if ( outputs[i] == scalarName )
      return i;
    }

  return static_cast< unsigned int >(-1); // Intentional underflow
}

unsigned int
Sampler
::GetParameterIndex( const std::string & parameterName ) const
{
  const std::vector< Parameter > & parameters = this->m_Model->GetParameters();
  for ( unsigned int i = 0; i < m_Model->GetNumberOfParameters(); i++ )
    {
    if ( parameters[i].m_Name == parameterName )
      return i;
    }

  return static_cast< unsigned int >(-1); // Intentional underflow
}

// To check if the model supplis a method for calculating the Likelihood and Prior
bool
Sampler
::IsLikeAndPrior() const
{
  std::cerr << "Using point at center of each parameter range" << std::endl;
  double * range = new double[2]();
  std::vector< double > temp_vals( this->m_Model->GetNumberOfParameters(), 0.0 );

  for ( unsigned int i = 0; i < this->m_Model->GetNumberOfParameters(); i++ ) {
    this->m_Model->GetRange( i, range );
    temp_vals[i] = (range[0] + range[1]) / 2;
    std::cerr << temp_vals[i] << "  ";
  }
  std::cerr << std::endl;

  double Likelihood, Prior;
  if ( this->m_Model->GetLikeAndPrior( temp_vals, Likelihood, Prior ) != Model::NO_ERROR ) {
    std::cerr << "GetLikeAndPrior not defined in model" << std::endl;
    return false;
  } else {
    std::cerr << "GetLikeAndPrior is defined" << std::endl;
    return true;
  }
}

bool
Sampler
::GetOptimizeOnLikelihood() const {
  return this->m_OptimizeOnLikelihood;
}

void
Sampler
::SetOptimizeOnLikelihood(bool val) {
  this->m_OptimizeOnLikelihood = val;
}

} // end namespace madai

<commit_msg>Simplified implementation of some methods<commit_after>/*=========================================================================
 *
 *  Copyright The University of North Carolina at Chapel Hill
 *  All rights reserved.
 *
 *  Licensed under the MADAI Software License. You may obtain a copy of
 *  this license at
 *
 *         https://madai-public.cs.unc.edu/software/license/
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "Sampler.h"
#include "Parameter.h"
#include <cassert>

namespace madai {

Sampler
::Sampler( const Model *model ) :
  m_Model(model),
  m_CurrentParameters(model->GetNumberOfParameters(),0.0),
  m_OutputScalarToOptimizeIndex( 0 ),
  m_ActiveParameterIndices(model->GetNumberOfParameters(), true),
  m_OptimizeOnLikelihood(false)
{
  assert(model != NULL);
  unsigned int np = this->m_Model->GetNumberOfParameters();
  unsigned int nt = this->m_Model->GetNumberOfScalarOutputs();
  assert(this->m_OutputScalarToOptimizeIndex < nt);

  // Initialize the vector for current parameters.
  m_CurrentParameters.resize( m_Model->GetNumberOfParameters() );

  // Activate all parameters by default.
  const std::vector< Parameter > & params = this->m_Model->GetParameters();
  assert(np == params.size());

  for (unsigned int i = 0; (i < np); ++i)
    {
    this->m_ActiveParameters.insert( params[i].m_Name );
    }

  this->m_OutputScalarToOptimize
    = this->m_Model->GetScalarOutputNames().at(
      this->m_OutputScalarToOptimizeIndex);
}

Sampler
::~Sampler()
{
}

const Model *
Sampler
::GetModel() const
{
  return m_Model;
}

std::set< std::string >
Sampler
::GetActiveParameters()
{
  return m_ActiveParameters;
}

void
Sampler
::ActivateParameter( const std::string & parameterName )
{
  bool found = false;
  unsigned int parameterIndex = this->GetParameterIndex( parameterName );
  if ( parameterIndex != static_cast< unsigned int >(-1) ) {
    m_ActiveParameterIndices[parameterIndex] = true;
    m_ActiveParameters.insert( parameterName );
    found = true;
  }

  assert(found); // should return an error, but this is a void function :(
}

void
Sampler
::ActivateParameter( unsigned int parameterIndex ) {
  assert(parameterIndex < this->GetNumberOfParameters());
  assert(this->GetNumberOfParameters() == this->GetParameters().size());
  assert(this->GetNumberOfParameters() == m_ActiveParameterIndices.size());
  m_ActiveParameterIndices[parameterIndex] = true;
  m_ActiveParameters.insert(this->GetParameters()[parameterIndex].m_Name);
}

void
Sampler
::DeactivateParameter( const std::string & parameterName )
{
  bool found = false;
  unsigned int parameterIndex = this->GetParameterIndex( parameterName );
  if ( parameterIndex != static_cast< unsigned int >(-1) ) {
    m_ActiveParameterIndices[ parameterIndex ] = false;
    m_ActiveParameters.erase( parameterName );
    found = true;
  }

  assert(found); // should return an error, but this is a void function :(
}

void
Sampler
::DeactivateParameter( unsigned int parameterIndex ) {
  assert(parameterIndex < this->GetNumberOfParameters());
  assert(this->GetNumberOfParameters() == this->GetParameters().size());
  assert(this->GetNumberOfParameters() == m_ActiveParameterIndices.size());
  m_ActiveParameterIndices[parameterIndex] = false;
  m_ActiveParameters.erase(this->GetParameters()[parameterIndex].m_Name);
}

unsigned int
Sampler
::GetNumberOfParameters() const {
  if (this->GetModel() != NULL)
    return this->GetModel()->GetNumberOfParameters();
  else
    return 0;
}

const std::vector< Parameter > &
Sampler
::GetParameters() const {
  assert (this->GetModel() != NULL);
  return this->GetModel()->GetParameters();
}

unsigned int
Sampler
::GetNumberOfActiveParameters() const
{
  return static_cast< unsigned int >( m_ActiveParameters.size() );
}

Sampler::ErrorType
Sampler
::SetParameterValue( const std::string & parameterName, double value )
{
  unsigned int parameterIndex = this->GetParameterIndex( parameterName );

  if ( parameterIndex == static_cast< unsigned int >( -1 ) )
    {
    // Error. Parameter not found.
    return INVALID_PARAMETER_INDEX_ERROR;
    }

  m_CurrentParameters[parameterIndex] = value;

  // TODO - set dirty flag

  return NO_ERROR;
}

Sampler::ErrorType
Sampler
::SetOutputScalarToOptimize( const std::string & scalarName )
{
  unsigned int idx = this->GetOutputScalarIndex( scalarName );
  if ( idx == static_cast< unsigned int >( -1 ) )
    return INVALID_PARAMETER_INDEX_ERROR;
  this->m_OutputScalarToOptimize = scalarName;
  this->m_OutputScalarToOptimizeIndex = idx;
  return NO_ERROR;
}

Sampler::ErrorType
Sampler
::SetOutputScalarToOptimize( unsigned int idx )
{
  if (idx >= m_Model->GetNumberOfScalarOutputs())
    return INVALID_PARAMETER_INDEX_ERROR;
  this->m_OutputScalarToOptimizeIndex = idx;
  this->m_OutputScalarToOptimize = this->m_Model->GetScalarOutputNames()[idx];
  return NO_ERROR;
}

std::string
Sampler
::GetOutputScalarToOptimizeName()
{
  return this->m_OutputScalarToOptimize;
}

unsigned int
Sampler
::GetOutputScalarToOptimizeIndex() const
{
  return this->m_OutputScalarToOptimizeIndex;
}

const std::vector< double > &
Sampler
::GetCurrentParameters() const
{
  return m_CurrentParameters;
}

unsigned int
Sampler
::GetOutputScalarIndex( const std::string & scalarName ) const
{
  std::vector< std::string > const & outputs = this->m_Model->GetScalarOutputNames();
  for ( unsigned int i = 0; i < outputs.size(); i++ )
    {
    if ( outputs[i] == scalarName )
      return i;
    }

  return static_cast< unsigned int >(-1); // Intentional underflow
}

unsigned int
Sampler
::GetParameterIndex( const std::string & parameterName ) const
{
  const std::vector< Parameter > & parameters = this->m_Model->GetParameters();
  for ( unsigned int i = 0; i < m_Model->GetNumberOfParameters(); i++ )
    {
    if ( parameters[i].m_Name == parameterName )
      return i;
    }

  return static_cast< unsigned int >(-1); // Intentional underflow
}

// To check if the model supplis a method for calculating the Likelihood and Prior
bool
Sampler
::IsLikeAndPrior() const
{
  std::cerr << "Using point at center of each parameter range" << std::endl;
  double * range = new double[2]();
  std::vector< double > temp_vals( this->m_Model->GetNumberOfParameters(), 0.0 );

  for ( unsigned int i = 0; i < this->m_Model->GetNumberOfParameters(); i++ ) {
    this->m_Model->GetRange( i, range );
    temp_vals[i] = (range[0] + range[1]) / 2;
    std::cerr << temp_vals[i] << "  ";
  }
  std::cerr << std::endl;

  double Likelihood, Prior;
  if ( this->m_Model->GetLikeAndPrior( temp_vals, Likelihood, Prior ) != Model::NO_ERROR ) {
    std::cerr << "GetLikeAndPrior not defined in model" << std::endl;
    return false;
  } else {
    std::cerr << "GetLikeAndPrior is defined" << std::endl;
    return true;
  }
}

bool
Sampler
::GetOptimizeOnLikelihood() const {
  return this->m_OptimizeOnLikelihood;
}

void
Sampler
::SetOptimizeOnLikelihood(bool val) {
  this->m_OptimizeOnLikelihood = val;
}

} // end namespace madai

<|endoftext|>


<commit_before>#include <ctype.h>
#include <fstream>
#include <iostream>
#include <string.h>
#include <utils.h>
#include "lynxbot.h"
#include "RSNList.h"

RSNList::RSNList()
{
	if (!read_rsns()) {
		fprintf(stderr, "Could not read rsns.json\n");
		WAIT_INPUT();
	}
}

/* add: add a new value with given nick and rsn */
int RSNList::add(const char *nick, const char *rsn)
{
	Json::Value *t, user, prev(Json::arrayValue);

	if (!valid(rsn))
		return 0;
	if ((t = find_rsn(nick))) {
		strcpy(error, "you already have a RSN set");
		return 0;
	}
	user["nick"] = nick;
	user["rsn"] = rsn;
	user["prev"] = prev;
	rsns["rsns"].append(user);
	utils::write_json("rsns.json", rsns);
	return 1;
}

/* change the rsn associated with nick */
int RSNList::edit(const char *nick, const char *rsn)
{
	Json::Value *user;

	if (!valid(rsn))
		return 0;
	if (!(user = find_rsn(nick))) {
		strcpy(error, "you don't have a RSN set");
		return 0;
	}
	(*user)["prev"].append((*user)["rsn"].asString());
	(*user)["rsn"] = rsn;
	utils::write_json("rsns.json", rsns);
	return 1;
}

/* delete saved data for nick */
int RSNList::del(const char *nick)
{
	Json::ArrayIndex ind;
	Json::Value def, rem, val;

	ind = 0;
	while (ind < rsns["rsns"].size()) {
		val = rsns["rsns"].get(ind, def);
		if (strcmp(val["nick"].asCString(), nick) == 0) break;
		++ind;
	}

	if (ind == rsns["rsns"].size())
		return 0;

	rsns["rsns"].removeIndex(ind, &rem);
	utils::write_json("rsns.json", rsns);
	return 1;
}

/* get the rsn associated with a twitch nick */
const char *RSNList::rsn(const char *nick)
{
	Json::Value *user;

	if (!(user = find_rsn(nick)))
		return NULL;
	return (*user)["rsn"].asCString();
}

/* get the twitch nick associated with a rsn */
const char *RSNList::nick(const char *rsn)
{
	Json::Value *user;

	if (!(user = find_nick(rsn)))
		return NULL;
	return (*user)["nick"].asCString();
}

const char *RSNList::err()
{
	return error;
}

/* check if the given rsn is valid */
int RSNList::valid(const char *rsn)
{
	Json::Value *t;
	const char *s;

	for (s = rsn; *s; ++s) {
		if (!isalnum(*s) && *s != '_' && *s != '-') {
			snprintf(error, 256, "'%s' contains invalid "
					"characters", rsn);
			return 0;
		}
	}
	if (strcmp(rsn, "lynx_titan") == 0) {
		strcpy(error, "nice try");
		return 0;
	}
	if (strlen(rsn) > 12) {
		strcpy(error, "invalid RSN - too long");
		return 0;
	}
	if (!(t = find_nick(rsn))->empty()) {
		snprintf(error, 256, "the RSN '%s' is already taken by %s",
				rsn, (*t)["nick"].asCString());
		return 0;
	}
	return 1;
}

/* find the value with the given nick if it exists */
Json::Value *RSNList::find_rsn(const char *nick)
{
	for (auto &val : rsns["rsns"]) {
		if (strcmp(val["nick"].asCString(), nick) == 0)
			return &val;
	}
	return NULL;
}

/* find the value with the given rsn if it exists */
Json::Value *RSNList::find_nick(const char *rsn)
{
	for (auto &val : rsns["rsns"]) {
		if (strcmp(val["rsn"].asCString(), rsn) == 0)
			return &val;
	}
	return NULL;
}

/* read the rsns file into rsns */
int RSNList::read_rsns()
{
	if (!utils::read_json("rsns.json", rsns) || !rsns.isMember("rsns")
			|| !rsns["rsns"].isArray())
		return 0;
	for (auto &val : rsns["rsns"]) {
		if (!val.isMember("nick") && !val.isMember("curr")
			&& !val.isMember("prev")) {
			fprintf(stderr, "rsns.json is improperly configured\n");
			return 0;
		}
	}
	return 1;
}
<commit_msg>Fix taken RSN check<commit_after>#include <ctype.h>
#include <fstream>
#include <iostream>
#include <string.h>
#include <utils.h>
#include "lynxbot.h"
#include "RSNList.h"

RSNList::RSNList()
{
	if (!read_rsns()) {
		fprintf(stderr, "Could not read rsns.json\n");
		WAIT_INPUT();
	}
}

/* add: add a new value with given nick and rsn */
int RSNList::add(const char *nick, const char *rsn)
{
	Json::Value *t, user, prev(Json::arrayValue);

	if (!valid(rsn))
		return 0;
	if ((t = find_rsn(nick))) {
		strcpy(error, "you already have a RSN set");
		return 0;
	}
	user["nick"] = nick;
	user["rsn"] = rsn;
	user["prev"] = prev;
	rsns["rsns"].append(user);
	utils::write_json("rsns.json", rsns);
	return 1;
}

/* change the rsn associated with nick */
int RSNList::edit(const char *nick, const char *rsn)
{
	Json::Value *user;

	if (!valid(rsn))
		return 0;
	if (!(user = find_rsn(nick))) {
		strcpy(error, "you don't have a RSN set");
		return 0;
	}
	(*user)["prev"].append((*user)["rsn"].asString());
	(*user)["rsn"] = rsn;
	utils::write_json("rsns.json", rsns);
	return 1;
}

/* delete saved data for nick */
int RSNList::del(const char *nick)
{
	Json::ArrayIndex ind;
	Json::Value def, rem, val;

	ind = 0;
	while (ind < rsns["rsns"].size()) {
		val = rsns["rsns"].get(ind, def);
		if (strcmp(val["nick"].asCString(), nick) == 0) break;
		++ind;
	}

	if (ind == rsns["rsns"].size())
		return 0;

	rsns["rsns"].removeIndex(ind, &rem);
	utils::write_json("rsns.json", rsns);
	return 1;
}

/* get the rsn associated with a twitch nick */
const char *RSNList::rsn(const char *nick)
{
	Json::Value *user;

	if (!(user = find_rsn(nick)))
		return NULL;
	return (*user)["rsn"].asCString();
}

/* get the twitch nick associated with a rsn */
const char *RSNList::nick(const char *rsn)
{
	Json::Value *user;

	if (!(user = find_nick(rsn)))
		return NULL;
	return (*user)["nick"].asCString();
}

const char *RSNList::err()
{
	return error;
}

/* check if the given rsn is valid */
int RSNList::valid(const char *rsn)
{
	Json::Value *t;
	const char *s;

	for (s = rsn; *s; ++s) {
		if (!isalnum(*s) && *s != '_' && *s != '-') {
			snprintf(error, 256, "'%s' contains invalid "
					"characters", rsn);
			return 0;
		}
	}
	if (strcmp(rsn, "lynx_titan") == 0) {
		strcpy(error, "nice try");
		return 0;
	}
	if (strlen(rsn) > 12) {
		strcpy(error, "invalid RSN - too long");
		return 0;
	}
	if ((t = find_nick(rsn))) {
		snprintf(error, 256, "the RSN '%s' is already taken by %s",
				rsn, (*t)["nick"].asCString());
		return 0;
	}
	return 1;
}

/* find the value with the given nick if it exists */
Json::Value *RSNList::find_rsn(const char *nick)
{
	for (auto &val : rsns["rsns"]) {
		if (strcmp(val["nick"].asCString(), nick) == 0)
			return &val;
	}
	return NULL;
}

/* find the value with the given rsn if it exists */
Json::Value *RSNList::find_nick(const char *rsn)
{
	for (auto &val : rsns["rsns"]) {
		if (strcmp(val["rsn"].asCString(), rsn) == 0)
			return &val;
	}
	return NULL;
}

/* read the rsns file into rsns */
int RSNList::read_rsns()
{
	if (!utils::read_json("rsns.json", rsns) || !rsns.isMember("rsns")
			|| !rsns["rsns"].isArray())
		return 0;
	for (auto &val : rsns["rsns"]) {
		if (!val.isMember("nick") && !val.isMember("curr")
			&& !val.isMember("prev")) {
			fprintf(stderr, "rsns.json is improperly configured\n");
			return 0;
		}
	}
	return 1;
}
<|endoftext|>


<commit_before>#ifndef SAPLIST_HPP
#define SAPLIST_HPP 1

#include <functional>
#include <map>
#include <typeinfo>
#include <climits>
#include "CollisionManager.hpp"

class Collisionable {
public:
    virtual int getXMin() = 0;
    virtual int getYMin() = 0;
    virtual int getXMax() = 0;
    virtual int getYMax() = 0;
    virtual ~Collisionable() {};
};

class SAPList : public CollisionManager<Collisionable> {

    class EndPoint;

    class AABB {
    public:
        /** min/max
         *  - first is x axis
         *  - second is y axis */
        EndPoint * min[2];
        EndPoint * max[2];

        size_t typeId; /* Need to use std::type_info::hash_code() */
        void * owner;

        AABB (int * minX, int minY, int maxX, int maxY, size_t t, void * o) :
            typeId(t), owner(o) {
            min[0] = minX;
            min[1] = minY;
            max[0] = maxX;
            max[1] = maxY;
        }

    };

    /**
     * TODO:
     * - Optimize merging isMin boolean into another member
     *   (as a flag)
     * - Using doubly-linked list could waste memory but is easier to implement
     *   than arrays.
     * - Implement pair manager
     */
    class EndPoint {
    public:
        AABB * owner;
        int value;
        bool isMin;

        EndPoint * prev;
        EndPoint * next;

        EndPoint (AABB* o,int v,bool m,EndPoint* p,EndPoint* n) :
            owner(o), value(v), isMin(m), prev(p), next(n) {}

        /** When and EndPoint is destroyed, it updates prev and next */
        ~EndPoint () {
            if (this->prev != NULL) {
                this->prev->next = this->next;
            }
            if (this->next != NULL)
                this->next->prev = this->prev;
        }
    };

    /**
     * Action manager stores actions to perform on collision or separation
     * of two objects depending on their type
     * It also stores default actions to execute if no specific action is
     * defined for two types.
     */
    class ActionManager {
    public:
        /**
         * action table stores 2 actions per types couple:
         * - first is onCollision
         * - second is onSeparation
         */
        std::map < std::pair < size_t,size_t >,
                   std::pair < std::function < void (void *, void *) >,
                               std::function < void (void *, void *) > > >
        actions;

        /**
         * @param t1 type id of first object
         * @param t2 type id of second object
         * @return function to call on t1/t2 collision
         */
        std::function < void (void *, void *) >
        onCollision(size_t t1, size_t t2) {
            return this
                ->actions[std::pair<size_t, size_t>(t1,t2)].first;
        }

        /**
         * @param t1 type id of first object
         * @param t2 type id of second object
         * @return function to call on t1/t2 separation
         */
        std::function < void (void *, void *) >
        onSeparation(size_t t1, size_t t2) {
            return this
                ->actions[std::pair<size_t, size_t>(t1,t2)].second;
        }
    };

private:

    EndPoint * xAxis;
    EndPoint * yAxis;
    ActionManager actions;

    /** Swap two EndPoint * */
    void swap(EndPoint * p1, EndPoint * p2) {
        p2->next->prev = p1;
        p1->next = p2->next;
        p1->prev->next = p2;
        p1->prev = p2;
        p2->next = p1;
    }

    /** A collision between two AABB on one axis */
    inline bool partialCollisionCheck(const AABB & b1,
                                      const AABB & b2,
                                      int dim) {
        return (b1.max[dim] <= b2.max[dim] && b1.max[dim] >= b2.min[dim])
            || (b1.min[dim] >= b2.min[dim] && b1.max[dim] <= b2.max[dim]);
    }

    /**
     * Check if two AABB collide using 2 axises
     * @see partialCollisionCheck
     */
    bool collisionCheck(const AABB & b1, const AABB & b2) {
        return partialCollisionCheck (b1, b2, 0)
            && partialCollisionCheck (b1, b2, 1);
    }

    /** Create the AABB corresponding to a collisionable object
     * @param c the object used to create the corresponding AABB
     * @return a pointer to freshly heap-allocated AABB
     */
    AABB * mk_AABB(const Collisionable & c) {
        EndPoint * miX, * miY, * maX, * maY;

        /* TODO: create EndPoints */

        return new AABB(miX, miY, maX, maY, typeid(c).hash_code, (void *) c);
    }

    /** Update EndPoint place and call the appropriate function in case
     * of collision/separation
     * @param pt the EndPoint to update
     */
    void updateEndPoint(EndPoint * pt) {

         auto aux =
            [&pt, this]
            (std::function<EndPoint*(EndPoint*)>succ,
             std::function<bool(int,int)>loop_cond,
             std::function<bool(EndPoint*,EndPoint*)>mustAdd,
             std::function<bool(EndPoint*,EndPoint*)>mustRm) {

            EndPoint * tmp = succ(pt);

            while (loop_cond(tmp->value, pt->value)) {
                this->swap(tmp, pt);
                if (mustAdd(pt, tmp)) {
                    if (this->collisionCheck(*(pt->owner), *(tmp->owner))) {
                    this->actions.onCollision
                        (pt->owner->typeId, tmp->owner->typeId)
                        (pt->owner->owner, tmp->owner->owner);
                    }
                } else if (mustRm(pt, tmp)) {
                    this->actions.onSeparation
                        (pt->owner->typeId,tmp->owner->typeId)
                        (pt->owner->owner, tmp->owner->owner);
                }
            }
        };

        /** TODO: use aux to update on x and y axis */

    }

public:

    SAPList () {
        /* not sure about the true/false values */
        xAxis = new EndPoint(NULL, INT_MIN, true, NULL, NULL);
        xAxis->next = new EndPoint(NULL, INT_MAX, false, xAxis, NULL);
        yAxis = new EndPoint(NULL, INT_MIN, true, NULL, NULL);
        yAxis->next = new EndPoint(NULL, INT_MAX, false, yAxis, NULL);
    }

    ~SAPList () {

        while (xAxis->next != NULL) {
            delete xAxis->next;
        } delete xAxis;

        while (yAxis->next != NULL) {
            delete yAxis->next;
        } delete yAxis;
    }

    void addObject(const Collisionable &) {}
    void updateObject(const Collisionable &) {}
    void removeObject(const Collisionable &) {}
};

#endif
<commit_msg>Fixed type errors.<commit_after>#ifndef SAPLIST_HPP
#define SAPLIST_HPP 1

#include <functional>
#include <map>
#include <typeinfo>
#include <climits>
#include "CollisionManager.hpp"

class Collisionable {
public:
    virtual int getXMin() = 0;
    virtual int getYMin() = 0;
    virtual int getXMax() = 0;
    virtual int getYMax() = 0;
    virtual ~Collisionable() {};
};

class SAPList : public CollisionManager<Collisionable> {

    class EndPoint;

    class AABB {
    public:
        /** min/max
         *  - first is x axis
         *  - second is y axis */
        EndPoint * min[2];
        EndPoint * max[2];

        size_t typeId; /* Need to use std::type_info::hash_code() */
        void * owner;

        AABB (int minX, int minY, int maxX, int maxY, size_t t, void * o) :
            typeId(t), owner(o) {
            min[0] = new EndPoint(this, minX, true);
            min[1] = new EndPoint(this, minY, true);
            max[0] = new EndPoint(this, maxX, false);
            max[1] = new EndPoint(this, maxY, false);
        }

    };

    /**
     * TODO:
     * - Optimize merging isMin boolean into another member
     *   (as a flag)
     * - Using doubly-linked list could waste memory but is easier to implement
     *   than arrays.
     * - Implement pair manager
     */
    class EndPoint {
    public:
        AABB * owner;
        int value; //FIXME: use a pointer?
        bool isMin;

        EndPoint * prev;
        EndPoint * next;

        EndPoint (AABB* o,int v,bool m,EndPoint* p=NULL,EndPoint* n=NULL) :
            owner(o), value(v), isMin(m), prev(p), next(n) {}

        /** When and EndPoint is destroyed, it updates prev and next */
        ~EndPoint () {
            if (this->prev != NULL) {
                this->prev->next = this->next;
            }
            if (this->next != NULL)
                this->next->prev = this->prev;
        }
    };

    /**
     * Action manager stores actions to perform on collision or separation
     * of two objects depending on their type
     * It also stores default actions to execute if no specific action is
     * defined for two types.
     */
    class ActionManager {
    public:
        /**
         * action table stores 2 actions per types couple:
         * - first is onCollision
         * - second is onSeparation
         */
        std::map < std::pair < size_t,size_t >,
                   std::pair < std::function < void (void *, void *) >,
                               std::function < void (void *, void *) > > >
        actions;

        /**
         * @param t1 type id of first object
         * @param t2 type id of second object
         * @return function to call on t1/t2 collision
         */
        std::function < void (void *, void *) >
        onCollision(size_t t1, size_t t2) {
            return this
                ->actions[std::pair<size_t, size_t>(t1,t2)].first;
        }

        /**
         * @param t1 type id of first object
         * @param t2 type id of second object
         * @return function to call on t1/t2 separation
         */
        std::function < void (void *, void *) >
        onSeparation(size_t t1, size_t t2) {
            return this
                ->actions[std::pair<size_t, size_t>(t1,t2)].second;
        }
    };

private:

    EndPoint * xAxis;
    EndPoint * yAxis;
    ActionManager actions;

    /** Swap two EndPoint * */
    void swap(EndPoint * p1, EndPoint * p2) {
        p2->next->prev = p1;
        p1->next = p2->next;
        p1->prev->next = p2;
        p1->prev = p2;
        p2->next = p1;
    }

    /** A collision between two AABB on one axis */
    inline bool partialCollisionCheck(const AABB & b1,
                                      const AABB & b2,
                                      int dim) {
        return (b1.max[dim] <= b2.max[dim] && b1.max[dim] >= b2.min[dim])
            || (b1.min[dim] >= b2.min[dim] && b1.max[dim] <= b2.max[dim]);
    }

    /**
     * Check if two AABB collide using 2 axises
     * @see partialCollisionCheck
     */
    bool collisionCheck(const AABB & b1, const AABB & b2) {
        return partialCollisionCheck (b1, b2, 0)
            && partialCollisionCheck (b1, b2, 1);
    }

    /** Create the AABB corresponding to a collisionable object
     * @param c the object used to create the corresponding AABB
     * @return a pointer to freshly heap-allocated AABB
     */
    AABB * mk_AABB(Collisionable * c) {
        return new AABB(c->getXMin(), c->getYMin(),
                        c->getXMax(), c->getYMax(),
                        typeid(c).hash_code(), (void *) c);
    }

    /** Update EndPoint place and call the appropriate function in case
     * of collision/separation
     * @param pt the EndPoint to update
     */
    void updateEndPoint(EndPoint * pt) {

         auto aux =
            [&pt, this]
            (std::function<EndPoint*(EndPoint*)>succ,
             std::function<bool(int,int)>loop_cond,
             std::function<bool(EndPoint*,EndPoint*)>mustAdd,
             std::function<bool(EndPoint*,EndPoint*)>mustRm) {

            EndPoint * tmp = succ(pt);

            while (loop_cond(tmp->value, pt->value)) {
                this->swap(tmp, pt);
                if (mustAdd(pt, tmp)) {
                    if (this->collisionCheck(*(pt->owner), *(tmp->owner))) {
                    this->actions.onCollision
                        (pt->owner->typeId, tmp->owner->typeId)
                        (pt->owner->owner, tmp->owner->owner);
                    }
                } else if (mustRm(pt, tmp)) {
                    this->actions.onSeparation
                        (pt->owner->typeId,tmp->owner->typeId)
                        (pt->owner->owner, tmp->owner->owner);
                }
            }
        };

        /** TODO: use aux to update on x and y axis */

    }

public:

    SAPList () {
        /* not sure about the true/false values */
        xAxis = new EndPoint(NULL, INT_MIN, true, NULL, NULL);
        xAxis->next = new EndPoint(NULL, INT_MAX, false, xAxis, NULL);
        yAxis = new EndPoint(NULL, INT_MIN, true, NULL, NULL);
        yAxis->next = new EndPoint(NULL, INT_MAX, false, yAxis, NULL);
    }

    ~SAPList () {

        while (xAxis->next != NULL) {
            delete xAxis->next;
        } delete xAxis;

        while (yAxis->next != NULL) {
            delete yAxis->next;
        } delete yAxis;
    }

    void addObject(const Collisionable &) {}
    void updateObject(const Collisionable &) {}
    void removeObject(const Collisionable &) {}
};

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <list>

#include <nix.hpp>

using namespace std;
using namespace nix;

Section::Section()
    : NamedEntity()
{
}

Section::Section(nullptr_t ptr)
    : NamedEntity()
{
}

Section::Section(const Section &other)
    : NamedEntity(other.impl_ptr)
{
}

Section::Section(const shared_ptr<base::ISection> &p_impl)
    : NamedEntity(p_impl)
{
}

//-----------------------------------------------------
// Methods concerning child sections
//-----------------------------------------------------

/*
 * Helper struct for {@link findSections}.
 */
struct SectionCont {
    SectionCont(Section s, size_t d = 0)
    : entity(s), depth(d)
    {}

    Section entity;
    size_t depth;
};

std::vector<Section> Section::findSections(std::function<bool(Section)> filter,
                                  size_t max_depth) const
{
    std::vector<Section>  results;
    std::list<SectionCont> todo;

    todo.push_back(SectionCont(*this));

    while(todo.size() > 0)
    {
        SectionCont current = todo.front();
        todo.pop_front();

        bool filter_ok = filter(current.entity);
        if (filter_ok) {
            results.push_back(current.entity);
        }

        if (current.depth < max_depth) {
            std::vector<Section> children = current.entity.children();
            size_t next_depth = current.depth + 1;

            for (auto it = children.begin(); it != children.end(); ++it) {
                todo.push_back(SectionCont(*it, next_depth));
            }
        }
    }

    return results;
}

//-----------------------------------------------------
// Methods for property access
//-----------------------------------------------------

vector<Property> Section::inheritedProperties() const {

    vector<Property> own = properties();

    if (link() == nullptr)
        return own;

    vector<Property> linked = link().properties();

    for (auto it_linked = linked.begin(); it_linked != linked.end(); ++it_linked) {

        bool not_own = true;
        for (auto it_own = own.begin(); it_own != own.end(); ++it_own) {
            if (it_linked->name() == it_own->name()) {
                not_own = false;
                break;
            }
        }

        if (not_own) {
            own.push_back(*it_linked);
        }

    }

    return own;
}

//------------------------------------------------------
// Operators and other functions
//------------------------------------------------------

std::ostream& nix::operator<<(ostream &out, const Section &ent) {
    out << "Section: {name = " << ent.name();
    out << ", type = " << ent.type();
    out << ", id = " << ent.id() << "}";
    return out;
}
<commit_msg>quick fix "children() = sections()"<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <list>

#include <nix.hpp>

using namespace std;
using namespace nix;

Section::Section()
    : NamedEntity()
{
}

Section::Section(nullptr_t ptr)
    : NamedEntity()
{
}

Section::Section(const Section &other)
    : NamedEntity(other.impl_ptr)
{
}

Section::Section(const shared_ptr<base::ISection> &p_impl)
    : NamedEntity(p_impl)
{
}

//-----------------------------------------------------
// Methods concerning child sections
//-----------------------------------------------------

/*
 * Helper struct for {@link findSections}.
 */
struct SectionCont {
    SectionCont(Section s, size_t d = 0)
    : entity(s), depth(d)
    {}

    Section entity;
    size_t depth;
};

std::vector<Section> Section::findSections(std::function<bool(Section)> filter,
                                  size_t max_depth) const
{
    std::vector<Section>  results;
    std::list<SectionCont> todo;

    todo.push_back(SectionCont(*this));

    while(todo.size() > 0)
    {
        SectionCont current = todo.front();
        todo.pop_front();

        bool filter_ok = filter(current.entity);
        if (filter_ok) {
            results.push_back(current.entity);
        }

        if (current.depth < max_depth) {
            std::vector<Section> children = current.entity.sections();
            size_t next_depth = current.depth + 1;

            for (auto it = children.begin(); it != children.end(); ++it) {
                todo.push_back(SectionCont(*it, next_depth));
            }
        }
    }

    return results;
}

//-----------------------------------------------------
// Methods for property access
//-----------------------------------------------------

vector<Property> Section::inheritedProperties() const {

    vector<Property> own = properties();

    if (link() == nullptr)
        return own;

    vector<Property> linked = link().properties();

    for (auto it_linked = linked.begin(); it_linked != linked.end(); ++it_linked) {

        bool not_own = true;
        for (auto it_own = own.begin(); it_own != own.end(); ++it_own) {
            if (it_linked->name() == it_own->name()) {
                not_own = false;
                break;
            }
        }

        if (not_own) {
            own.push_back(*it_linked);
        }

    }

    return own;
}

//------------------------------------------------------
// Operators and other functions
//------------------------------------------------------

std::ostream& nix::operator<<(ostream &out, const Section &ent) {
    out << "Section: {name = " << ent.name();
    out << ", type = " << ent.type();
    out << ", id = " << ent.id() << "}";
    return out;
}
<|endoftext|>


<commit_before>#include "Session.h"

#include <string>
#include <iostream>

using namespace regexbench;

Session::Session(const char *pkt) : hashval(0), matcher_idx(0) {
  ether_type = ntohs(reinterpret_cast<const ether_header *>(pkt)->ether_type);
  uint16_t size_iphdr = 0;
  if (ether_type == ETHERTYPE_IPV6) {
    protocol =
        reinterpret_cast<const ip6_hdr *>(pkt + ETHER_HDR_LEN)->ip6_nxt;

    size_iphdr = 40;
    memcpy(&addr.ipv6.src, EXT_SIP6(pkt), 16);
    memcpy(&addr.ipv6.dst, EXT_DIP6(pkt), 16);

    auto oft = ETHER_HDR_LEN + offsetof(struct ip6_hdr, ip6_dst);
    for (size_t i = 0; i < 16; i+=4)
      hashval ^= *reinterpret_cast<const uint32_t *>(&pkt[oft+i]);

    oft = ETHER_HDR_LEN + offsetof(struct ip6_hdr, ip6_src);
    for (size_t i = 0; i < 16; i+=4)
      hashval ^= *reinterpret_cast<const uint32_t *>(&pkt[oft+i]);

    hashval ^= protocol;
  } else if (ether_type == ETHERTYPE_IP) {
    auto ih = reinterpret_cast<const ip *>(pkt + ETHER_HDR_LEN);
    protocol = ih->ip_p;
    size_iphdr = static_cast<uint16_t>(ih->ip_hl << 2);
    addr.ipv4.src.s_addr = EXT_SIP(pkt);
    addr.ipv4.dst.s_addr = EXT_DIP(pkt);

    hashval ^= addr.ipv4.src.s_addr;
    hashval ^= addr.ipv4.dst.s_addr;
    hashval ^= protocol;
  }

  if (protocol == IPPROTO_ICMP) {
    si.icmp_tp = EXT_ICMP_TP(pkt, size_iphdr);
    di.icmp_cd = EXT_ICMP_CD(pkt, size_iphdr);
    hashval ^= static_cast<uint32_t>(si.icmp_tp) << 16 | di.icmp_cd;
  } else {
    si.sport = EXT_SPORT(pkt, size_iphdr);
    di.dport = EXT_DPORT(pkt, size_iphdr);
    hashval ^= static_cast<uint32_t>(si.sport) << 16 | di.dport;
  }
  // std::cout << hashval << "\n";
}

bool Session::operator==(const Session &rhs) {
  if (ether_type != rhs.ether_type || protocol != rhs.protocol)
    return false;
  if (ether_type == ETHERTYPE_IP) {
    if (addr.ipv4.src.s_addr == rhs.addr.ipv4.src.s_addr &&
        addr.ipv4.dst.s_addr == rhs.addr.ipv4.dst.s_addr) {
      if (__builtin_expect(protocol == IPPROTO_ICMP, false)) {
        if (si.icmp_tp == rhs.si.icmp_tp &&
            di.icmp_cd == rhs.di.icmp_cd) {
          return true;
        }
      } else if (si.sport == rhs.si.sport && di.dport == rhs.di.dport) {
        return true;
      }
    }
    return false;
  }

  // IPv6
  if (cmp_in6_addr(&addr.ipv6.src, &rhs.addr.ipv6.src) &&
      cmp_in6_addr(&addr.ipv6.dst, &rhs.addr.ipv6.dst)) {
    if (__builtin_expect(protocol == IPPROTO_ICMP, false)) {
      if (si.icmp_tp == rhs.si.icmp_tp &&
          di.icmp_cd == rhs.di.icmp_cd) {
        return true;
      }
    } else if (si.sport == rhs.si.sport && di.dport == rhs.di.dport) {
      return true;
    }
  }
  return false;
}

bool SessionTable::find(Session &s, size_t &sid) {
  auto its = sessionTable.equal_range(s.getHashval());
  auto it = its.first;
  for (; it != its.second; ++it) {
    if (s == (*it).second) {
      sid = (*it).second.getSession();
      return true;
    }
  }
  if (it == its.second) {
    s.setSession(nsessions++);
    sessionTable.insert(std::make_pair(s.getHashval(), s));
    sid = s.getSession();
  }
  return false;
}

uint32_t SessionTable::nsessions = 0;
<commit_msg>Minor edits<commit_after>#include "Session.h"

#include <string>

using namespace regexbench;

Session::Session(const char *pkt) : hashval(0), matcher_idx(0) {
  ether_type = ntohs(reinterpret_cast<const ether_header *>(pkt)->ether_type);
  uint16_t size_iphdr = 0;
  if (ether_type == ETHERTYPE_IPV6) {
    protocol =
        reinterpret_cast<const ip6_hdr *>(pkt + ETHER_HDR_LEN)->ip6_nxt;

    size_iphdr = 40;
    memcpy(&addr.ipv6.src, EXT_SIP6(pkt), 16);
    memcpy(&addr.ipv6.dst, EXT_DIP6(pkt), 16);

    auto oft = ETHER_HDR_LEN + offsetof(struct ip6_hdr, ip6_dst);
    for (size_t i = 0; i < 16; i+=4)
      hashval ^= *reinterpret_cast<const uint32_t *>(&pkt[oft+i]);

    oft = ETHER_HDR_LEN + offsetof(struct ip6_hdr, ip6_src);
    for (size_t i = 0; i < 16; i+=4)
      hashval ^= *reinterpret_cast<const uint32_t *>(&pkt[oft+i]);

    hashval ^= protocol;
  } else if (ether_type == ETHERTYPE_IP) {
    auto ih = reinterpret_cast<const ip *>(pkt + ETHER_HDR_LEN);
    protocol = ih->ip_p;
    size_iphdr = static_cast<uint16_t>(ih->ip_hl << 2);
    addr.ipv4.src.s_addr = EXT_SIP(pkt);
    addr.ipv4.dst.s_addr = EXT_DIP(pkt);

    hashval ^= addr.ipv4.src.s_addr;
    hashval ^= addr.ipv4.dst.s_addr;
    hashval ^= protocol;
  }

  if (protocol == IPPROTO_ICMP) {
    si.icmp_tp = EXT_ICMP_TP(pkt, size_iphdr);
    di.icmp_cd = EXT_ICMP_CD(pkt, size_iphdr);
    hashval ^= static_cast<uint32_t>(si.icmp_tp) << 16 | di.icmp_cd;
  } else {
    si.sport = EXT_SPORT(pkt, size_iphdr);
    di.dport = EXT_DPORT(pkt, size_iphdr);
    hashval ^= static_cast<uint32_t>(si.sport) << 16 | di.dport;
  }
}

bool Session::operator==(const Session &rhs) {
  if (ether_type != rhs.ether_type || protocol != rhs.protocol)
    return false;
  if (ether_type == ETHERTYPE_IP) {
    if (addr.ipv4.src.s_addr == rhs.addr.ipv4.src.s_addr &&
        addr.ipv4.dst.s_addr == rhs.addr.ipv4.dst.s_addr) {
      if (__builtin_expect(protocol == IPPROTO_ICMP, false)) {
        if (si.icmp_tp == rhs.si.icmp_tp &&
            di.icmp_cd == rhs.di.icmp_cd) {
          return true;
        }
      } else if (si.sport == rhs.si.sport && di.dport == rhs.di.dport) {
        return true;
      }
    }
    return false;
  }

  // IPv6
  if (cmp_in6_addr(&addr.ipv6.src, &rhs.addr.ipv6.src) &&
      cmp_in6_addr(&addr.ipv6.dst, &rhs.addr.ipv6.dst)) {
    if (__builtin_expect(protocol == IPPROTO_ICMP, false)) {
      if (si.icmp_tp == rhs.si.icmp_tp &&
          di.icmp_cd == rhs.di.icmp_cd) {
        return true;
      }
    } else if (si.sport == rhs.si.sport && di.dport == rhs.di.dport) {
      return true;
    }
  }
  return false;
}

bool SessionTable::find(Session &s, size_t &sid) {
  auto its = sessionTable.equal_range(s.getHashval());
  auto it = its.first;
  for (; it != its.second; ++it) {
    if (s == it->second) {
      sid = it->second.getSession();
      return true;
    }
  }
  if (it == its.second) {
    s.setSession(nsessions++);
    sessionTable.insert(std::make_pair(s.getHashval(), s));
    sid = s.getSession();
  }
  return false;
}

uint32_t SessionTable::nsessions = 0;
<|endoftext|>


<commit_before>/*
** Copyright 2015 Robert Fratto. See the LICENSE.txt file at the top-level
** directory of this distribution.
**
** Licensed under the MIT license <http://opensource.org/licenses/MIT>. This file
** may not be copied, modified, or distributed except according to those terms.
*/

#include <Terminal.h>

Terminal::Terminal(std::string name)
: Component(name)
{
	// Do nothing.
}<commit_msg>Add Terminals to their own FIRST list.<commit_after>/*
** Copyright 2015 Robert Fratto. See the LICENSE.txt file at the top-level
** directory of this distribution.
**
** Licensed under the MIT license <http://opensource.org/licenses/MIT>. This file
** may not be copied, modified, or distributed except according to those terms.
*/

#include <Terminal.h>

Terminal::Terminal(std::string name)
: Component(name)
{
	// Add self to first.
	addToFirst(this);
}<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file Selection.cxx
 ** Classes maintaining the selection.
 **/
// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>

#include <vector>

#include "Platform.h"

#include "Scintilla.h"

#include "Selection.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
	if (position == startChange) {
		virtualSpace = 0;
	}
	if (insertion) {
		if (position > startChange) {
			position += length;
		}
	} else {
		if (position > startChange) {
			int endDeletion = startChange + length;
			if (position > endDeletion) {
				position -= length;
			} else {
				position = startChange;
				virtualSpace = 0;
			}
		}
	}
}

bool SelectionPosition::operator <(const SelectionPosition &other) const {
	if (position == other.position)
		return virtualSpace < other.virtualSpace;
	else
		return position < other.position;
}

bool SelectionPosition::operator >(const SelectionPosition &other) const {
	if (position == other.position)
		return virtualSpace > other.virtualSpace;
	else
		return position > other.position;
}

bool SelectionPosition::operator <=(const SelectionPosition &other) const {
	if (position == other.position && virtualSpace == other.virtualSpace)
		return true;
	else
		return other > *this;
}

bool SelectionPosition::operator >=(const SelectionPosition &other) const {
	if (position == other.position && virtualSpace == other.virtualSpace)
		return true;
	else
		return *this > other;
}

int SelectionRange::Length() const {
	if (anchor > caret) {
		return anchor.Position() - caret.Position();
	} else {
		return caret.Position() - anchor.Position();
	}
}

bool SelectionRange::Contains(int pos) const {
	if (anchor > caret)
		return (pos >= caret.Position()) && (pos <= anchor.Position());
	else
		return (pos >= anchor.Position()) && (pos <= caret.Position());
}

bool SelectionRange::Contains(SelectionPosition sp) const {
	if (anchor > caret)
		return (sp >= caret) && (sp <= anchor);
	else
		return (sp >= anchor) && (sp <= caret);
}

bool SelectionRange::ContainsCharacter(int posCharacter) const {
	if (anchor > caret)
		return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position());
	else
		return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
}

SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
	SelectionSegment inOrder(caret, anchor);
	if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
		SelectionSegment portion = check;
		if (portion.start < inOrder.start)
			portion.start = inOrder.start;
		if (portion.end > inOrder.end)
			portion.end = inOrder.end;
		if (portion.start > portion.end)
			return SelectionSegment();
		else
			return portion;
	} else {
		return SelectionSegment();
	}
}

bool SelectionRange::Trim(SelectionRange range) {
	SelectionPosition startRange = range.Start();
	SelectionPosition endRange = range.End();
	SelectionPosition start = Start();
	SelectionPosition end = End();
	PLATFORM_ASSERT(start <= end);
	PLATFORM_ASSERT(startRange <= endRange);
	if ((startRange <= end) && (endRange >= start)) {
		if ((start > startRange) && (end < endRange)) {
			// Completely covered by range -> empty at start
			end = start;
		} else if ((start < startRange) && (end > endRange)) {
			// Completely covers range -> empty at start
			end = start;
		} else if (start <= startRange) {
			// Trim end
			end = startRange;
		} else { //
			PLATFORM_ASSERT(end >= endRange);
			// Trim start
			start = endRange;
		}
		if (anchor > caret) {
			caret = start;
			anchor = end;
		} else {
			anchor = start;
			caret = end;
		}
		return Empty();
	} else {
		return false;
	}
}

// If range is all virtual collapse to start of virtual space
void SelectionRange::MinimizeVirtualSpace() {
	if (caret.Position() == anchor.Position()) {
		int virtualSpace = caret.VirtualSpace();
		if (virtualSpace > anchor.VirtualSpace())
			virtualSpace = anchor.VirtualSpace();
		caret.SetVirtualSpace(virtualSpace);
		anchor.SetVirtualSpace(virtualSpace);
	}
}

Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
	AddSelection(SelectionPosition(0));
}

Selection::~Selection() {
}

bool Selection::IsRectangular() const {
	return (selType == selRectangle) || (selType == selThin);
}

int Selection::MainCaret() const {
	return ranges[mainRange].caret.Position();
}

int Selection::MainAnchor() const {
	return ranges[mainRange].anchor.Position();
}

SelectionRange &Selection::Rectangular() {
	return rangeRectangular;
}

SelectionSegment Selection::Limits() const {
	if (ranges.empty()) {
		return SelectionSegment();
	} else {
		SelectionSegment sr(ranges[0].anchor, ranges[0].caret);
		for (size_t i=1; i<ranges.size(); i++) {
			sr.Extend(ranges[i].anchor);
			sr.Extend(ranges[i].caret);
		}
		return sr;
	}
}

SelectionSegment Selection::LimitsForRectangularElseMain() const {
	if (IsRectangular()) {
		return Limits();
	} else {
		return SelectionSegment(ranges[mainRange].caret, ranges[mainRange].anchor);
	}
}

size_t Selection::Count() const {
	return ranges.size();
}

size_t Selection::Main() const {
	return mainRange;
}

void Selection::SetMain(size_t r) {
	PLATFORM_ASSERT(r < ranges.size());
	mainRange = r;
}

SelectionRange &Selection::Range(size_t r) {
	return ranges[r];
}

SelectionRange &Selection::RangeMain() {
	return ranges[mainRange];
}

bool Selection::MoveExtends() const {
	return moveExtends;
}

void Selection::SetMoveExtends(bool moveExtends_) {
	moveExtends = moveExtends_;
}

bool Selection::Empty() const {
	for (size_t i=0; i<ranges.size(); i++) {
		if (!ranges[i].Empty())
			return false;
	}
	return true;
}

SelectionPosition Selection::Last() const {
	SelectionPosition lastPosition;
	for (size_t i=0; i<ranges.size(); i++) {
		if (lastPosition < ranges[i].caret)
			lastPosition = ranges[i].caret;
		if (lastPosition < ranges[i].anchor)
			lastPosition = ranges[i].anchor;
	}
	return lastPosition;
}

int Selection::Length() const {
	int len = 0;
	for (size_t i=0; i<ranges.size(); i++) {
		len += ranges[i].Length();
	}
	return len;
}

void Selection::MovePositions(bool insertion, int startChange, int length) {
	for (size_t i=0; i<ranges.size(); i++) {
		ranges[i].caret.MoveForInsertDelete(insertion, startChange, length);
		ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length);
	}
}

void Selection::TrimSelection(SelectionRange range) {
	for (size_t i=0; i<ranges.size();) {
		if ((i != mainRange) && (ranges[i].Trim(range))) {
			// Trimmed to empty so remove
			for (size_t j=i; j<ranges.size()-1; j++) {
				ranges[j] = ranges[j+1];
				if (j == mainRange-1)
					mainRange--;
			}
			ranges.pop_back();
		} else {
			i++;
		}
	}
}

void Selection::SetSelection(SelectionRange range) {
	ranges.clear();
	ranges.push_back(range);
	mainRange = ranges.size() - 1;
}

void Selection::AddSelection(SelectionRange range) {
	TrimSelection(range);
	ranges.push_back(range);
	mainRange = ranges.size() - 1;
}

void Selection::AddSelectionWithoutTrim(SelectionRange range) {
	ranges.push_back(range);
	mainRange = ranges.size() - 1;
}

void Selection::TentativeSelection(SelectionRange range) {
	if (!tentativeMain) {
		rangesSaved = ranges;
	}
	ranges = rangesSaved;
	AddSelection(range);
	TrimSelection(ranges[mainRange]);
	tentativeMain = true;
}

void Selection::CommitTentative() {
	rangesSaved.clear();
	tentativeMain = false;
}

int Selection::CharacterInSelection(int posCharacter) const {
	for (size_t i=0; i<ranges.size(); i++) {
		if (ranges[i].ContainsCharacter(posCharacter))
			return i == mainRange ? 1 : 2;
	}
	return 0;
}

int Selection::InSelectionForEOL(int pos) const {
	for (size_t i=0; i<ranges.size(); i++) {
		if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position()))
			return i == mainRange ? 1 : 2;
	}
	return 0;
}

int Selection::VirtualSpaceFor(int pos) const {
	int virtualSpace = 0;
	for (size_t i=0; i<ranges.size(); i++) {
		if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace()))
			virtualSpace = ranges[i].caret.VirtualSpace();
		if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace()))
			virtualSpace = ranges[i].anchor.VirtualSpace();
	}
	return virtualSpace;
}

void Selection::Clear() {
	ranges.clear();
	ranges.push_back(SelectionRange());
	mainRange = ranges.size() - 1;
	selType = selStream;
	moveExtends = false;
	ranges[mainRange].Reset();
	rangeRectangular.Reset();
}

void Selection::RemoveDuplicates() {
	for (size_t i=0; i<ranges.size()-1; i++) {
		if (ranges[i].Empty()) {
			size_t j=i+1;
			while (j<ranges.size()) {
				if (ranges[i] == ranges[j]) {
					ranges.erase(ranges.begin() + j);
					if (mainRange >= j)
						mainRange--;
				} else {
					j++;
				}
			}
		}
	}
}

void Selection::RotateMain() {
	mainRange = (mainRange + 1) % ranges.size();
}

<commit_msg>Move selections with virtual space more reasonably when real spaces inserted at their location by converting virtual space to real position changes up to the amount of virtual space. This allows multi-typing to work when two carets are located in virtual space on one line.<commit_after>// Scintilla source code edit control
/** @file Selection.cxx
 ** Classes maintaining the selection.
 **/
// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>

#include <vector>

#include "Platform.h"

#include "Scintilla.h"

#include "Selection.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
	if (insertion) {
		if (position == startChange) {
			int virtualLengthRemove = std::min(length, virtualSpace);
			virtualSpace -= virtualLengthRemove;
			position += virtualLengthRemove;
		} else if (position > startChange) {
			position += length;
		}
	} else {
		if (position == startChange) {
			virtualSpace = 0;
		}
		if (position > startChange) {
			int endDeletion = startChange + length;
			if (position > endDeletion) {
				position -= length;
			} else {
				position = startChange;
				virtualSpace = 0;
			}
		}
	}
}

bool SelectionPosition::operator <(const SelectionPosition &other) const {
	if (position == other.position)
		return virtualSpace < other.virtualSpace;
	else
		return position < other.position;
}

bool SelectionPosition::operator >(const SelectionPosition &other) const {
	if (position == other.position)
		return virtualSpace > other.virtualSpace;
	else
		return position > other.position;
}

bool SelectionPosition::operator <=(const SelectionPosition &other) const {
	if (position == other.position && virtualSpace == other.virtualSpace)
		return true;
	else
		return other > *this;
}

bool SelectionPosition::operator >=(const SelectionPosition &other) const {
	if (position == other.position && virtualSpace == other.virtualSpace)
		return true;
	else
		return *this > other;
}

int SelectionRange::Length() const {
	if (anchor > caret) {
		return anchor.Position() - caret.Position();
	} else {
		return caret.Position() - anchor.Position();
	}
}

bool SelectionRange::Contains(int pos) const {
	if (anchor > caret)
		return (pos >= caret.Position()) && (pos <= anchor.Position());
	else
		return (pos >= anchor.Position()) && (pos <= caret.Position());
}

bool SelectionRange::Contains(SelectionPosition sp) const {
	if (anchor > caret)
		return (sp >= caret) && (sp <= anchor);
	else
		return (sp >= anchor) && (sp <= caret);
}

bool SelectionRange::ContainsCharacter(int posCharacter) const {
	if (anchor > caret)
		return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position());
	else
		return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
}

SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
	SelectionSegment inOrder(caret, anchor);
	if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
		SelectionSegment portion = check;
		if (portion.start < inOrder.start)
			portion.start = inOrder.start;
		if (portion.end > inOrder.end)
			portion.end = inOrder.end;
		if (portion.start > portion.end)
			return SelectionSegment();
		else
			return portion;
	} else {
		return SelectionSegment();
	}
}

bool SelectionRange::Trim(SelectionRange range) {
	SelectionPosition startRange = range.Start();
	SelectionPosition endRange = range.End();
	SelectionPosition start = Start();
	SelectionPosition end = End();
	PLATFORM_ASSERT(start <= end);
	PLATFORM_ASSERT(startRange <= endRange);
	if ((startRange <= end) && (endRange >= start)) {
		if ((start > startRange) && (end < endRange)) {
			// Completely covered by range -> empty at start
			end = start;
		} else if ((start < startRange) && (end > endRange)) {
			// Completely covers range -> empty at start
			end = start;
		} else if (start <= startRange) {
			// Trim end
			end = startRange;
		} else { //
			PLATFORM_ASSERT(end >= endRange);
			// Trim start
			start = endRange;
		}
		if (anchor > caret) {
			caret = start;
			anchor = end;
		} else {
			anchor = start;
			caret = end;
		}
		return Empty();
	} else {
		return false;
	}
}

// If range is all virtual collapse to start of virtual space
void SelectionRange::MinimizeVirtualSpace() {
	if (caret.Position() == anchor.Position()) {
		int virtualSpace = caret.VirtualSpace();
		if (virtualSpace > anchor.VirtualSpace())
			virtualSpace = anchor.VirtualSpace();
		caret.SetVirtualSpace(virtualSpace);
		anchor.SetVirtualSpace(virtualSpace);
	}
}

Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
	AddSelection(SelectionPosition(0));
}

Selection::~Selection() {
}

bool Selection::IsRectangular() const {
	return (selType == selRectangle) || (selType == selThin);
}

int Selection::MainCaret() const {
	return ranges[mainRange].caret.Position();
}

int Selection::MainAnchor() const {
	return ranges[mainRange].anchor.Position();
}

SelectionRange &Selection::Rectangular() {
	return rangeRectangular;
}

SelectionSegment Selection::Limits() const {
	if (ranges.empty()) {
		return SelectionSegment();
	} else {
		SelectionSegment sr(ranges[0].anchor, ranges[0].caret);
		for (size_t i=1; i<ranges.size(); i++) {
			sr.Extend(ranges[i].anchor);
			sr.Extend(ranges[i].caret);
		}
		return sr;
	}
}

SelectionSegment Selection::LimitsForRectangularElseMain() const {
	if (IsRectangular()) {
		return Limits();
	} else {
		return SelectionSegment(ranges[mainRange].caret, ranges[mainRange].anchor);
	}
}

size_t Selection::Count() const {
	return ranges.size();
}

size_t Selection::Main() const {
	return mainRange;
}

void Selection::SetMain(size_t r) {
	PLATFORM_ASSERT(r < ranges.size());
	mainRange = r;
}

SelectionRange &Selection::Range(size_t r) {
	return ranges[r];
}

SelectionRange &Selection::RangeMain() {
	return ranges[mainRange];
}

bool Selection::MoveExtends() const {
	return moveExtends;
}

void Selection::SetMoveExtends(bool moveExtends_) {
	moveExtends = moveExtends_;
}

bool Selection::Empty() const {
	for (size_t i=0; i<ranges.size(); i++) {
		if (!ranges[i].Empty())
			return false;
	}
	return true;
}

SelectionPosition Selection::Last() const {
	SelectionPosition lastPosition;
	for (size_t i=0; i<ranges.size(); i++) {
		if (lastPosition < ranges[i].caret)
			lastPosition = ranges[i].caret;
		if (lastPosition < ranges[i].anchor)
			lastPosition = ranges[i].anchor;
	}
	return lastPosition;
}

int Selection::Length() const {
	int len = 0;
	for (size_t i=0; i<ranges.size(); i++) {
		len += ranges[i].Length();
	}
	return len;
}

void Selection::MovePositions(bool insertion, int startChange, int length) {
	for (size_t i=0; i<ranges.size(); i++) {
		ranges[i].caret.MoveForInsertDelete(insertion, startChange, length);
		ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length);
	}
}

void Selection::TrimSelection(SelectionRange range) {
	for (size_t i=0; i<ranges.size();) {
		if ((i != mainRange) && (ranges[i].Trim(range))) {
			// Trimmed to empty so remove
			for (size_t j=i; j<ranges.size()-1; j++) {
				ranges[j] = ranges[j+1];
				if (j == mainRange-1)
					mainRange--;
			}
			ranges.pop_back();
		} else {
			i++;
		}
	}
}

void Selection::SetSelection(SelectionRange range) {
	ranges.clear();
	ranges.push_back(range);
	mainRange = ranges.size() - 1;
}

void Selection::AddSelection(SelectionRange range) {
	TrimSelection(range);
	ranges.push_back(range);
	mainRange = ranges.size() - 1;
}

void Selection::AddSelectionWithoutTrim(SelectionRange range) {
	ranges.push_back(range);
	mainRange = ranges.size() - 1;
}

void Selection::TentativeSelection(SelectionRange range) {
	if (!tentativeMain) {
		rangesSaved = ranges;
	}
	ranges = rangesSaved;
	AddSelection(range);
	TrimSelection(ranges[mainRange]);
	tentativeMain = true;
}

void Selection::CommitTentative() {
	rangesSaved.clear();
	tentativeMain = false;
}

int Selection::CharacterInSelection(int posCharacter) const {
	for (size_t i=0; i<ranges.size(); i++) {
		if (ranges[i].ContainsCharacter(posCharacter))
			return i == mainRange ? 1 : 2;
	}
	return 0;
}

int Selection::InSelectionForEOL(int pos) const {
	for (size_t i=0; i<ranges.size(); i++) {
		if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position()))
			return i == mainRange ? 1 : 2;
	}
	return 0;
}

int Selection::VirtualSpaceFor(int pos) const {
	int virtualSpace = 0;
	for (size_t i=0; i<ranges.size(); i++) {
		if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace()))
			virtualSpace = ranges[i].caret.VirtualSpace();
		if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace()))
			virtualSpace = ranges[i].anchor.VirtualSpace();
	}
	return virtualSpace;
}

void Selection::Clear() {
	ranges.clear();
	ranges.push_back(SelectionRange());
	mainRange = ranges.size() - 1;
	selType = selStream;
	moveExtends = false;
	ranges[mainRange].Reset();
	rangeRectangular.Reset();
}

void Selection::RemoveDuplicates() {
	for (size_t i=0; i<ranges.size()-1; i++) {
		if (ranges[i].Empty()) {
			size_t j=i+1;
			while (j<ranges.size()) {
				if (ranges[i] == ranges[j]) {
					ranges.erase(ranges.begin() + j);
					if (mainRange >= j)
						mainRange--;
				} else {
					j++;
				}
			}
		}
	}
}

void Selection::RotateMain() {
	mainRange = (mainRange + 1) % ranges.size();
}

<|endoftext|>