<commit_before>#include "problem_definition.h"

#include <sstream>
#include <utility>
#include <iomanip>

#include <deal.II/base/utilities.h>

dealii::ParameterHandler bparams::GlobPrm;

namespace bparams {
void DeclareParameters (dealii::ParameterHandler &local_prm) {
  // our final strategy is to declare all possible entries
  // and then ignore some of them suggested by Wolfgang Bangerth
  // from Colorado State on 05-10-2017
  // The following are the basic parameters we need to define a problem
  {
    local_prm.declare_entry ("problem dimension", "2",
        dealii::Patterns::Integer(), "");
    local_prm.declare_entry ("transport model", "none",
        dealii::Patterns::Selection("ep|none"),
        "valid names such as ep");
    local_prm.declare_entry ("ho linear solver name", "cg",
        dealii::Patterns::Selection("cg|gmres|bicgstab|direct"),
        "solers");
    local_prm.declare_entry ("ho preconditioner name", "amg",
        dealii::Patterns::Selection("amg|parasails|bjacobi|jacobi|bssor"),
        "precond names");
    local_prm.declare_entry ("ho ssor factor", "1.0",
        dealii::Patterns::Double (),
        "damping factor of Block SSOR for HO");
    local_prm.declare_entry ("nda linear solver name", "none",
        dealii::Patterns::Selection("none|gmres|bicgstab|direct"),
        "NDA linear solers");
    local_prm.declare_entry ("nda preconditioner name", "jacobi",
        dealii::Patterns::Selection("amg|parasails|bjacobi|jacobi|bssor"),
        "precond names");
    local_prm.declare_entry ("nda ssor factor", "1.0",
        dealii::Patterns::Double (),
        "damping factor of Block SSOR for NDA");
    local_prm.declare_entry ("angular quadrature name", "none",
        dealii::Patterns::Selection ("lsgc|gl|none"),
        "angular quadrature types. only LS-GC for multi-D and GL for 1D implemented for now.");
    local_prm.declare_entry ("angular quadrature order", "4",
        dealii::Patterns::Integer (),
        "Gauss-Chebyshev level-symmetric-like quadrature");
    local_prm.declare_entry ("number of groups", "1",
        dealii::Patterns::Integer (), "Number of groups in MG calculations");
    local_prm.declare_entry ("thermal group boundary", "0",
        dealii::Patterns::Integer (),
        "group number for the first thermal group");
    local_prm.declare_entry ("ho spatial discretization", "cfem",
        dealii::Patterns::Selection("dfem|cfem"),
        "HO equation spatial discretization");
    local_prm.declare_entry ("nda spatial discretization", "cfem",
        dealii::Patterns::Selection("dfem|cfem|cmfd|rtk"),
        "NDA equation spatial discretization");
    local_prm.declare_entry ("do eigenvalue calculations", "false",
        dealii::Patterns::Bool(),
        "Boolean to determine problem type");
    local_prm.declare_entry ("do nda", "false",
        dealii::Patterns::Bool(),
        "Boolean to determine NDA or not");
    local_prm.declare_entry ("have reflective BC", "false",
        dealii::Patterns::Bool(), "");
    local_prm.declare_entry ("reflective boundary names", "",
        dealii::Patterns::List (dealii::Patterns::Anything ()),
        "must be lower cases of xmin,xmax,ymin,ymax,zmin,zmax");
    local_prm.declare_entry ("finite element polynomial degree", "1",
        dealii::Patterns::Integer(),
        "polynomial degree p for finite element");
    local_prm.declare_entry ("uniform refinements", "0",
        dealii::Patterns::Integer(),
        "number of uniform refinements desired");
    local_prm.declare_entry ("fuel rod radius", "0.5",
        dealii::Patterns::Double(),
        "radius of fuel rod");
    local_prm.declare_entry ("fuel rod triangulation type", "simple",
        dealii::Patterns::Selection("simple|composite"),
        "triangulation type of fuel rod");
    local_prm.declare_entry ("x, y, z max values of boundary locations", "",
        dealii::Patterns::List (dealii::Patterns::Double ()),
        "xmax, ymax, zmax of the boundaries, mins are zero");
    local_prm.declare_entry ("number of cells for x, y, z directions", "",
        dealii::Patterns::List (dealii::Patterns::Integer ()),
        "Geometry is hyper rectangle defined by how many cells exist per direction");
    local_prm.declare_entry ("number of materials", "1",
        dealii::Patterns::Integer (),
        "must be a positive integer");
    local_prm.declare_entry ("do print angular quadrature info", "true",
        dealii::Patterns::Bool(),
        "Boolean to determine if printing angular quadrature information");
    local_prm.declare_entry ("is mesh generated by deal.II", "true",
        dealii::Patterns::Bool(),
        "Boolean to determine if generating mesh in dealii or read in mesh");
    local_prm.declare_entry ("is mesh pin-resolved", "false",
        dealii::Patterns::Bool(),
        "Boolean to determine if producing pin-resolved mesh");
    local_prm.declare_entry ("output file name base", "solu",
        dealii::Patterns::Anything(),
        "name base of the output file");
    local_prm.declare_entry ("mesh file name", "mesh.msh",
        dealii::Patterns::Anything(),
        ".msh file name for read-in mesh");
  }

  // Explanation: we brute-forcely declare as many entries as possible without read-in problem-definition
  // parameters. kNMat and ngrp should both be large enough s.t. when reading starts, the real setting will
  // have entry-declaration
  local_prm.enter_subsection ("material ID map");
  {
    local_prm.declare_entry ("material id file name", "mid.txt",
        dealii::Patterns::FileName(),
        "file name for material id map");
    local_prm.declare_entry ("fuel pin material id file name", "pin_id.txt",
        dealii::Patterns::FileName(),
        "file name for pin material id map for pin-resolved calculations");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("sigma_t, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry (os.str (), "",
          dealii::Patterns::List (dealii::Patterns::Double ()), "");
    }
  }
  local_prm.leave_subsection ();

  for (int m=0; m<kNMat; ++m) {
    std::ostringstream os;
    os << "sigma_s, material " << m + 1;
    local_prm.enter_subsection (os.str());
    {
      for (int gin=0; gin<kNGrp; ++gin) {
        std::ostringstream osm;
        osm << "g_in=" << gin + 1;
        local_prm.declare_entry (osm.str(), "",
            dealii::Patterns::List(dealii::Patterns::Double()),
            "multigroup sigma_s");
      }
    }
    local_prm.leave_subsection ();
  }

  local_prm.enter_subsection ("one-group sigma_t");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group sigma_s");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group Q");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group chi");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group nu_sigf");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("Q, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry (os.str (), "",
         dealii::Patterns::List (dealii::Patterns::Double ()), "");
    }
  }
  local_prm.leave_subsection ();

  // the following is for eigen problems
  local_prm.enter_subsection ("fissile material IDs");
  {
    local_prm.declare_entry ("fissile material ids", "",
        dealii::Patterns::List (dealii::Patterns::Integer ()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("chi, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry(os.str(), "",
          dealii::Patterns::List(dealii::Patterns::Double()), "");
    }
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("nu_sigf, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry(os.str(), "",
          dealii::Patterns::List(dealii::Patterns::Double()), "");
    }
  }
  local_prm.leave_subsection ();
}

void DeclareParameters () {
  DeclareParameters (GlobPrm);
}
}
<commit_msg>change entry names in problem definition<commit_after>#include "problem_definition.h"

#include <sstream>
#include <utility>
#include <iomanip>

#include <deal.II/base/utilities.h>

dealii::ParameterHandler bparams::GlobPrm;

namespace bparams {
void DeclareParameters (dealii::ParameterHandler &local_prm) {
  // our final strategy is to declare all possible entries
  // and then ignore some of them suggested by Wolfgang Bangerth
  // from Colorado State on 05-10-2017
  // The following are the basic parameters we need to define a problem
  {
    local_prm.declare_entry ("problem dimension", "2",
        dealii::Patterns::Integer(), "");
    local_prm.declare_entry ("transport model", "none",
        dealii::Patterns::Selection("ep|none"),
        "valid names such as ep");
    local_prm.declare_entry ("ho linear solver name", "cg",
        dealii::Patterns::Selection("cg|gmres|bicgstab|direct"),
        "solers");
    local_prm.declare_entry ("ho preconditioner name", "amg",
        dealii::Patterns::Selection("amg|parasails|bjacobi|jacobi|bssor"),
        "precond names");
    local_prm.declare_entry ("ho ssor factor", "1.0",
        dealii::Patterns::Double (),
        "damping factor of Block SSOR for HO");
    local_prm.declare_entry ("eigen solver name", "pi",
        dealii::Patterns::Selection("pi"), "");
    local_prm.declare_entry ("mg solver name", "gs",
        dealii::Patterns::Selection("gs"), "");
    local_prm.declare_entry ("in group solver name", "si",
        dealii::Patterns::Selection("si"), "");
    local_prm.declare_entry ("nda linear solver name", "none",
        dealii::Patterns::Selection("none|gmres|bicgstab|direct"),
        "NDA linear solers");
    local_prm.declare_entry ("nda preconditioner name", "jacobi",
        dealii::Patterns::Selection("amg|parasails|bjacobi|jacobi|bssor"),
        "precond names");
    local_prm.declare_entry ("nda ssor factor", "1.0",
        dealii::Patterns::Double (),
        "damping factor of Block SSOR for NDA");
    local_prm.declare_entry ("angular quadrature name", "none",
        dealii::Patterns::Selection ("lsgc|gl|none"),
        "angular quadrature types. only LS-GC for multi-D and GL for 1D implemented for now.");
    local_prm.declare_entry ("angular quadrature order", "4",
        dealii::Patterns::Integer (),
        "Gauss-Chebyshev level-symmetric-like quadrature");
    local_prm.declare_entry ("number of groups", "1",
        dealii::Patterns::Integer (), "Number of groups in MG calculations");
    local_prm.declare_entry ("thermal group boundary", "0",
        dealii::Patterns::Integer (),
        "group number for the first thermal group");
    local_prm.declare_entry ("ho spatial discretization", "cfem",
        dealii::Patterns::Selection("dfem|cfem"),
        "HO equation spatial discretization");
    local_prm.declare_entry ("nda spatial discretization", "cfem",
        dealii::Patterns::Selection("dfem|cfem|cmfd|rtk"),
        "NDA equation spatial discretization");
    local_prm.declare_entry ("do eigenvalue calculations", "false",
        dealii::Patterns::Bool(),
        "Boolean to determine problem type");
    local_prm.declare_entry ("do nda", "false",
        dealii::Patterns::Bool(),
        "Boolean to determine NDA or not");
    local_prm.declare_entry ("have reflective boundary", "false",
        dealii::Patterns::Bool(), "");
    local_prm.declare_entry ("reflective boundary names", "",
        dealii::Patterns::List (dealii::Patterns::Anything ()),
        "must be lower cases of xmin,xmax,ymin,ymax,zmin,zmax");
    local_prm.declare_entry ("finite element polynomial degree", "1",
        dealii::Patterns::Integer(),
        "polynomial degree p for finite element");
    local_prm.declare_entry ("uniform refinements", "0",
        dealii::Patterns::Integer(),
        "number of uniform refinements desired");
    local_prm.declare_entry ("fuel rod radius", "0.5",
        dealii::Patterns::Double(),
        "radius of fuel rod");
    local_prm.declare_entry ("fuel rod triangulation type", "simple",
        dealii::Patterns::Selection("simple|composite"),
        "triangulation type of fuel rod");
    local_prm.declare_entry ("x, y, z max values of boundary locations", "",
        dealii::Patterns::List (dealii::Patterns::Double ()),
        "xmax, ymax, zmax of the boundaries, mins are zero");
    local_prm.declare_entry ("number of cells for x, y, z directions", "",
        dealii::Patterns::List (dealii::Patterns::Integer ()),
        "Geometry is hyper rectangle defined by how many cells exist per direction");
    local_prm.declare_entry ("number of materials", "1",
        dealii::Patterns::Integer (),
        "must be a positive integer");
    local_prm.declare_entry ("do print angular quadrature info", "true",
        dealii::Patterns::Bool(),
        "Boolean to determine if printing angular quadrature information");
    local_prm.declare_entry ("is mesh generated by deal.II", "true",
        dealii::Patterns::Bool(),
        "Boolean to determine if generating mesh in dealii or read in mesh");
    local_prm.declare_entry ("is mesh pin-resolved", "false",
        dealii::Patterns::Bool(),
        "Boolean to determine if producing pin-resolved mesh");
    local_prm.declare_entry ("output file name base", "solu",
        dealii::Patterns::Anything(),
        "name base of the output file");
    local_prm.declare_entry ("mesh file name", "mesh.msh",
        dealii::Patterns::Anything(),
        ".msh file name for read-in mesh");
  }

  // Explanation: we brute-forcely declare as many entries as possible without read-in problem-definition
  // parameters. kNMat and ngrp should both be large enough s.t. when reading starts, the real setting will
  // have entry-declaration
  local_prm.enter_subsection ("material ID map");
  {
    local_prm.declare_entry ("material id file name", "mid.txt",
        dealii::Patterns::FileName(),
        "file name for material id map");
    local_prm.declare_entry ("fuel pin material id file name", "pin_id.txt",
        dealii::Patterns::FileName(),
        "file name for pin material id map for pin-resolved calculations");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("sigma_t, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry (os.str (), "",
          dealii::Patterns::List (dealii::Patterns::Double ()), "");
    }
  }
  local_prm.leave_subsection ();

  for (int m=0; m<kNMat; ++m) {
    std::ostringstream os;
    os << "sigma_s, material " << m + 1;
    local_prm.enter_subsection (os.str());
    {
      for (int gin=0; gin<kNGrp; ++gin) {
        std::ostringstream osm;
        osm << "g_in=" << gin + 1;
        local_prm.declare_entry (osm.str(), "",
            dealii::Patterns::List(dealii::Patterns::Double()),
            "multigroup sigma_s");
      }
    }
    local_prm.leave_subsection ();
  }

  local_prm.enter_subsection ("one-group sigma_t");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group sigma_s");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group Q");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group chi");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("one-group nu_sigf");
  {
    local_prm.declare_entry ("values", "",
        dealii::Patterns::List(dealii::Patterns::Double()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("Q, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry (os.str (), "",
         dealii::Patterns::List (dealii::Patterns::Double ()), "");
    }
  }
  local_prm.leave_subsection ();

  // the following is for eigen problems
  local_prm.enter_subsection ("fissile material IDs");
  {
    local_prm.declare_entry ("fissile material ids", "",
        dealii::Patterns::List (dealii::Patterns::Integer ()), "");
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("chi, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry(os.str(), "",
          dealii::Patterns::List(dealii::Patterns::Double()), "");
    }
  }
  local_prm.leave_subsection ();

  local_prm.enter_subsection ("nu_sigf, group=1 to G");
  {
    for (int m=0; m<kNMat; ++m) {
      std::ostringstream os;
      os << "material " << m + 1;
      local_prm.declare_entry(os.str(), "",
          dealii::Patterns::List(dealii::Patterns::Double()), "");
    }
  }
  local_prm.leave_subsection ();
}

void DeclareParameters () {
  DeclareParameters (GlobPrm);
}
}
<|endoftext|>


<commit_before>#include <qnumeric.h>
#include <QsLog.h>
#include <velib/vecan/products.h>
#include "froniussolar_api.h"
#include "fronius_device_info.h"
#include "settings.h"
#include "solar_api_detector.h"
#include "sunspec_detector.h"

QList<QString> SolarApiDetector::mInvalidDevices;

SolarApiDetector::SolarApiDetector(const Settings *settings, QObject *parent):
	AbstractDetector(parent),
	mSunspecDetector(new SunspecDetector(this)),
	mSettings(settings)
{
}

DetectorReply *SolarApiDetector::start(const QString &hostName)
{
	Reply *reply = new Reply(this);
	reply->api = new FroniusSolarApi(hostName, mSettings->portNumber(), reply);
	mApiToReply[reply->api] = reply;
	connect(reply->api, SIGNAL(converterInfoFound(InverterListData)),
		this, SLOT(onConverterInfoFound(InverterListData)));
	reply->api->getConverterInfoAsync();
	return reply;
}

void SolarApiDetector::onConverterInfoFound(const InverterListData &data)
{
	FroniusSolarApi *api = static_cast<FroniusSolarApi *>(sender());
	Reply *reply = mApiToReply.value(api);
	bool setFinished = true;
	for (QList<InverterInfo>::const_iterator it = data.inverters.begin();
		 it != data.inverters.end();
		 ++it) {
		// Sometimes (during startup?) PV inverters will send 255 as device
		// type instead of the real type. We have only seen this in a test
		// setup with a Fronius IG Plus 50 V-1.
		if (it->deviceType == 255) {
			if (!mInvalidDevices.contains(it->uniqueId)) {
				mInvalidDevices.append(it->uniqueId);
				QLOG_WARN() << "PV inverter reported type 255. Serial:" << it->uniqueId;
			}
		} else {
			ReplyToInverter device;
			device.reply = reply;
			device.inverter = *it;

			mSunspecDetector->setUnitId(it->id);
			DetectorReply *dr = mSunspecDetector->start(api->hostName());
			connect(dr, SIGNAL(deviceFound(DeviceInfo)),
					this, SLOT(onSunspecDeviceFound(DeviceInfo)));
			connect(dr, SIGNAL(finished()), this, SLOT(onSunspecDone()));
			mDetectorReplyToInverter[dr] = device;
			setFinished = false;
		}
	}
	if (setFinished)
		reply->setFinished();
}

void SolarApiDetector::onSunspecDeviceFound(const DeviceInfo &info)
{
	DetectorReply *dr = static_cast<DetectorReply *>(sender());
	ReplyToInverter &device = mDetectorReplyToInverter[dr];
	Q_ASSERT(device.reply != 0);
	if (device.reply == 0)
		return;
	DeviceInfo i2(info);
	// unique ID is used to find inverter settings, and to determine the device instance. In
	// previous versions, the unique ID constructed from data retrieved using the solar API.
	// The sunspec detector uses the serial number of the inverter as unique ID, which is not
	// available in the solar API.
	i2.uniqueId = fixUniqueId(device.inverter);

	// Fronius inverters have a deviceType that is exposed on solarAPI but not
	// via sunspec. Transplant it here. If this is not a Fronius inverter
	// this value will simply be a zero.
	i2.deviceType = device.inverter.deviceType;

	device.deviceFound = true;
	device.reply->setResult(i2);
}

void SolarApiDetector::onSunspecDone()
{
	DetectorReply *dr = static_cast<DetectorReply *>(sender());
	dr->deleteLater();
	ReplyToInverter device = mDetectorReplyToInverter.take(dr);
	Q_ASSERT(device.reply != 0);
	if (device.reply == 0)
		return;
	if (device.deviceFound) {
		checkFinished(device.reply);
		return;
	}
	// Sunspec was not enabled for this inverter, so we fall back to solar api.
	DeviceInfo info;
	info.networkId = device.inverter.id;
	info.uniqueId = fixUniqueId(device.inverter);
	info.hostName = device.reply->api->hostName();
	info.port = device.reply->api->port();
	info.deviceType = device.inverter.deviceType;
	info.productId = VE_PROD_ID_PV_INVERTER_FRONIUS;
	info.maxPower = qQNaN();
	const FroniusDeviceInfo *deviceInfo = FroniusDeviceInfo::find(device.inverter.deviceType);
	if (deviceInfo == 0) {
		QLOG_WARN() << "Unknown inverter type:" << device.inverter.deviceType;
		info.productName = "Unknown PV Inverter";
		info.phaseCount = 1;
	} else {
		info.productName = deviceInfo->name;
		info.phaseCount = deviceInfo->phaseCount;
	}
	device.deviceFound = true;
	device.reply->setResult(info);
	checkFinished(device.reply);
}

QString SolarApiDetector::fixUniqueId(const InverterInfo &inverterInfo)
{
	bool isOk = false;
	QString result;
	foreach (QChar c, inverterInfo.uniqueId) {
		c = c.toAscii();
		if (!c.isLetterOrNumber()) {
			c = '_';
		} else {
			isOk = true;
		}
		result += c;
	}
	if (!isOk)
		result = QString("T%1").arg(inverterInfo.id);
	return QString("%1_%2").arg(inverterInfo.deviceType).arg(result);
}

void SolarApiDetector::checkFinished(Reply *reply)
{
	// Check if there are any pending replies from the sunspec detector associated `reply`.
	// We need this because a single call to getConverterInfoAsync in the solar API may give us
	// multiple PV inverters. Each PV inverter is tested for ModbusTCP support. Only after the last
	// test has been completed the request, which initiated the call to getConverterInfoAsync can
	// be finished.
	foreach (const ReplyToInverter &rti, mDetectorReplyToInverter) {
		if (rti.reply == reply && !rti.deviceFound)
			return;
	}
	reply->setFinished();
}

SolarApiDetector::Reply::Reply(QObject *parent):
	DetectorReply(parent),
	api(0)
{
}

SolarApiDetector::Reply::~Reply()
{
}
<commit_msg>qt5: use QChar.toLatin1 ito toAscii.<commit_after>#include <qnumeric.h>
#include <QsLog.h>
#include <velib/vecan/products.h>
#include "froniussolar_api.h"
#include "fronius_device_info.h"
#include "settings.h"
#include "solar_api_detector.h"
#include "sunspec_detector.h"

QList<QString> SolarApiDetector::mInvalidDevices;

SolarApiDetector::SolarApiDetector(const Settings *settings, QObject *parent):
	AbstractDetector(parent),
	mSunspecDetector(new SunspecDetector(this)),
	mSettings(settings)
{
}

DetectorReply *SolarApiDetector::start(const QString &hostName)
{
	Reply *reply = new Reply(this);
	reply->api = new FroniusSolarApi(hostName, mSettings->portNumber(), reply);
	mApiToReply[reply->api] = reply;
	connect(reply->api, SIGNAL(converterInfoFound(InverterListData)),
		this, SLOT(onConverterInfoFound(InverterListData)));
	reply->api->getConverterInfoAsync();
	return reply;
}

void SolarApiDetector::onConverterInfoFound(const InverterListData &data)
{
	FroniusSolarApi *api = static_cast<FroniusSolarApi *>(sender());
	Reply *reply = mApiToReply.value(api);
	bool setFinished = true;
	for (QList<InverterInfo>::const_iterator it = data.inverters.begin();
		 it != data.inverters.end();
		 ++it) {
		// Sometimes (during startup?) PV inverters will send 255 as device
		// type instead of the real type. We have only seen this in a test
		// setup with a Fronius IG Plus 50 V-1.
		if (it->deviceType == 255) {
			if (!mInvalidDevices.contains(it->uniqueId)) {
				mInvalidDevices.append(it->uniqueId);
				QLOG_WARN() << "PV inverter reported type 255. Serial:" << it->uniqueId;
			}
		} else {
			ReplyToInverter device;
			device.reply = reply;
			device.inverter = *it;

			mSunspecDetector->setUnitId(it->id);
			DetectorReply *dr = mSunspecDetector->start(api->hostName());
			connect(dr, SIGNAL(deviceFound(DeviceInfo)),
					this, SLOT(onSunspecDeviceFound(DeviceInfo)));
			connect(dr, SIGNAL(finished()), this, SLOT(onSunspecDone()));
			mDetectorReplyToInverter[dr] = device;
			setFinished = false;
		}
	}
	if (setFinished)
		reply->setFinished();
}

void SolarApiDetector::onSunspecDeviceFound(const DeviceInfo &info)
{
	DetectorReply *dr = static_cast<DetectorReply *>(sender());
	ReplyToInverter &device = mDetectorReplyToInverter[dr];
	Q_ASSERT(device.reply != 0);
	if (device.reply == 0)
		return;
	DeviceInfo i2(info);
	// unique ID is used to find inverter settings, and to determine the device instance. In
	// previous versions, the unique ID constructed from data retrieved using the solar API.
	// The sunspec detector uses the serial number of the inverter as unique ID, which is not
	// available in the solar API.
	i2.uniqueId = fixUniqueId(device.inverter);

	// Fronius inverters have a deviceType that is exposed on solarAPI but not
	// via sunspec. Transplant it here. If this is not a Fronius inverter
	// this value will simply be a zero.
	i2.deviceType = device.inverter.deviceType;

	device.deviceFound = true;
	device.reply->setResult(i2);
}

void SolarApiDetector::onSunspecDone()
{
	DetectorReply *dr = static_cast<DetectorReply *>(sender());
	dr->deleteLater();
	ReplyToInverter device = mDetectorReplyToInverter.take(dr);
	Q_ASSERT(device.reply != 0);
	if (device.reply == 0)
		return;
	if (device.deviceFound) {
		checkFinished(device.reply);
		return;
	}
	// Sunspec was not enabled for this inverter, so we fall back to solar api.
	DeviceInfo info;
	info.networkId = device.inverter.id;
	info.uniqueId = fixUniqueId(device.inverter);
	info.hostName = device.reply->api->hostName();
	info.port = device.reply->api->port();
	info.deviceType = device.inverter.deviceType;
	info.productId = VE_PROD_ID_PV_INVERTER_FRONIUS;
	info.maxPower = qQNaN();
	const FroniusDeviceInfo *deviceInfo = FroniusDeviceInfo::find(device.inverter.deviceType);
	if (deviceInfo == 0) {
		QLOG_WARN() << "Unknown inverter type:" << device.inverter.deviceType;
		info.productName = "Unknown PV Inverter";
		info.phaseCount = 1;
	} else {
		info.productName = deviceInfo->name;
		info.phaseCount = deviceInfo->phaseCount;
	}
	device.deviceFound = true;
	device.reply->setResult(info);
	checkFinished(device.reply);
}

QString SolarApiDetector::fixUniqueId(const InverterInfo &inverterInfo)
{
	bool isOk = false;
	QString result;
	foreach (QChar c, inverterInfo.uniqueId) {
		c = c.toLatin1();
		if (!c.isLetterOrNumber()) {
			c = '_';
		} else {
			isOk = true;
		}
		result += c;
	}
	if (!isOk)
		result = QString("T%1").arg(inverterInfo.id);
	return QString("%1_%2").arg(inverterInfo.deviceType).arg(result);
}

void SolarApiDetector::checkFinished(Reply *reply)
{
	// Check if there are any pending replies from the sunspec detector associated `reply`.
	// We need this because a single call to getConverterInfoAsync in the solar API may give us
	// multiple PV inverters. Each PV inverter is tested for ModbusTCP support. Only after the last
	// test has been completed the request, which initiated the call to getConverterInfoAsync can
	// be finished.
	foreach (const ReplyToInverter &rti, mDetectorReplyToInverter) {
		if (rti.reply == reply && !rti.deviceFound)
			return;
	}
	reply->setFinished();
}

SolarApiDetector::Reply::Reply(QObject *parent):
	DetectorReply(parent),
	api(0)
{
}

SolarApiDetector::Reply::~Reply()
{
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tabsthdl.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-12 14:51:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_PROPERTYHANDLER_TABSTOPTYPES_HXX
#include <tabsthdl.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#ifndef _COM_SUN_STAR_STYLE_TABSTOP_HPP_
#include <com/sun/star/style/TabStop.hpp>
#endif

using namespace ::com::sun::star;

///////////////////////////////////////////////////////////////////////////////
//
// class XMLFontFamilyNamePropHdl
//

XMLTabStopPropHdl::~XMLTabStopPropHdl()
{
    // Nothing to do
}

bool XMLTabStopPropHdl::equals( const uno::Any& r1, const uno::Any& r2 ) const
{
    sal_Bool bEqual = sal_False;

    uno::Sequence< style::TabStop> aSeq1;
    if( r1 >>= aSeq1 )
    {
        uno::Sequence< style::TabStop> aSeq2;
        if( r2 >>= aSeq2 )
        {
            if( aSeq1.getLength() == aSeq2.getLength() )
            {
                bEqual = sal_True;
                if( aSeq1.getLength() > 0 )
                {
                    const style::TabStop* pTabs1 = aSeq1.getConstArray();
                    const style::TabStop* pTabs2 = aSeq2.getConstArray();

                    int i=0;

                    do
                    {
                        bEqual = ( pTabs1[i].Position == pTabs2[i].Position       &&
                                   pTabs1[i].Alignment == pTabs2[i].Alignment     &&
                                   pTabs1[i].DecimalChar == pTabs2[i].DecimalChar &&
                                   pTabs1[i].FillChar == pTabs2[i].FillChar );
                        i++;

                    } while( bEqual && i < aSeq1.getLength() );
                }
            }
        }
    }

    return bEqual;
}

sal_Bool XMLTabStopPropHdl::importXML( const ::rtl::OUString&, ::com::sun::star::uno::Any&, const SvXMLUnitConverter& ) const
{
    return sal_False;
}

sal_Bool XMLTabStopPropHdl::exportXML( ::rtl::OUString&, const ::com::sun::star::uno::Any&, const SvXMLUnitConverter& ) const
{
    return sal_False;
}

<commit_msg>INTEGRATION: CWS changefileheader (1.6.290); FILE MERGED 2008/04/01 16:09:58 thb 1.6.290.3: #i85898# Stripping all external header guards 2008/04/01 13:05:10 thb 1.6.290.2: #i85898# Stripping all external header guards 2008/03/31 16:28:23 rt 1.6.290.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: tabsthdl.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include <tabsthdl.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/style/TabStop.hpp>

using namespace ::com::sun::star;

///////////////////////////////////////////////////////////////////////////////
//
// class XMLFontFamilyNamePropHdl
//

XMLTabStopPropHdl::~XMLTabStopPropHdl()
{
    // Nothing to do
}

bool XMLTabStopPropHdl::equals( const uno::Any& r1, const uno::Any& r2 ) const
{
    sal_Bool bEqual = sal_False;

    uno::Sequence< style::TabStop> aSeq1;
    if( r1 >>= aSeq1 )
    {
        uno::Sequence< style::TabStop> aSeq2;
        if( r2 >>= aSeq2 )
        {
            if( aSeq1.getLength() == aSeq2.getLength() )
            {
                bEqual = sal_True;
                if( aSeq1.getLength() > 0 )
                {
                    const style::TabStop* pTabs1 = aSeq1.getConstArray();
                    const style::TabStop* pTabs2 = aSeq2.getConstArray();

                    int i=0;

                    do
                    {
                        bEqual = ( pTabs1[i].Position == pTabs2[i].Position       &&
                                   pTabs1[i].Alignment == pTabs2[i].Alignment     &&
                                   pTabs1[i].DecimalChar == pTabs2[i].DecimalChar &&
                                   pTabs1[i].FillChar == pTabs2[i].FillChar );
                        i++;

                    } while( bEqual && i < aSeq1.getLength() );
                }
            }
        }
    }

    return bEqual;
}

sal_Bool XMLTabStopPropHdl::importXML( const ::rtl::OUString&, ::com::sun::star::uno::Any&, const SvXMLUnitConverter& ) const
{
    return sal_False;
}

sal_Bool XMLTabStopPropHdl::exportXML( ::rtl::OUString&, const ::com::sun::star::uno::Any&, const SvXMLUnitConverter& ) const
{
    return sal_False;
}

<|endoftext|>


<commit_before>#pragma once

#include <array>
#include <iostream>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <stdexcept>
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>

#include <boost/mpl/set.hpp>
#include <boost/optional.hpp>

#include "blackhole/attribute/set.hpp"
#include "blackhole/config.hpp"
#include "blackhole/detail/iterator/join.hpp"
#include "blackhole/detail/traits/tuple.hpp"

namespace blackhole {

namespace attribute {

namespace set_view {

template<class... T>
struct tuple_extractor_t;

} // namespace set_view

class set_view_t {
    template<class... T> friend struct set_view::tuple_extractor_t;

public:
    typedef aux::iterator::join_t<set_t, true> const_iterator;

    struct attached_set_t { set_t v; };
    struct internal_set_t { set_t v; };
    struct external_set_t { set_t v; };

private:
    attached_set_t attached;  // Likely empty.
    internal_set_t internal;  // About level + message + pid + tid + timestamp (4-5).
    external_set_t external;  // The most filled (scoped + user attributes)

public:
    set_view_t() = default;
    set_view_t(set_t attached, set_t external, set_t&& internal);

    bool
    empty() const BLACKHOLE_NOEXCEPT {
        return empty<attached_set_t, internal_set_t, external_set_t>();
    }

    template<class T>
    bool
    empty() const BLACKHOLE_NOEXCEPT;

    template<class T, class... Args>
    typename std::enable_if<
        sizeof...(Args) != 0 && sizeof...(Args) <= 3,
        bool
    >::type
    empty() const BLACKHOLE_NOEXCEPT {
        return empty<T>() && empty<Args...>();
    }

    //! Intentionally allow to insert only to external attribute set.
    void insert(pair_t pair);

    template<typename InputIterator>
    void insert(InputIterator first, InputIterator last);

    const_iterator begin() const BLACKHOLE_NOEXCEPT;
    const_iterator end() const BLACKHOLE_NOEXCEPT;

    boost::optional<const attribute_t&>
    find(const std::string& name) const BLACKHOLE_NOEXCEPT;

    const attribute_t& at(const std::string& name) const;
};

namespace set_view {

template<>
struct tuple_extractor_t<set_view_t::attached_set_t> {
    static
    std::tuple<set_view_t::attached_set_t>
    extract(const set_view_t& view) {
        return std::make_tuple(view.attached);
    }
};

template<>
struct tuple_extractor_t<set_view_t::internal_set_t> {
    static
    std::tuple<set_view_t::internal_set_t>
    extract(const set_view_t& view) {
        return std::make_tuple(view.internal);
    }
};

template<>
struct tuple_extractor_t<set_view_t::external_set_t> {
    static
    std::tuple<set_view_t::external_set_t>
    extract(const set_view_t& view) {
        return std::make_tuple(view.external);
    }
};

template<class T, class Arg, class... Args>
struct tuple_extractor_t<T, Arg, Args...> {
    static
    std::tuple<T, Arg, Args...>
    extract(const set_view_t& view) {
        return std::tuple_cat(
            tuple_extractor_t<T>::extract(view),
            tuple_extractor_t<Arg, Args...>::extract(view)
        );
    }
};

} // namespace set_view

template<class T, unsigned size>
struct all_empty_t {
    static bool empty(const T& tuple) {
        return std::get<size>(tuple).v.empty() && all_empty_t<T, size - 1>::empty(tuple);
    }
};

template<class T>
struct all_empty_t<T, 0u> {
    static bool empty(const T& tuple) {
        return std::get<0>(tuple).v.empty();
    }
};

template<class T>
struct tuple_empty {
    static bool empty(const T& tuple) {
        return all_empty_t<T, std::tuple_size<T>::value - 1>::empty(tuple);
    }
};

template<class... T>
class partial_view_t {
public:
    typedef std::tuple<T...> tuple_type;
    typedef std::integral_constant<
        typename std::tuple_size<tuple_type>::value_type,
        std::tuple_size<tuple_type>::value
    > tuple_size;

    typedef set_view_t::const_iterator const_iterator;

private:
    typedef std::array<const set_t*, tuple_size::value> array_type;
    typedef typename make_index_tuple<tuple_size::value>::type index_tuple_type;

    const tuple_type tuple;

public:
    partial_view_t(const set_view_t& view) :
        tuple(set_view::tuple_extractor_t<T...>::extract(view))
    {}

    bool
    empty() const BLACKHOLE_NOEXCEPT {
        return empty(tuple);
    }

    const_iterator
    begin() const BLACKHOLE_NOEXCEPT {
        return const_iterator(to_array(tuple, index_tuple_type()));
    }

    const_iterator
    end() const BLACKHOLE_NOEXCEPT {
        return const_iterator(to_array(tuple, index_tuple_type()), aux::iterator::invalidate_tag);
    }

private:
    template<unsigned... I>
    static
    inline
    array_type
    to_array(const tuple_type& tuple, index_tuple<I...>) {
        return array_type {{ &std::get<I>(tuple).v... }};
    }

    static
    inline
    bool
    empty(const tuple_type& tuple) {
        return tuple_empty<tuple_type>::empty(tuple);
    }
};

BLACKHOLE_API
set_view_t::set_view_t(set_t attached, set_t external, set_t&& internal) :
    attached({ std::move(attached) }),
    internal({ std::move(internal) }),
    external({ std::move(external) })
{}

template<>
BLACKHOLE_API
bool
set_view_t::empty<set_view_t::attached_set_t>() const BLACKHOLE_NOEXCEPT {
    return attached.v.empty();
}

template<>
BLACKHOLE_API
bool
set_view_t::empty<set_view_t::internal_set_t>() const BLACKHOLE_NOEXCEPT {
    return internal.v.empty();
}

template<>
BLACKHOLE_API
bool
set_view_t::empty<set_view_t::external_set_t>() const BLACKHOLE_NOEXCEPT {
    return external.v.empty();
}

BLACKHOLE_API
void
set_view_t::insert(pair_t pair) {
    external.v.insert(std::move(pair));
}

template<typename InputIterator>
BLACKHOLE_API
void
set_view_t::insert(InputIterator first, InputIterator last) {
    external.v.insert(first, last);
}

BLACKHOLE_API
set_view_t::const_iterator
set_view_t::begin() const BLACKHOLE_NOEXCEPT {
    std::array<set_t const*, 3> a{{ &internal.v, &external.v, &attached.v }};
    return const_iterator(a);
}

BLACKHOLE_API
set_view_t::const_iterator
set_view_t::end() const BLACKHOLE_NOEXCEPT {
    std::array<set_t const*, 3> a{{ &internal.v, &external.v, &attached.v }};
    return const_iterator(a, aux::iterator::invalidate_tag);
}

BLACKHOLE_API
boost::optional<const attribute_t&>
set_view_t::find(const std::string& name) const BLACKHOLE_NOEXCEPT {
    auto it = internal.v.find(name);
    if (it != internal.v.end()) {
        return it->second;
    }

    it = external.v.find(name);
    if (it != external.v.end()) {
        return it->second;
    }

    it = attached.v.find(name);
    if (it != attached.v.end()) {
        return it->second;
    }

    return boost::optional<const attribute_t&>();
}

BLACKHOLE_API
const attribute_t&
set_view_t::at(const std::string &name) const {
    auto value = find(name);
    if (!value) {
        throw std::out_of_range(name);
    }

    return *value;
}

} // namespace attribute

} // namespace blackhole
<commit_msg>[Code Clean] Simplification for 'empty' method.<commit_after>#pragma once

#include <array>
#include <iostream>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <stdexcept>
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>

#include <boost/mpl/set.hpp>
#include <boost/optional.hpp>

#include "blackhole/attribute/set.hpp"
#include "blackhole/config.hpp"
#include "blackhole/detail/iterator/join.hpp"
#include "blackhole/detail/traits/tuple.hpp"

namespace blackhole {

namespace attribute {

namespace set_view {

template<class... T>
struct tuple_extractor_t;

} // namespace set_view

class set_view_t {
    template<class... T> friend struct set_view::tuple_extractor_t;

public:
    typedef aux::iterator::join_t<set_t, true> const_iterator;

    struct attached_set_t { set_t v; };
    struct internal_set_t { set_t v; };
    struct external_set_t { set_t v; };

private:
    attached_set_t attached;  // Likely empty.
    internal_set_t internal;  // About level + message + pid + tid + timestamp (4-5).
    external_set_t external;  // The most filled (scoped + user attributes)

public:
    set_view_t() = default;
    set_view_t(set_t attached, set_t external, set_t&& internal);

    bool
    empty() const BLACKHOLE_NOEXCEPT {
        return internal.v.empty() && external.v.empty() && attached.v.empty();
    }

    //! Intentionally allow to insert only to external attribute set.
    void insert(pair_t pair);

    template<typename InputIterator>
    void insert(InputIterator first, InputIterator last);

    const_iterator begin() const BLACKHOLE_NOEXCEPT;
    const_iterator end() const BLACKHOLE_NOEXCEPT;

    boost::optional<const attribute_t&>
    find(const std::string& name) const BLACKHOLE_NOEXCEPT;

    const attribute_t& at(const std::string& name) const;
};

namespace set_view {

template<>
struct tuple_extractor_t<set_view_t::attached_set_t> {
    static
    std::tuple<set_view_t::attached_set_t>
    extract(const set_view_t& view) {
        return std::make_tuple(view.attached);
    }
};

template<>
struct tuple_extractor_t<set_view_t::internal_set_t> {
    static
    std::tuple<set_view_t::internal_set_t>
    extract(const set_view_t& view) {
        return std::make_tuple(view.internal);
    }
};

template<>
struct tuple_extractor_t<set_view_t::external_set_t> {
    static
    std::tuple<set_view_t::external_set_t>
    extract(const set_view_t& view) {
        return std::make_tuple(view.external);
    }
};

template<class T, class Arg, class... Args>
struct tuple_extractor_t<T, Arg, Args...> {
    static
    std::tuple<T, Arg, Args...>
    extract(const set_view_t& view) {
        return std::tuple_cat(
            tuple_extractor_t<T>::extract(view),
            tuple_extractor_t<Arg, Args...>::extract(view)
        );
    }
};

} // namespace set_view

template<class T, unsigned size>
struct all_empty_t {
    static bool empty(const T& tuple) {
        return std::get<size>(tuple).v.empty() && all_empty_t<T, size - 1>::empty(tuple);
    }
};

template<class T>
struct all_empty_t<T, 0u> {
    static bool empty(const T& tuple) {
        return std::get<0>(tuple).v.empty();
    }
};

template<class T>
struct tuple_empty {
    static bool empty(const T& tuple) {
        return all_empty_t<T, std::tuple_size<T>::value - 1>::empty(tuple);
    }
};

template<class... T>
class partial_view_t {
public:
    typedef std::tuple<T...> tuple_type;
    typedef std::integral_constant<
        typename std::tuple_size<tuple_type>::value_type,
        std::tuple_size<tuple_type>::value
    > tuple_size;

    typedef set_view_t::const_iterator const_iterator;

private:
    typedef std::array<const set_t*, tuple_size::value> array_type;
    typedef typename make_index_tuple<tuple_size::value>::type index_tuple_type;

    const tuple_type tuple;

public:
    partial_view_t(const set_view_t& view) :
        tuple(set_view::tuple_extractor_t<T...>::extract(view))
    {}

    bool
    empty() const BLACKHOLE_NOEXCEPT {
        return empty(tuple);
    }

    const_iterator
    begin() const BLACKHOLE_NOEXCEPT {
        return const_iterator(to_array(tuple, index_tuple_type()));
    }

    const_iterator
    end() const BLACKHOLE_NOEXCEPT {
        return const_iterator(to_array(tuple, index_tuple_type()), aux::iterator::invalidate_tag);
    }

private:
    template<unsigned... I>
    static
    inline
    array_type
    to_array(const tuple_type& tuple, index_tuple<I...>) {
        return array_type {{ &std::get<I>(tuple).v... }};
    }

    static
    inline
    bool
    empty(const tuple_type& tuple) {
        return tuple_empty<tuple_type>::empty(tuple);
    }
};

BLACKHOLE_API
set_view_t::set_view_t(set_t attached, set_t external, set_t&& internal) :
    attached({ std::move(attached) }),
    internal({ std::move(internal) }),
    external({ std::move(external) })
{}

BLACKHOLE_API
void
set_view_t::insert(pair_t pair) {
    external.v.insert(std::move(pair));
}

template<typename InputIterator>
BLACKHOLE_API
void
set_view_t::insert(InputIterator first, InputIterator last) {
    external.v.insert(first, last);
}

BLACKHOLE_API
set_view_t::const_iterator
set_view_t::begin() const BLACKHOLE_NOEXCEPT {
    std::array<set_t const*, 3> a{{ &internal.v, &external.v, &attached.v }};
    return const_iterator(a);
}

BLACKHOLE_API
set_view_t::const_iterator
set_view_t::end() const BLACKHOLE_NOEXCEPT {
    std::array<set_t const*, 3> a{{ &internal.v, &external.v, &attached.v }};
    return const_iterator(a, aux::iterator::invalidate_tag);
}

BLACKHOLE_API
boost::optional<const attribute_t&>
set_view_t::find(const std::string& name) const BLACKHOLE_NOEXCEPT {
    auto it = internal.v.find(name);
    if (it != internal.v.end()) {
        return it->second;
    }

    it = external.v.find(name);
    if (it != external.v.end()) {
        return it->second;
    }

    it = attached.v.find(name);
    if (it != attached.v.end()) {
        return it->second;
    }

    return boost::optional<const attribute_t&>();
}

BLACKHOLE_API
const attribute_t&
set_view_t::at(const std::string &name) const {
    auto value = find(name);
    if (!value) {
        throw std::out_of_range(name);
    }

    return *value;
}

} // namespace attribute

} // namespace blackhole
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: weighhdl.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:45:49 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_PROPERTYHANDLER_FONTWEIGHTTYPES_HXX
#include <weighhdl.hxx>
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif

#ifndef _VCL_VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

#ifndef _INC_LIMITS
#include <limits.h>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::xmloff::token;

struct FontWeightMapper
{
    FontWeight eWeight;
    USHORT nValue;
};

FontWeightMapper const aFontWeightMap[] =
{
    { WEIGHT_DONTKNOW,              0 },
    { WEIGHT_THIN,                  100 },
    { WEIGHT_ULTRALIGHT,            150 },
    { WEIGHT_LIGHT,                 250 },
    { WEIGHT_SEMILIGHT,             350 },
    { WEIGHT_NORMAL,                400 },
    { WEIGHT_MEDIUM,                450 },
    { WEIGHT_SEMIBOLD,              600 },
    { WEIGHT_BOLD,                  700 },
    { WEIGHT_ULTRABOLD,             800 },
    { WEIGHT_BLACK,                 900 },
    { (FontWeight)USHRT_MAX,       1000 }
};

///////////////////////////////////////////////////////////////////////////////
//
// class XMLFmtBreakBeforePropHdl
//

XMLFontWeightPropHdl::~XMLFontWeightPropHdl()
{
    // Nothing to do
}

sal_Bool XMLFontWeightPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
    sal_Bool bRet = sal_False;
    sal_uInt16 nWeight = 0;

    if( IsXMLToken( rStrImpValue, XML_WEIGHT_NORMAL ) )
    {
        nWeight = 400;
        bRet = sal_True;
    }
    else if( IsXMLToken( rStrImpValue, XML_WEIGHT_BOLD ) )
    {
        nWeight = 700;
        bRet = sal_True;
    }
    else
    {
        sal_Int32 nTemp;
        bRet = SvXMLUnitConverter::convertNumber( nTemp, rStrImpValue, 100, 900 );
        if( bRet )
            nWeight = sal::static_int_cast< sal_uInt16 >(nTemp);
    }

    if( bRet )
    {
        bRet = sal_False;

        for( int i = 0; aFontWeightMap[i].eWeight != USHRT_MAX; i++ )
        {
            if( (nWeight >= aFontWeightMap[i].nValue) && (nWeight <= aFontWeightMap[i+1].nValue) )
            {
                sal_uInt16 nDiff1 = nWeight - aFontWeightMap[i].nValue;
                sal_uInt16 nDiff2 = aFontWeightMap[i+1].nValue - nWeight;

                if( nDiff1 < nDiff2 )
                    rValue <<= (float)( VCLUnoHelper::ConvertFontWeight( aFontWeightMap[i].eWeight ) );
                else
                    rValue <<= (float)( VCLUnoHelper::ConvertFontWeight( aFontWeightMap[i+1].eWeight ) );

                bRet = sal_True;
                break;
            }
        }
    }

    return bRet;
}

sal_Bool XMLFontWeightPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
    sal_Bool bRet = sal_False;
    FontWeight eWeight;

    float fValue = float();
    if( !( rValue >>= fValue ) )
    {
        sal_Int32 nValue = 0;
        if( rValue >>= nValue )
        {
            fValue = (float)nValue;
            bRet = sal_True;
        }
    }
    else
        bRet = sal_True;

    eWeight = VCLUnoHelper::ConvertFontWeight( fValue );

    if( bRet )
    {
        sal_uInt16 nWeight = 0;

        for( int i = 0; aFontWeightMap[i].eWeight != -1; i++ )
        {
            if( aFontWeightMap[i].eWeight == eWeight )
            {
                 nWeight = aFontWeightMap[i].nValue;
                 break;
            }
        }

        OUStringBuffer aOut;

        if( 400 == nWeight )
            aOut.append( GetXMLToken(XML_WEIGHT_NORMAL) );
        else if( 700 == nWeight )
            aOut.append( GetXMLToken(XML_WEIGHT_BOLD) );
        else
            SvXMLUnitConverter::convertNumber( aOut, (sal_Int32)nWeight );

        rStrExpValue = aOut.makeStringAndClear();
    }

    return bRet;
}

<commit_msg>INTEGRATION: CWS impresstables2 (1.8.46); FILE MERGED 2007/08/01 14:35:13 cl 1.8.46.2: RESYNC: (1.8-1.9); FILE MERGED 2007/07/27 09:09:54 cl 1.8.46.1: fixed build issues due to pch and namespace ::rtl<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: weighhdl.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-12 10:54:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_PROPERTYHANDLER_FONTWEIGHTTYPES_HXX
#include <weighhdl.hxx>
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif

#ifndef _VCL_VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

#ifndef _INC_LIMITS
#include <limits.h>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star::uno;
using namespace ::xmloff::token;

struct FontWeightMapper
{
    FontWeight eWeight;
    USHORT nValue;
};

FontWeightMapper const aFontWeightMap[] =
{
    { WEIGHT_DONTKNOW,              0 },
    { WEIGHT_THIN,                  100 },
    { WEIGHT_ULTRALIGHT,            150 },
    { WEIGHT_LIGHT,                 250 },
    { WEIGHT_SEMILIGHT,             350 },
    { WEIGHT_NORMAL,                400 },
    { WEIGHT_MEDIUM,                450 },
    { WEIGHT_SEMIBOLD,              600 },
    { WEIGHT_BOLD,                  700 },
    { WEIGHT_ULTRABOLD,             800 },
    { WEIGHT_BLACK,                 900 },
    { (FontWeight)USHRT_MAX,       1000 }
};

///////////////////////////////////////////////////////////////////////////////
//
// class XMLFmtBreakBeforePropHdl
//

XMLFontWeightPropHdl::~XMLFontWeightPropHdl()
{
    // Nothing to do
}

sal_Bool XMLFontWeightPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
{
    sal_Bool bRet = sal_False;
    sal_uInt16 nWeight = 0;

    if( IsXMLToken( rStrImpValue, XML_WEIGHT_NORMAL ) )
    {
        nWeight = 400;
        bRet = sal_True;
    }
    else if( IsXMLToken( rStrImpValue, XML_WEIGHT_BOLD ) )
    {
        nWeight = 700;
        bRet = sal_True;
    }
    else
    {
        sal_Int32 nTemp;
        bRet = SvXMLUnitConverter::convertNumber( nTemp, rStrImpValue, 100, 900 );
        if( bRet )
            nWeight = sal::static_int_cast< sal_uInt16 >(nTemp);
    }

    if( bRet )
    {
        bRet = sal_False;

        for( int i = 0; aFontWeightMap[i].eWeight != USHRT_MAX; i++ )
        {
            if( (nWeight >= aFontWeightMap[i].nValue) && (nWeight <= aFontWeightMap[i+1].nValue) )
            {
                sal_uInt16 nDiff1 = nWeight - aFontWeightMap[i].nValue;
                sal_uInt16 nDiff2 = aFontWeightMap[i+1].nValue - nWeight;

                if( nDiff1 < nDiff2 )
                    rValue <<= (float)( VCLUnoHelper::ConvertFontWeight( aFontWeightMap[i].eWeight ) );
                else
                    rValue <<= (float)( VCLUnoHelper::ConvertFontWeight( aFontWeightMap[i+1].eWeight ) );

                bRet = sal_True;
                break;
            }
        }
    }

    return bRet;
}

sal_Bool XMLFontWeightPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
{
    sal_Bool bRet = sal_False;
    FontWeight eWeight;

    float fValue = float();
    if( !( rValue >>= fValue ) )
    {
        sal_Int32 nValue = 0;
        if( rValue >>= nValue )
        {
            fValue = (float)nValue;
            bRet = sal_True;
        }
    }
    else
        bRet = sal_True;

    eWeight = VCLUnoHelper::ConvertFontWeight( fValue );

    if( bRet )
    {
        sal_uInt16 nWeight = 0;

        for( int i = 0; aFontWeightMap[i].eWeight != -1; i++ )
        {
            if( aFontWeightMap[i].eWeight == eWeight )
            {
                 nWeight = aFontWeightMap[i].nValue;
                 break;
            }
        }

        OUStringBuffer aOut;

        if( 400 == nWeight )
            aOut.append( GetXMLToken(XML_WEIGHT_NORMAL) );
        else if( 700 == nWeight )
            aOut.append( GetXMLToken(XML_WEIGHT_BOLD) );
        else
            SvXMLUnitConverter::convertNumber( aOut, (sal_Int32)nWeight );

        rStrExpValue = aOut.makeStringAndClear();
    }

    return bRet;
}

<|endoftext|>


<commit_before>#include "core/argparse.h"

#include "core/generator_maze.h"
#include "core/generator_cell.h"

#include "core/random.h"
#include "core/imageops.h"

#include "core/debug.h"

#include <iostream>

// later when doing floodfill
// #include "core/colorbrewer.h"

void maze(int world_width, int world_height, int cell_size, int wall_size, const std::string& output, bool console)
{
  auto random = Random {};
  auto maze = generator::Maze::FromWidthHeight(world_width, world_height);

  auto gen   = generator::RecursiveBacktracker{};
  gen.maze = &maze;
  gen.random = &random;
  gen.Setup();

  auto drawer = generator::Drawer {};
  drawer.maze = &maze;
  drawer.tracker = &gen;
  drawer.cell_size = cell_size;
  drawer.wall_size = wall_size;

  while(gen.HasMoreWork())
  {
    gen.Work();
  }

  drawer.Draw();

  if(!console)
  {
    debug::MemoryChunkToFile(drawer.image.Write(ImageWriteFormat::PNG), output);
  }

  if(console)
  {
    auto table = ImageToStringTable(drawer.image,
      {
        {'#', drawer.wall_color},
        {'/', drawer.cell_color},
        {' ', drawer.wall_color},
        {' ', drawer.cell_visited_color},
        {'O', drawer.unit_color}
      }
    );

    for(int r=0; r<table.Height(); r+=1)
    {
      for(int c=0; c<table.Width(); c+=1)
      {
        std::cout << table.Value(c, r);
      }
      std::cout << "\n";
    }
  }
}

void cell(int world_width, int world_height, const std::string& output)
{
  auto random = Random {};
  auto world = generator::World::FromWidthHeight(world_width, world_height);

  generator::CellularAutomata cell;
  cell.world = &world;
  cell.random = &random;
  cell.Setup();

  auto drawer = generator::CellularAutomataDrawer {};
  drawer.world = &world;

  while(cell.HasMoreWork())
  {
    cell.Work();
  }

  drawer.Draw();
  debug::MemoryChunkToFile(drawer.image.Write(ImageWriteFormat::PNG), output);
}

int main(int argc, char* argv[])
{
  auto parser = argparse::Parser{"Generate worlds"};

  int world_width = 10;
  int world_height = 10;
  std::string output = "maze.png";
  bool console = false;

  int cell_size = 1;
  int wall_size = 1;

  parser.AddSimple("--cell", cell_size).Help("set the cell size");
  parser.AddSimple("--wall", wall_size).Help("set the wall size");
  parser.AddSimple("--width", world_width).Help("set the height");
  parser.AddSimple("--height", world_height).Help("set the width");
  parser.AddSimple("-o", output).Help("specify output");
  parser.AddSimple("-c", console).Help("foce console");

  auto maze_command = [&]() {
    maze(world_width, world_height, cell_size, wall_size, output, console);
  };
  auto cell_command = [&]() {
    cell(world_width, world_height, output);
  };

  // todo: fix this setup
  // parser.AddSimpleFunction("-maze", maze_command);
  // parser.AddSimpleFunction("-cell", cell_command);

  std::string command;
  parser.AddSimple("command", command).Help("specify either cell or maze");

  auto status = parser.Parse(argc, argv);

  if(!status.error.empty())
  {
    std::cerr << status.error;
  }
  std::cout << status.out;

  if(command == "maze")
  {
    maze_command();
  }
  else if (command == "cell")
  {
    cell_command();
  }

  return 0;
}
<commit_msg>can output to sheet now<commit_after>#include "core/argparse.h"

#include "core/generator_maze.h"
#include "core/generator_cell.h"

#include "core/random.h"
#include "core/imageops.h"

#include "core/stringutils.h"
#include "core/debug.h"

#include <iostream>
#include <sstream>
#include <iomanip>

// later when doing floodfill
// #include "core/colorbrewer.h"

struct Output
{
  explicit Output(const std::string& o)
    : file(o)
    , single(!EndsWith(o, "/"))
  {
  }

  std::string NextFile()
  {
    std::ostringstream ss;
    index += 1;
    std::cout << "Generating " << index << "...\n";
    ss << file << std::setfill('0') << std::setw(5) << index << ".png";
    return ss.str();
  }

  std::string file;
  bool single;
  int index = 0;
};

void maze(int world_width, int world_height, int cell_size, int wall_size, const std::string& f, bool console)
{
  auto output = Output{f};
  auto random = Random {};
  auto maze = generator::Maze::FromWidthHeight(world_width, world_height);

  auto gen   = generator::RecursiveBacktracker{};
  gen.maze = &maze;
  gen.random = &random;
  gen.Setup();

  auto drawer = generator::Drawer {};
  drawer.maze = &maze;
  drawer.tracker = &gen;
  drawer.cell_size = cell_size;
  drawer.wall_size = wall_size;

  if(!output.single)
  {
    drawer.Draw();
    debug::MemoryChunkToFile(drawer.image.Write(ImageWriteFormat::PNG), output.NextFile());
  }

  while(gen.HasMoreWork())
  {
    gen.Work();

    if(!output.single)
    {
      drawer.Draw();
      debug::MemoryChunkToFile(drawer.image.Write(ImageWriteFormat::PNG), output.NextFile());
    }
  }

  drawer.Draw();

  if(!console && output.single)
  {
    debug::MemoryChunkToFile(drawer.image.Write(ImageWriteFormat::PNG), output.file);
  }

  if(console)
  {
    auto table = ImageToStringTable(drawer.image,
      {
        {'#', drawer.wall_color},
        {'/', drawer.cell_color},
        {' ', drawer.wall_color},
        {' ', drawer.cell_visited_color},
        {'O', drawer.unit_color}
      }
    );

    for(int r=0; r<table.Height(); r+=1)
    {
      for(int c=0; c<table.Width(); c+=1)
      {
        std::cout << table.Value(c, r);
      }
      std::cout << "\n";
    }
  }
}

void cell(int world_width, int world_height, const std::string& output)
{
  auto random = Random {};
  auto world = generator::World::FromWidthHeight(world_width, world_height);

  generator::CellularAutomata cell;
  cell.world = &world;
  cell.random = &random;
  cell.Setup();

  auto drawer = generator::CellularAutomataDrawer {};
  drawer.world = &world;

  while(cell.HasMoreWork())
  {
    cell.Work();
  }

  drawer.Draw();
  debug::MemoryChunkToFile(drawer.image.Write(ImageWriteFormat::PNG), output);
}

int main(int argc, char* argv[])
{
  auto parser = argparse::Parser{"Generate worlds"};

  int world_width = 10;
  int world_height = 10;
  std::string output = "maze.png";
  bool console = false;

  int cell_size = 1;
  int wall_size = 1;

  parser.AddSimple("--cell", cell_size).Help("set the cell size");
  parser.AddSimple("--wall", wall_size).Help("set the wall size");
  parser.AddSimple("--width", world_width).Help("set the height");
  parser.AddSimple("--height", world_height).Help("set the width");
  parser.AddSimple("-o", output).Help("specify output");
  parser.AddSimple("-c", console).Help("foce console");

  auto maze_command = [&]() {
    maze(world_width, world_height, cell_size, wall_size, output, console);
  };
  auto cell_command = [&]() {
    cell(world_width, world_height, output);
  };

  // todo: fix this setup
  // parser.AddSimpleFunction("-maze", maze_command);
  // parser.AddSimpleFunction("-cell", cell_command);

  std::string command;
  parser.AddSimple("command", command).Help("specify either cell or maze");

  auto status = parser.Parse(argc, argv);

  if(!status.error.empty())
  {
    std::cerr << status.error;
  }
  std::cout << status.out;

  if(command == "maze")
  {
    maze_command();
  }
  else if (command == "cell")
  {
    cell_command();
  }

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <deque>
#include <vector>
#include "enum_set.hh"
#include "service/pager/paging_state.hh"
#include "schema.hh"

namespace cql3 {

class metadata {
public:
    enum class flag : uint8_t {
        GLOBAL_TABLES_SPEC,
        HAS_MORE_PAGES,
        NO_METADATA
    };

    using flag_enum = super_enum<flag,
        flag::GLOBAL_TABLES_SPEC,
        flag::HAS_MORE_PAGES,
        flag::NO_METADATA>;

    using flag_enum_set = enum_set<flag_enum>;

private:
    flag_enum_set _flags;

public:
    // Please note that columnCount can actually be smaller than names, even if names is not null. This is
    // used to include columns in the resultSet that we need to do post-query re-orderings
    // (SelectStatement.orderResults) but that shouldn't be sent to the user as they haven't been requested
    // (CASSANDRA-4911). So the serialization code will exclude any columns in name whose index is >= columnCount.
    std::vector<::shared_ptr<column_specification>> names;

private:
    const uint32_t _column_count;
    ::shared_ptr<const service::pager::paging_state> _paging_state;

public:
    metadata(std::vector<::shared_ptr<column_specification>> names_);

    metadata(flag_enum_set flags, std::vector<::shared_ptr<column_specification>> names_, uint32_t column_count,
            ::shared_ptr<const service::pager::paging_state> paging_state);

    // The maximum number of values that the ResultSet can hold. This can be bigger than columnCount due to CASSANDRA-4911
    uint32_t value_count();

    void add_non_serialized_column(::shared_ptr<column_specification> name);

private:
    bool all_in_same_cf() const;

public:
    void set_has_more_pages(::shared_ptr<const service::pager::paging_state> paging_state);

    void set_skip_metadata();

    flag_enum_set flags() const;

    uint32_t column_count() const;

    ::shared_ptr<const service::pager::paging_state> paging_state() const;

    const std::vector<::shared_ptr<column_specification>>& get_names() const;
};

inline ::shared_ptr<cql3::metadata> make_empty_metadata()
{
    auto result = ::make_shared<cql3::metadata>(std::vector<::shared_ptr<cql3::column_specification>>{});
    result->set_skip_metadata();
    return result;
}

class prepared_metadata {
public:
    enum class flag : uint8_t {
        GLOBAL_TABLES_SPEC,
    };

    using flag_enum = super_enum<flag,
        flag::GLOBAL_TABLES_SPEC>;

    using flag_enum_set = enum_set<flag_enum>;
private:
    flag_enum_set _flags;
    std::vector<::shared_ptr<column_specification>> _names;
    std::vector<uint16_t> _partition_key_bind_indices;
public:
    prepared_metadata(const std::vector<::shared_ptr<column_specification>>& names,
                      const std::vector<uint16_t>& partition_key_bind_indices);

    flag_enum_set flags() const;
    const std::vector<::shared_ptr<column_specification>> names() const;
    const std::vector<uint16_t> partition_key_bind_indices() const;
};

class result_set {
public:
    ::shared_ptr<metadata> _metadata;
    std::deque<std::vector<bytes_opt>> _rows;
public:
    result_set(std::vector<::shared_ptr<column_specification>> metadata_);

    result_set(::shared_ptr<metadata> metadata);

    size_t size() const;

    bool empty() const;

    void add_row(std::vector<bytes_opt> row);

    void add_column_value(bytes_opt value);

    void reverse();

    void trim(size_t limit);

    template<typename RowComparator>
    void sort(RowComparator&& cmp) {
        std::sort(_rows.begin(), _rows.end(), std::forward<RowComparator>(cmp));
    }

    metadata& get_metadata();

    const metadata& get_metadata() const;

    // Returns a range of rows. A row is a range of bytes_opt.
    const std::deque<std::vector<bytes_opt>>& rows() const;
};

}
<commit_msg>cql3: Specify result set flag ABI explicitly<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <deque>
#include <vector>
#include "enum_set.hh"
#include "service/pager/paging_state.hh"
#include "schema.hh"

namespace cql3 {

class metadata {
public:
    enum class flag : uint8_t {
        GLOBAL_TABLES_SPEC = 0,
        HAS_MORE_PAGES = 1,
        NO_METADATA = 2,
    };

    using flag_enum = super_enum<flag,
        flag::GLOBAL_TABLES_SPEC,
        flag::HAS_MORE_PAGES,
        flag::NO_METADATA>;

    using flag_enum_set = enum_set<flag_enum>;

private:
    flag_enum_set _flags;

public:
    // Please note that columnCount can actually be smaller than names, even if names is not null. This is
    // used to include columns in the resultSet that we need to do post-query re-orderings
    // (SelectStatement.orderResults) but that shouldn't be sent to the user as they haven't been requested
    // (CASSANDRA-4911). So the serialization code will exclude any columns in name whose index is >= columnCount.
    std::vector<::shared_ptr<column_specification>> names;

private:
    const uint32_t _column_count;
    ::shared_ptr<const service::pager::paging_state> _paging_state;

public:
    metadata(std::vector<::shared_ptr<column_specification>> names_);

    metadata(flag_enum_set flags, std::vector<::shared_ptr<column_specification>> names_, uint32_t column_count,
            ::shared_ptr<const service::pager::paging_state> paging_state);

    // The maximum number of values that the ResultSet can hold. This can be bigger than columnCount due to CASSANDRA-4911
    uint32_t value_count();

    void add_non_serialized_column(::shared_ptr<column_specification> name);

private:
    bool all_in_same_cf() const;

public:
    void set_has_more_pages(::shared_ptr<const service::pager::paging_state> paging_state);

    void set_skip_metadata();

    flag_enum_set flags() const;

    uint32_t column_count() const;

    ::shared_ptr<const service::pager::paging_state> paging_state() const;

    const std::vector<::shared_ptr<column_specification>>& get_names() const;
};

inline ::shared_ptr<cql3::metadata> make_empty_metadata()
{
    auto result = ::make_shared<cql3::metadata>(std::vector<::shared_ptr<cql3::column_specification>>{});
    result->set_skip_metadata();
    return result;
}

class prepared_metadata {
public:
    enum class flag : uint8_t {
        GLOBAL_TABLES_SPEC = 0,
    };

    using flag_enum = super_enum<flag,
        flag::GLOBAL_TABLES_SPEC>;

    using flag_enum_set = enum_set<flag_enum>;
private:
    flag_enum_set _flags;
    std::vector<::shared_ptr<column_specification>> _names;
    std::vector<uint16_t> _partition_key_bind_indices;
public:
    prepared_metadata(const std::vector<::shared_ptr<column_specification>>& names,
                      const std::vector<uint16_t>& partition_key_bind_indices);

    flag_enum_set flags() const;
    const std::vector<::shared_ptr<column_specification>> names() const;
    const std::vector<uint16_t> partition_key_bind_indices() const;
};

class result_set {
public:
    ::shared_ptr<metadata> _metadata;
    std::deque<std::vector<bytes_opt>> _rows;
public:
    result_set(std::vector<::shared_ptr<column_specification>> metadata_);

    result_set(::shared_ptr<metadata> metadata);

    size_t size() const;

    bool empty() const;

    void add_row(std::vector<bytes_opt> row);

    void add_column_value(bytes_opt value);

    void reverse();

    void trim(size_t limit);

    template<typename RowComparator>
    void sort(RowComparator&& cmp) {
        std::sort(_rows.begin(), _rows.end(), std::forward<RowComparator>(cmp));
    }

    metadata& get_metadata();

    const metadata& get_metadata() const;

    // Returns a range of rows. A row is a range of bytes_opt.
    const std::deque<std::vector<bytes_opt>>& rows() const;
};

}
<|endoftext|>


<commit_before>/**
\file ll_table.hpp
\brief Defines class LLTable and its methods.
\author Radek Vít
*/
#ifndef CTF_LL_TABLE_H
#define CTF_LL_TABLE_H

#include <stdexcept>
#include <utility>

#include "translation_grammar.hpp"

namespace ctf {
/**
\brief Class containing rule indices to be used in a LL controlled translation.
*/
class LLTable {
 public:
  /**
  \brief Type of cells.
  */
  using cell = size_t;
  /**
  \brief Type of rows.
  */
  using row = vector<cell>;

 protected:
  /**
  \brief Table storing rule indices. 2D array mapped to 1D array.
  */
  row table_;
  /**
  \brief Mapping nonterminals to indices to table_.
  */
  map<Symbol, size_t> nonterminalMap_;
  /**
  \brief Mapping terminals to indices to table_ rows.
  */
  map<Symbol, size_t> terminalMap_;
  /**
  \brief Stores invalid rule index.
  */
  size_t invalidRuleIndex_;
  /**
  \brief Maps 2D indices to 1D indices.
  */
  size_t index(size_t y, size_t x) const { return terminalMap_.size() * y + x; }

 public:
  /**
  \brief Constructs an empty LL table.
  */
  LLTable() = default;
  /**
  \brief Constructs a LLtable from a translation grammar and a predict set.

  \param[in] tg TranslationGrammar. Terminals and Nonterminals are mapped to
  their respective indices. Rule indices are stored in LLTable.
  \param[in] predict Predict set for table construction.
  */
  LLTable(const TranslationGrammar &tg, const vector<vector<Symbol>> &predict)
      : table_(tg.nonterminals().size() * (tg.terminals().size() + 1),
               tg.rules().size()),
        invalidRuleIndex_(tg.rules().size()) {
    if (predict.size() != tg.rules().size())
      throw std::invalid_argument(
          "Mismatched predict and TranslationGrammar.rules "
          "sizes when constructing LLTable.");

    // create index maps for terminals and nonterminals
    for (size_t i = 0; i < tg.nonterminals().size(); ++i) {
      nonterminalMap_.insert(std::make_pair(tg.nonterminals()[i], i));
    }
    for (size_t i = 0; i < tg.terminals().size(); ++i) {
      terminalMap_.insert(std::make_pair(tg.terminals()[i], i));
    }
    terminalMap_.insert(std::make_pair(Symbol::eof(), tg.terminals().size()));

    /* fill table */
    for (size_t i = 0; i < tg.rules().size(); ++i) {
      auto &terminals = predict[i];
      // TranslationGrammar requires this to be always found
      size_t ni = nonterminalMap_.at(tg.rules()[i].nonterminal());

      for (auto &t : terminals) {
        auto tit = terminalMap_.find(t);
        if (tit == terminalMap_.end())
          throw std::invalid_argument(
              "Terminal in predict not a terminal in translation grammar when "
              "constructing LLTable.");

        size_t ti = tit->second;
        // a rule is already present
        if (table_[index(ni, ti)] != invalidRuleIndex_) {
          throw std::invalid_argument(
              "Constructing LLTable from a non-LL TranslationGrammar.");
        }
        table_[index(ni, terminalMap_.at(t))] = i;
      }  // for all terminals
    }    // for all i
  }
  /**
  \brief Returns an index of the rule to be used when t is the current token
  and nt is at the top of input stack.

  \param[in] nt Nonterminal on the top of the stack.
  \param[in] t Last read terminal.

  \returns Index of the applicable rule or invalid rule index.

  If no rule is applicable, returns the index beyond the last rule.
  */
  size_t rule_index(const Symbol &nt, const Symbol &t) noexcept {
    // iterator to nonterminal index
    auto ntit = nonterminalMap_.find(nt);
    // iterator to terminal index;
    auto tit = terminalMap_.find(t);
    // either of the arguments not found
    if (ntit == nonterminalMap_.end() || tit == terminalMap_.end())
      return invalidRuleIndex_;
    // returning from LL table
    return table_[index(ntit->second, tit->second)];
  }
};
}  // namespace ctf

#endif
/*** End of file ll_table.hpp ***/<commit_msg>modified ll table<commit_after>/**
\file ll_table.hpp
\brief Defines class LLTable and its methods.
\author Radek Vít
*/
#ifndef CTF_LL_TABLE_H
#define CTF_LL_TABLE_H

#include <algorithm>
#include <stdexcept>
#include <utility>

#include "translation_grammar.hpp"

namespace ctf {

template <typename T>
class DecisionTable {
 public:
  /**
  \brief Type of cells.
  */
  using cell = T;
  /**
  \brief Type of rows.
  */
  using row = vector<cell>;

 protected:
  /**
  \brief Table storing rule indices. 2D array mapped to 1D array.
  */
  row table_;
  /**
  \brief Mapping nonterminals to table_ indices.
  */
  map<Symbol, size_t> nonterminalMap_;
  /**
  \brief Mapping terminals to table_ row indices.
  */
  map<Symbol, size_t> terminalMap_;
  /**
  \brief Stores invalid value.
  */
  cell invalid_;
  /**
  \brief Maps 2D indices to 1D indices.
  */
  size_t index(size_t y, size_t x) const { return terminalMap_.size() * y + x; }

  virtual void initialize_invalid(const TranslationGrammar &) { return; }

  virtual void insert_rule(const size_t insertedRule, const size_t i) {
    table_[i] = {insertedRule};
  }

  void initialize() {}

  void initialize(const TranslationGrammar &tg,
                  const vector<vector<Symbol>> &predict) {
    initialize_invalid(tg);
    table_ =
        row(tg.nonterminals().size() * (tg.terminals().size() + 1), invalid_);
    if (predict.size() != tg.rules().size())
      throw std::invalid_argument(
          "Mismatched predict and TranslationGrammar.rules "
          "sizes when constructing a decision table.");

    // create index maps for terminals and nonterminals
    for (size_t i = 0; i < tg.nonterminals().size(); ++i) {
      nonterminalMap_.insert(std::make_pair(tg.nonterminals()[i], i));
    }
    for (size_t i = 0; i < tg.terminals().size(); ++i) {
      terminalMap_.insert(std::make_pair(tg.terminals()[i], i));
    }
    terminalMap_.insert(std::make_pair(Symbol::eof(), tg.terminals().size()));

    /* fill table */
    for (size_t i = 0; i < tg.rules().size(); ++i) {
      auto &terminals = predict[i];
      // TranslationGrammar requires this to be always found
      size_t ni = nonterminalMap_.at(tg.rules()[i].nonterminal());

      for (auto &t : terminals) {
        auto tit = terminalMap_.find(t);
        if (tit == terminalMap_.end())
          throw std::invalid_argument(
              "Terminal in predict not a terminal in translation grammar when "
              "constructing a decision table.");

        size_t ti = tit->second;
        insert_rule(i, index(ni, ti));
      }  // for all terminals
    }    // for all i
  }

 public:
  /**
  \brief Constructs an empty LL table.
  */
  DecisionTable() = default;
  /**
  \brief Constructs a decision table from a translation grammar and a predict
  set.

  \param[in] tg TranslationGrammar. Terminals and Nonterminals are mapped to
  their respective indices. Rule indices are stored in the decision table.
  \param[in] predict Predict set for table construction.
  */
  DecisionTable(const TranslationGrammar &tg,
                const vector<vector<Symbol>> &predict) {
    initialize(tg, predict);
  }
  /**
  \brief Returns an index of the rule to be used when t is the current token
  and nt is at the top of input stack.

  \param[in] nt Nonterminal on the top of the stack.
  \param[in] t Last read terminal.

  \returns Index of the applicable rule or invalid rule index.

  If no rule is applicable, returns the index beyond the last rule.
  */
  size_t rule_index(const Symbol &nt, const Symbol &t) noexcept {
    // iterator to nonterminal index
    auto ntit = nonterminalMap_.find(nt);
    // iterator to terminal index;
    auto tit = terminalMap_.find(t);
    // either of the arguments not found
    if (ntit == nonterminalMap_.end() || tit == terminalMap_.end())
      return invalid_;
    // returning from LL table
    return table_[index(ntit->second, tit->second)];
  }
};

/**
\brief Class containing rule indices to be used in a LL controlled translation.
*/
class LLTable : public DecisionTable<size_t> {
  void initialize_invalid(const TranslationGrammar &tg) override {
    invalid_ = tg.rules().size();
  }

  void insert_rule(const size_t insertedRule, const size_t i) override {
    // a rule is already present
    if (table_[i] != invalid_) {
      throw std::invalid_argument(
          "Constructing LLTable from a non-LL TranslationGrammar.");
    }
    table_[i] = insertedRule;
  }

 public:
  LLTable(const TranslationGrammar &tg, const vector<vector<Symbol>> &predict) {
    initialize(tg, predict);
  }

  LLTable() { invalid_ = 0; };
};

class GeneralLLTable : public DecisionTable<vector<size_t>> {
  void insert_rule(const size_t insertedRule, const size_t i) override {
    cell inserted{insertedRule};
    cell newTable{};
    std::set_union(table_[i].begin(), table_[i].end(), inserted.begin(),
                   inserted.end(), std::back_inserter(newTable));
    std::swap(table_[i], newTable);
  }

  void initialize_invalid(const TranslationGrammar &) override {
    invalid_ = {};
  }

 public:
  GeneralLLTable(const TranslationGrammar &tg,
                 const vector<vector<Symbol>> &predict) {
    initialize(tg, predict);
  }

  GeneralLLTable() { initialize(); };
};
}  // namespace ctf

#endif
/*** End of file ll_table.hpp ***/<|endoftext|>