more styling
This commit is contained in:
parent
d75712816e
commit
5f4032eca0
21 changed files with 4580 additions and 5033 deletions
|
@ -21,7 +21,7 @@ Attractor::Attractor(const std::string& filename) : kernel(0), projector(0) {
|
||||||
projector = Projector::createProjector(system.getChild(system.getValue("Projector")), system);
|
projector = Projector::createProjector(system.getChild(system.getValue("Projector")), system);
|
||||||
}
|
}
|
||||||
|
|
||||||
Attractor::~Attractor(){
|
Attractor::~Attractor() {
|
||||||
delete kernel;
|
delete kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ Attractor::~Attractor(){
|
||||||
// this should probably done in the projector section
|
// this should probably done in the projector section
|
||||||
void Attractor::init_range() {
|
void Attractor::init_range() {
|
||||||
// stabilize attractor
|
// stabilize attractor
|
||||||
for ( unsigned int i = 0; i < 100000; i++ ) {
|
for(unsigned int i = 0; i < 100000; i++) {
|
||||||
iterate();
|
iterate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,22 +41,22 @@ bool Attractor::is_chaos() {
|
||||||
Single point attractor
|
Single point attractor
|
||||||
Lyapunov exponent
|
Lyapunov exponent
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
for ( unsigned int i = 0; i < dim; i++ ) {
|
for ( unsigned int i = 0; i < dim; i++ ) {
|
||||||
const double dist = 0; //new_point[i] - point[i];
|
const double dist = 0; //new_point[i] - point[i];
|
||||||
sum += dist*dist;
|
sum += dist*dist;
|
||||||
}
|
}
|
||||||
if ( sum >= 1.0e7 ) {
|
if ( sum >= 1.0e7 ) {
|
||||||
// big change => Escaping
|
// big change => Escaping
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( sum <= 1.0e-7 ) {
|
if ( sum <= 1.0e-7 ) {
|
||||||
// small change => singularity
|
// small change => singularity
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
*/
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ void Attractor::iterate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attractor::plot() {
|
void Attractor::plot() {
|
||||||
const double * point = kernel->vector();
|
const double* point = kernel->vector();
|
||||||
projector->plot(point);
|
projector->plot(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +75,9 @@ void Attractor::plot() {
|
||||||
*/
|
*/
|
||||||
void Attractor::output() {
|
void Attractor::output() {
|
||||||
const unsigned int dimension = kernel->getDimension();
|
const unsigned int dimension = kernel->getDimension();
|
||||||
const double * point = kernel->vector();
|
const double* point = kernel->vector();
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < dimension; i++ ) {
|
for(unsigned int i = 0; i < dimension; i++) {
|
||||||
LogMoreInfo("%f, ", point[i]);
|
LogMoreInfo("%f, ", point[i]);
|
||||||
}
|
}
|
||||||
LogMoreInfo("\n");
|
LogMoreInfo("\n");
|
||||||
|
|
|
@ -10,7 +10,7 @@ class AttractorKernel;
|
||||||
class Attractor {
|
class Attractor {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AttractorKernel * kernel;
|
AttractorKernel* kernel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
#pragma mark memory
|
#pragma mark memory
|
||||||
|
|
||||||
AttractorKernel::AttractorKernel(const unsigned int dimension, const unsigned int numberOfParameters) :
|
AttractorKernel::AttractorKernel(const unsigned int dimension, const unsigned int numberOfParameters) :
|
||||||
numberOfParameters(numberOfParameters), dimension(dimension){
|
numberOfParameters(numberOfParameters), dimension(dimension) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
allocate();
|
allocate();
|
||||||
} catch (std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
LogError("Couldn't construct Attractorkernel: %s\n", e.what());
|
LogError("Couldn't construct Attractorkernel: %s\n", e.what());
|
||||||
dealloc();
|
dealloc();
|
||||||
}
|
}
|
||||||
|
@ -30,17 +30,17 @@ numberOfParameters(numberOfParameters), dimension(dimension){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AttractorKernel::~AttractorKernel(){
|
AttractorKernel::~AttractorKernel() {
|
||||||
dealloc();
|
dealloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttractorKernel::allocate(){
|
void AttractorKernel::allocate() {
|
||||||
parameters = new double[numberOfParameters];
|
parameters = new double[numberOfParameters];
|
||||||
vectorNew = new double[dimension];
|
vectorNew = new double[dimension];
|
||||||
vectorOld = new double[dimension];
|
vectorOld = new double[dimension];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttractorKernel::dealloc(){
|
void AttractorKernel::dealloc() {
|
||||||
delete[] vectorOld;
|
delete[] vectorOld;
|
||||||
vectorOld = NULL;
|
vectorOld = NULL;
|
||||||
delete[] vectorNew;
|
delete[] vectorNew;
|
||||||
|
@ -54,30 +54,30 @@ void AttractorKernel::dealloc(){
|
||||||
|
|
||||||
// NOTE: inlining these functions (with the keyword inline) improves performance by at most 1% (tested)
|
// NOTE: inlining these functions (with the keyword inline) improves performance by at most 1% (tested)
|
||||||
|
|
||||||
double & AttractorKernel::operator[](const unsigned int index){
|
double& AttractorKernel::operator[](const unsigned int index) {
|
||||||
return parameters[index];
|
return parameters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
double const & AttractorKernel::operator[](const unsigned int index) const{
|
double const& AttractorKernel::operator[](const unsigned int index) const {
|
||||||
return parameters[index];
|
return parameters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int AttractorKernel::getNumberOfParameters() const{
|
unsigned int AttractorKernel::getNumberOfParameters() const {
|
||||||
return numberOfParameters;
|
return numberOfParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark vector
|
#pragma mark vector
|
||||||
|
|
||||||
double const * AttractorKernel::vector() const{
|
double const* AttractorKernel::vector() const {
|
||||||
return vectorNew;
|
return vectorNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
double const * AttractorKernel::previousVector() const{
|
double const* AttractorKernel::previousVector() const {
|
||||||
return vectorOld;
|
return vectorOld;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int AttractorKernel::getDimension() const{
|
unsigned int AttractorKernel::getDimension() const {
|
||||||
return dimension;
|
return dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ unsigned int AttractorKernel::getDimension() const{
|
||||||
#include "kernels/PolynomialA3D.hpp"
|
#include "kernels/PolynomialA3D.hpp"
|
||||||
#include "kernels/Unravel3D.hpp"
|
#include "kernels/Unravel3D.hpp"
|
||||||
|
|
||||||
AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
|
AttractorKernel* AttractorKernel::createAttractorKernel(stfu::node& attractor) {
|
||||||
|
|
||||||
AttractorKernel * myAttractor = NULL;
|
AttractorKernel* myAttractor = NULL;
|
||||||
|
|
||||||
// reading basic stuff
|
// reading basic stuff
|
||||||
const std::string attractorType = attractor.getValue("type");
|
const std::string attractorType = attractor.getValue("type");
|
||||||
|
@ -108,30 +108,30 @@ AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
|
||||||
|
|
||||||
|
|
||||||
// depending on type, make the formula object
|
// depending on type, make the formula object
|
||||||
if ( attractorType == "lorenz" ){
|
if(attractorType == "lorenz") {
|
||||||
if ( dimension == 3 ) {
|
if(dimension == 3) {
|
||||||
myAttractor = new Lorenz3D();
|
myAttractor = new Lorenz3D();
|
||||||
} else {
|
} else {
|
||||||
LogError("something wrong\n");
|
LogError("something wrong\n");
|
||||||
exit(37);
|
exit(37);
|
||||||
}
|
}
|
||||||
} else if ( attractorType == "polynomial" ) {
|
} else if(attractorType == "polynomial") {
|
||||||
const std::string attractorOrde = attractor.getValue("orde");
|
const std::string attractorOrde = attractor.getValue("orde");
|
||||||
const unsigned int orde = atoi(attractorOrde.c_str());
|
const unsigned int orde = atoi(attractorOrde.c_str());
|
||||||
LogMoreInfo(" Orde: %d\n", orde);
|
LogMoreInfo(" Orde: %d\n", orde);
|
||||||
myAttractor = new Polynomial(dimension, orde);
|
myAttractor = new Polynomial(dimension, orde);
|
||||||
|
|
||||||
} else if ( attractorType == "polynomial a" ) {
|
} else if(attractorType == "polynomial a") {
|
||||||
if ( dimension == 3 ) {
|
if(dimension == 3) {
|
||||||
myAttractor = new PolynomialA3D();
|
myAttractor = new PolynomialA3D();
|
||||||
} else {
|
} else {
|
||||||
LogError("something wrong\n");
|
LogError("something wrong\n");
|
||||||
exit(37);
|
exit(37);
|
||||||
}
|
}
|
||||||
} else if ( attractorType == "logistic" ) {
|
} else if(attractorType == "logistic") {
|
||||||
myAttractor = new Logistic(dimension);
|
myAttractor = new Logistic(dimension);
|
||||||
} else if ( attractorType == "unravel" ) {
|
} else if(attractorType == "unravel") {
|
||||||
if ( dimension == 3 ) {
|
if(dimension == 3) {
|
||||||
myAttractor = new Unravel3D();
|
myAttractor = new Unravel3D();
|
||||||
} else {
|
} else {
|
||||||
LogError("something wrong\n");
|
LogError("something wrong\n");
|
||||||
|
@ -146,7 +146,7 @@ AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
|
||||||
// read parameters
|
// read parameters
|
||||||
const unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
|
const unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < numberOfParameters; i++ ) {
|
for(unsigned int i = 0; i < numberOfParameters; i++) {
|
||||||
stfu::node attractorParameters = attractor.getChild("parameters");
|
stfu::node attractorParameters = attractor.getChild("parameters");
|
||||||
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
|
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
|
||||||
LogMoreInfo(" Parameter %d set to %f, ", i, (*myAttractor)[i]);
|
LogMoreInfo(" Parameter %d set to %f, ", i, (*myAttractor)[i]);
|
||||||
|
|
|
@ -13,9 +13,9 @@ protected:
|
||||||
|
|
||||||
// biggest type first, this will reduce sizeof(AttractorKernel)
|
// biggest type first, this will reduce sizeof(AttractorKernel)
|
||||||
// size is now 40 (when the unsigned int are in front, it was 48)
|
// size is now 40 (when the unsigned int are in front, it was 48)
|
||||||
double * parameters;
|
double* parameters;
|
||||||
double * vectorNew;
|
double* vectorNew;
|
||||||
double * vectorOld;
|
double* vectorOld;
|
||||||
|
|
||||||
unsigned int numberOfParameters;
|
unsigned int numberOfParameters;
|
||||||
unsigned int dimension;
|
unsigned int dimension;
|
||||||
|
@ -26,23 +26,23 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// parameters are stored in a array of doubles
|
// parameters are stored in a array of doubles
|
||||||
double & operator[](const unsigned int index);
|
double& operator[](const unsigned int index);
|
||||||
double const & operator[](const unsigned int index) const;
|
double const& operator[](const unsigned int index) const;
|
||||||
unsigned int getNumberOfParameters() const;
|
unsigned int getNumberOfParameters() const;
|
||||||
|
|
||||||
// iterate his formula, implemented by subclasses
|
// iterate his formula, implemented by subclasses
|
||||||
virtual void operator()() = 0;
|
virtual void operator()() = 0;
|
||||||
|
|
||||||
// getter functions for teh resulta (can't be used as setters)
|
// getter functions for teh resulta (can't be used as setters)
|
||||||
double const * vector() const;
|
double const* vector() const;
|
||||||
double const * previousVector() const;
|
double const* previousVector() const;
|
||||||
unsigned int getDimension() const;
|
unsigned int getDimension() const;
|
||||||
|
|
||||||
// dtor, should be virtual for subclasses to be deleted
|
// dtor, should be virtual for subclasses to be deleted
|
||||||
virtual ~AttractorKernel();
|
virtual ~AttractorKernel();
|
||||||
|
|
||||||
// factory function
|
// factory function
|
||||||
static AttractorKernel * createAttractorKernel(stfu::node& attractorKernel);
|
static AttractorKernel* createAttractorKernel(stfu::node& attractorKernel);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#include "Canvas.hpp"
|
#include "Canvas.hpp"
|
||||||
|
|
||||||
// lol
|
// lol
|
||||||
|
|
44
Canvas.hpp
44
Canvas.hpp
|
@ -1,22 +1,22 @@
|
||||||
#ifndef CANVAS_HPP
|
#ifndef CANVAS_HPP
|
||||||
#define CANVAS_HPP
|
#define CANVAS_HPP
|
||||||
|
|
||||||
|
|
||||||
class Canvas {
|
class Canvas {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
unsigned int dimension;
|
unsigned int dimension;
|
||||||
Canvas (const unsigned int dimension) : dimension (dimension) {};
|
Canvas(const unsigned int dimension) : dimension(dimension) {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
unsigned int getDimension() const { return dimension; };
|
unsigned int getDimension() const { return dimension; };
|
||||||
|
|
||||||
virtual ~Canvas() {};
|
virtual ~Canvas() {};
|
||||||
|
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
virtual void plot (const double * normalizedPosition) = 0;
|
virtual void plot(const double* normalizedPosition) = 0;
|
||||||
virtual void output_file (const char * filename) const = 0;
|
virtual void output_file(const char* filename) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CANVAS_HPP
|
#endif // CANVAS_HPP
|
||||||
|
|
12
Logger.hpp
12
Logger.hpp
|
@ -1,8 +1,8 @@
|
||||||
#ifndef LOGGER_HPP_INCLUDED
|
#ifndef LOGGER_HPP_INCLUDED
|
||||||
#define LOGGER_HPP_INCLUDED
|
#define LOGGER_HPP_INCLUDED
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
extern int verbose;
|
extern int verbose;
|
||||||
|
|
||||||
#define LogDebug(s, ...) \
|
#define LogDebug(s, ...) \
|
||||||
|
@ -17,6 +17,6 @@ extern int verbose;
|
||||||
#define LogError(s, ...) \
|
#define LogError(s, ...) \
|
||||||
if ( verbose >= 0 ) { printf("%s, %d: ", __FILE__, __LINE__); printf(s, ##__VA_ARGS__); }
|
if ( verbose >= 0 ) { printf("%s, %d: ", __FILE__, __LINE__); printf(s, ##__VA_ARGS__); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // LOGGER_HPP_INCLUDED
|
#endif // LOGGER_HPP_INCLUDED
|
||||||
|
|
|
@ -18,7 +18,7 @@ Projector::Projector(unsigned int inputDimension, unsigned int outputDimension)
|
||||||
std::fill_n(projectedPoint, outputDimension, 0.0);
|
std::fill_n(projectedPoint, outputDimension, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Projector::~Projector(){
|
Projector::~Projector() {
|
||||||
deallocate();
|
deallocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
defines.hpp
15
defines.hpp
|
@ -1,13 +1,12 @@
|
||||||
|
|
||||||
#define DEFAULT_ATTRACTOR_FILE "attractors/testUnravel.stf"
|
#define DEFAULT_ATTRACTOR_FILE "attractors/testUnravel.stf"
|
||||||
|
|
||||||
#ifdef UNI_BUILD
|
#ifdef UNI_BUILD
|
||||||
#warning Building for the RU, are you sure?
|
#warning Building for the RU, are you sure?
|
||||||
#define DEFAULT_WIDTH 8000
|
#define DEFAULT_WIDTH 8000
|
||||||
#define DEFAULT_HEIGHT 8000
|
#define DEFAULT_HEIGHT 8000
|
||||||
#define DEFAULT_ITERATIONS 4200000000
|
#define DEFAULT_ITERATIONS 4200000000
|
||||||
#else
|
#else
|
||||||
#define DEFAULT_WIDTH 800
|
#define DEFAULT_WIDTH 800
|
||||||
#define DEFAULT_HEIGHT 800
|
#define DEFAULT_HEIGHT 800
|
||||||
#define DEFAULT_ITERATIONS 1000000
|
#define DEFAULT_ITERATIONS 1000000
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,7 +36,7 @@ void Logistic::init() {
|
||||||
void Logistic::operator()() {
|
void Logistic::operator()() {
|
||||||
std::swap(vectorNew, vectorOld);
|
std::swap(vectorNew, vectorOld);
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < dimension; i++ ) {
|
for(unsigned int i = 0; i < dimension; i++) {
|
||||||
vectorNew[i] = parameters[i]*vectorOld[i]*(1.0 - vectorOld[i]);
|
vectorNew[i] = parameters[i]*vectorOld[i]*(1.0 - vectorOld[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#pragma mark ctors
|
#pragma mark ctors
|
||||||
|
|
||||||
Lorenz3D::Lorenz3D():
|
Lorenz3D::Lorenz3D():
|
||||||
AttractorKernel(3, 4){
|
AttractorKernel(3, 4) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
unsigned int calculateNumberOfParameters(const unsigned int dimension, const unsigned int orde) {
|
unsigned int calculateNumberOfParameters(const unsigned int dimension, const unsigned int orde) {
|
||||||
double n_coef = orde + 1;
|
double n_coef = orde + 1;
|
||||||
for (unsigned int i = 2; i <= dimension; i++) {
|
for(unsigned int i = 2; i <= dimension; i++) {
|
||||||
n_coef = n_coef*(orde + i)/(i - 1);
|
n_coef = n_coef*(orde + i)/(i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ unsigned int calculateNumberOfParameters(const unsigned int dimension, const uns
|
||||||
#pragma mark ctors
|
#pragma mark ctors
|
||||||
|
|
||||||
Polynomial::Polynomial():
|
Polynomial::Polynomial():
|
||||||
AttractorKernel(3, calculateNumberOfParameters(3, 2)), orde(2){}
|
AttractorKernel(3, calculateNumberOfParameters(3, 2)), orde(2) {}
|
||||||
|
|
||||||
Polynomial::Polynomial(const unsigned int dimension, const unsigned int orde):
|
Polynomial::Polynomial(const unsigned int dimension, const unsigned int orde):
|
||||||
AttractorKernel(dimension, calculateNumberOfParameters(dimension, orde)), orde(orde){}
|
AttractorKernel(dimension, calculateNumberOfParameters(dimension, orde)), orde(orde) {}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -38,7 +38,7 @@ void Polynomial::operator()() {
|
||||||
std::swap(vectorNew, vectorOld);
|
std::swap(vectorNew, vectorOld);
|
||||||
|
|
||||||
unsigned int m = 0;
|
unsigned int m = 0;
|
||||||
for ( unsigned int i = 0; i < dimension; i++ ) {
|
for(unsigned int i = 0; i < dimension; i++) {
|
||||||
|
|
||||||
vectorNew[i] = parameters[m];
|
vectorNew[i] = parameters[m];
|
||||||
m++;
|
m++;
|
||||||
|
@ -48,12 +48,12 @@ void Polynomial::operator()() {
|
||||||
|
|
||||||
void Polynomial::recur(unsigned int curr_dimension, unsigned int prev_i, unsigned int n, unsigned int& m, double prev_product) {
|
void Polynomial::recur(unsigned int curr_dimension, unsigned int prev_i, unsigned int n, unsigned int& m, double prev_product) {
|
||||||
double product;
|
double product;
|
||||||
for (unsigned int i = prev_i; i < dimension; i++) {
|
for(unsigned int i = prev_i; i < dimension; i++) {
|
||||||
|
|
||||||
product = prev_product * vectorOld[i];
|
product = prev_product * vectorOld[i];
|
||||||
vectorNew[curr_dimension] += parameters[m] * product;
|
vectorNew[curr_dimension] += parameters[m] * product;
|
||||||
m++;
|
m++;
|
||||||
if (n < orde) {
|
if(n < orde) {
|
||||||
recur(curr_dimension, i, n+1, m, product);
|
recur(curr_dimension, i, n+1, m, product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#pragma mark ctors
|
#pragma mark ctors
|
||||||
|
|
||||||
PolynomialA3D::PolynomialA3D():
|
PolynomialA3D::PolynomialA3D():
|
||||||
AttractorKernel(3, 3){}
|
AttractorKernel(3, 3) {}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#pragma mark ctors
|
#pragma mark ctors
|
||||||
|
|
||||||
Unravel3D::Unravel3D():
|
Unravel3D::Unravel3D():
|
||||||
AttractorKernel(3, 7){}
|
AttractorKernel(3, 7) {}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -22,9 +22,9 @@ void Unravel3D::operator()() {
|
||||||
|
|
||||||
const double dist = vectorNew[0]*vectorNew[0] + vectorNew[1]*vectorNew[1] + vectorNew[2]*vectorNew[2];
|
const double dist = vectorNew[0]*vectorNew[0] + vectorNew[1]*vectorNew[1] + vectorNew[2]*vectorNew[2];
|
||||||
|
|
||||||
if ( dist > parameters[6]*parameters[6] ) {
|
if(dist > parameters[6]*parameters[6]) {
|
||||||
const double sqrtDist = std::sqrt(dist);
|
const double sqrtDist = std::sqrt(dist);
|
||||||
const double p = 1.0 - parameters[6] * ( static_cast<int> ( sqrtDist / parameters[6] ) + 1.0 ) / sqrtDist;
|
const double p = 1.0 - parameters[6] * (static_cast<int>(sqrtDist / parameters[6]) + 1.0) / sqrtDist;
|
||||||
vectorNew[0] *= p;
|
vectorNew[0] *= p;
|
||||||
vectorNew[1] *= p;
|
vectorNew[1] *= p;
|
||||||
vectorNew[2] *= p;
|
vectorNew[2] *= p;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef OSTREAM_HELPERS_HPP
|
#ifndef OSTREAM_HELPERS_HPP
|
||||||
#define OSTREAM_HELPERS_HPP
|
#define OSTREAM_HELPERS_HPP
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, AttractorKernel const& x) {
|
std::ostream& operator<<(std::ostream& os, AttractorKernel const& x) {
|
||||||
const unsigned int dimension = x.getDimension();
|
const unsigned int dimension = x.getDimension();
|
||||||
const double * point = x.vector();
|
const double* point = x.vector();
|
||||||
|
|
||||||
std::copy(point, point+dimension, std::ostream_iterator<double>(os, ", "));
|
std::copy(point, point+dimension, std::ostream_iterator<double>(os, ", "));
|
||||||
return os;
|
return os;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -9,7 +9,7 @@ Normalizer::Normalizer(unsigned int dimension) : Projector(dimension, dimension)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
allocate();
|
allocate();
|
||||||
} catch (std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
LogError("Couldn't construct Normalizer (Projector): %s\n", e.what());
|
LogError("Couldn't construct Normalizer (Projector): %s\n", e.what());
|
||||||
deallocate();
|
deallocate();
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,13 @@ Normalizer::~Normalizer() {
|
||||||
deallocate();
|
deallocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Normalizer::allocate(){
|
void Normalizer::allocate() {
|
||||||
range_min = new double[outputDimension];
|
range_min = new double[outputDimension];
|
||||||
range_max = new double[outputDimension];
|
range_max = new double[outputDimension];
|
||||||
offset = new double[outputDimension];
|
offset = new double[outputDimension];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Normalizer::deallocate(){
|
void Normalizer::deallocate() {
|
||||||
delete[] range_min;
|
delete[] range_min;
|
||||||
range_min = 0;
|
range_min = 0;
|
||||||
delete[] range_max;
|
delete[] range_max;
|
||||||
|
@ -41,12 +41,12 @@ void Normalizer::deallocate(){
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark plot
|
#pragma mark plot
|
||||||
|
|
||||||
void Normalizer::project(const double * point) {
|
void Normalizer::project(const double* point) {
|
||||||
for ( unsigned int i = 0; i < inputDimension; ++i ) {
|
for(unsigned int i = 0; i < inputDimension; ++i) {
|
||||||
projectedPoint[0] = point[0]*factor + offset[0];
|
projectedPoint[0] = point[0]*factor + offset[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ready){
|
if(!ready) {
|
||||||
static unsigned int state = 0;
|
static unsigned int state = 0;
|
||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
|
@ -70,16 +70,16 @@ void Normalizer::project(const double * point) {
|
||||||
#pragma mark setting up
|
#pragma mark setting up
|
||||||
|
|
||||||
void Normalizer::init_range() {
|
void Normalizer::init_range() {
|
||||||
for ( unsigned int i = 0; i < outputDimension; i++ ) {
|
for(unsigned int i = 0; i < outputDimension; i++) {
|
||||||
range_min[i] = range_max[i] = projectedPoint[i];
|
range_min[i] = range_max[i] = projectedPoint[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Normalizer::update_range() {
|
void Normalizer::update_range() {
|
||||||
for ( unsigned int i = 0; i < outputDimension; i++ ) {
|
for(unsigned int i = 0; i < outputDimension; i++) {
|
||||||
if ( projectedPoint[i] < range_min[i] ) {
|
if(projectedPoint[i] < range_min[i]) {
|
||||||
range_min[i] = projectedPoint[i];
|
range_min[i] = projectedPoint[i];
|
||||||
} else if ( projectedPoint[i] > range_max[i] ) {
|
} else if(projectedPoint[i] > range_max[i]) {
|
||||||
range_max[i] = projectedPoint[i];
|
range_max[i] = projectedPoint[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,16 +87,16 @@ void Normalizer::update_range() {
|
||||||
|
|
||||||
void Normalizer::finish_range() {
|
void Normalizer::finish_range() {
|
||||||
factor = 2.0 / (range_max[0] - range_min[0]);
|
factor = 2.0 / (range_max[0] - range_min[0]);
|
||||||
for ( unsigned int i = 1; i < outputDimension; i++ ) {
|
for(unsigned int i = 1; i < outputDimension; i++) {
|
||||||
double dist = range_max[i] - range_min[i];
|
double dist = range_max[i] - range_min[i];
|
||||||
if ( factor * dist > 2.0 ) {
|
if(factor * dist > 2.0) {
|
||||||
factor = 2.0 / dist;
|
factor = 2.0 / dist;
|
||||||
//teh_size = canvas->size[i];
|
//teh_size = canvas->size[i];
|
||||||
LogDebug("Crap for dimension %d\n", i);
|
LogDebug("Crap for dimension %d\n", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < outputDimension; i++ ) {
|
for(unsigned int i = 0; i < outputDimension; i++) {
|
||||||
offset[i] = -0.5*factor*(range_min[i] + range_max[i]);
|
offset[i] = -0.5*factor*(range_min[i] + range_max[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "Projection.hpp"
|
#include "Projection.hpp"
|
||||||
|
|
||||||
Projection::Projection(unsigned int inputDimension, unsigned int outputDimension) : Projector(inputDimension, outputDimension){
|
Projection::Projection(unsigned int inputDimension, unsigned int outputDimension) : Projector(inputDimension, outputDimension) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Projection::project(const double* point){
|
void Projection::project(const double* point) {
|
||||||
for ( unsigned int i = 0; i < inputDimension; ++i){
|
for(unsigned int i = 0; i < inputDimension; ++i) {
|
||||||
projectedPoint[i] = point[i];
|
projectedPoint[i] = point[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
550
stfu/stf.cpp
550
stfu/stf.cpp
|
@ -1,275 +1,275 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2009 Maurice Bos and Nick Overdijk
|
Copyright (c) 2009 Maurice Bos and Nick Overdijk
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
* The names of the authors may not be used to endorse or promote
|
* The names of the authors may not be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
- Maurice Bos (maurice@bosbyte.nl)
|
- Maurice Bos (maurice@bosbyte.nl)
|
||||||
- Nick Overdijk (nick@dotsimplicity.net)
|
- Nick Overdijk (nick@dotsimplicity.net)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
#include "stf.hpp"
|
#include "stf.hpp"
|
||||||
|
|
||||||
namespace stfu{
|
namespace stfu {
|
||||||
|
|
||||||
std::ostream &operator<< (std::ostream &out, const node &root) {
|
std::ostream& operator<< (std::ostream& out, const node& root) {
|
||||||
root.write(out);
|
root.write(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<< (const char *filename, const node &root){
|
bool operator<< (const char* filename, const node& root) {
|
||||||
return root.write(filename);
|
return root.write(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<< (std::ofstream &out, const node &root) {
|
bool operator<< (std::ofstream& out, const node& root) {
|
||||||
return root.write(out);
|
return root.write(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>> (std::istream &in, node &root) {
|
bool operator>> (std::istream& in, node& root) {
|
||||||
return root.read(in);
|
return root.read(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>> (const char *filename, node &root) {
|
bool operator>> (const char* filename, node& root) {
|
||||||
return root.read(filename);
|
return root.read(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &node::getValue(const std::string &name, size_t index) const throw (std::out_of_range) {
|
const std::string& node::getValue(const std::string& name, size_t index) const throw(std::out_of_range) {
|
||||||
return get_indexed<std::string, std::string>(values, name, index);
|
return get_indexed<std::string, std::string>(values, name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Function is const, but shouldn't be called on const objects since it returns a nonconst-reference to a member*/
|
/*Function is const, but shouldn't be called on const objects since it returns a nonconst-reference to a member*/
|
||||||
std::string &node::getValue(const std::string &name, size_t index) throw (std::out_of_range) {
|
std::string& node::getValue(const std::string& name, size_t index) throw(std::out_of_range) {
|
||||||
return get_indexed<std::string, std::string>(values, name, index);
|
return get_indexed<std::string, std::string>(values, name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &node::addValue(const std::string &name) {
|
std::string& node::addValue(const std::string& name) {
|
||||||
return values.insert(std::pair<std::string, std::string>(name, std::string()))->second;
|
return values.insert(std::pair<std::string, std::string>(name, std::string()))->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &node::value(const std::string &name, size_t index) {
|
std::string& node::value(const std::string& name, size_t index) {
|
||||||
try {
|
try {
|
||||||
return getValue(name, index);
|
return getValue(name, index);
|
||||||
} catch (std::out_of_range &e) {
|
} catch(std::out_of_range& e) {
|
||||||
//it doesn't exist: create it
|
//it doesn't exist: create it
|
||||||
return addValue(name);
|
return addValue(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void node::removeValue(const std::string &name, size_t index) throw (std::out_of_range) {
|
void node::removeValue(const std::string& name, size_t index) throw(std::out_of_range) {
|
||||||
values.erase(get_indexed_it(values, name, index));
|
values.erase(get_indexed_it(values, name, index));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void node::renameValue(const std::string &oldName, const std::string &newName, size_t index) {
|
void node::renameValue(const std::string& oldName, const std::string& newName, size_t index) {
|
||||||
addValue(newName) = value(oldName, index);
|
addValue(newName) = value(oldName, index);
|
||||||
removeValue(oldName, index);
|
removeValue(oldName, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const node &node::getChild(const std::string &name, size_t index) const throw (std::out_of_range) {
|
const node& node::getChild(const std::string& name, size_t index) const throw(std::out_of_range) {
|
||||||
return get_indexed<std::string, node>(children, name, index);
|
return get_indexed<std::string, node>(children, name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
node &node::getChild(const std::string &name, size_t index) throw (std::out_of_range) {
|
node& node::getChild(const std::string& name, size_t index) throw(std::out_of_range) {
|
||||||
return get_indexed<std::string, node>(children, name, index);
|
return get_indexed<std::string, node>(children, name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
node &node::addChild(const std::string &name) {
|
node& node::addChild(const std::string& name) {
|
||||||
return children.insert(std::pair<std::string, node>(name, node()))->second;
|
return children.insert(std::pair<std::string, node>(name, node()))->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
node &node::addChild(const std::string &name, node &newNode) {
|
node& node::addChild(const std::string& name, node& newNode) {
|
||||||
return children.insert(std::pair<std::string, node>(name, newNode))->second;
|
return children.insert(std::pair<std::string, node>(name, newNode))->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
node &node::child(const std::string &name, size_t index) {
|
node& node::child(const std::string& name, size_t index) {
|
||||||
//if there's no such child, add one
|
//if there's no such child, add one
|
||||||
try {
|
try {
|
||||||
return getChild(name, index);
|
return getChild(name, index);
|
||||||
} catch (std::out_of_range &e) {
|
} catch(std::out_of_range& e) {
|
||||||
//it doesn't exist: create it
|
//it doesn't exist: create it
|
||||||
return addChild(name);
|
return addChild(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void node::renameChild(const std::string &oldName, const std::string &newName, size_t index) {
|
void node::renameChild(const std::string& oldName, const std::string& newName, size_t index) {
|
||||||
node copy = child(oldName, index);
|
node copy = child(oldName, index);
|
||||||
removeChild(oldName, index);
|
removeChild(oldName, index);
|
||||||
addChild(newName) = copy;
|
addChild(newName) = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void node::removeChild(const std::string &name, size_t index) throw (std::out_of_range) {
|
void node::removeChild(const std::string& name, size_t index) throw(std::out_of_range) {
|
||||||
children.erase(get_indexed_it(children, name, index));
|
children.erase(get_indexed_it(children, name, index));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool node::read(const char *filename) {
|
bool node::read(const char* filename) {
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
|
|
||||||
if (!f.good()) return false;
|
if(!f.good()) return false;
|
||||||
|
|
||||||
bool success = read(f);
|
bool success = read(f);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool node::read(std::istream &in) {
|
bool node::read(std::istream& in) {
|
||||||
while (1) {
|
while(1) {
|
||||||
in >> std::ws; //Skip whitespace
|
in >> std::ws; //Skip whitespace
|
||||||
|
|
||||||
//if end of node is reached, return
|
//if end of node is reached, return
|
||||||
if (in.peek() == '}') {
|
if(in.peek() == '}') {
|
||||||
in.ignore();
|
in.ignore();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in.eof()) {
|
if(in.eof()) {
|
||||||
return true; //End of the file is reached
|
return true; //End of the file is reached
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
char type; // '{' or '"'
|
char type; // '{' or '"'
|
||||||
streamRead(in, name, ':'); //Read name (all chars before ':')
|
streamRead(in, name, ':'); //Read name (all chars before ':')
|
||||||
type = streamSkip(in,"\"{"); //Skip everything until '{' or '"'
|
type = streamSkip(in,"\"{"); //Skip everything until '{' or '"'
|
||||||
|
|
||||||
switch (type) {
|
switch(type) {
|
||||||
|
|
||||||
//in case of value
|
//in case of value
|
||||||
case '"': {
|
case '"': {
|
||||||
std::string value;
|
std::string value;
|
||||||
while (1) {
|
while(1) {
|
||||||
if (streamRead(in, value, '"') == 0) { //Read to the closing-"
|
if(streamRead(in, value, '"') == 0) { //Read to the closing-"
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (in.peek() == '"') {
|
if(in.peek() == '"') {
|
||||||
in.ignore();
|
in.ignore();
|
||||||
value += '"';
|
value += '"';
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->values.insert(std::pair<std::string,std::string>(name, value));
|
this->values.insert(std::pair<std::string,std::string>(name, value));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//in case of child
|
//in case of child
|
||||||
case '{': {
|
case '{': {
|
||||||
node sub;
|
node sub;
|
||||||
if (!sub.read(in)) { //Recursively read the subnode
|
if(!sub.read(in)) { //Recursively read the subnode
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this->children.insert(std::pair<std::string,node>(name,sub));
|
this->children.insert(std::pair<std::string,node>(name,sub));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Writes to a file using it's overloaded self*/
|
/*Writes to a file using it's overloaded self*/
|
||||||
bool node::write(const char *filename) const {
|
bool node::write(const char* filename) const {
|
||||||
std::ofstream f(filename);
|
std::ofstream f(filename);
|
||||||
|
|
||||||
if (!f.good()) {
|
if(!f.good()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = write(f);
|
bool success = write(f);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO (Nick#1#): Make write() not put unnamed values on a new line, children are okay.
|
// TODO (Nick#1#): Make write() not put unnamed values on a new line, children are okay.
|
||||||
bool node::write(std::ostream &out, size_t depth, std::string indent) const {
|
bool node::write(std::ostream& out, size_t depth, std::string indent) const {
|
||||||
std::string indentation;
|
std::string indentation;
|
||||||
for (size_t i = 0; i < depth; i++) {
|
for(size_t i = 0; i < depth; i++) {
|
||||||
indentation += indent;
|
indentation += indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::multimap<std::string, std::string>::const_iterator value_it = values.begin(); value_it != values.end(); value_it++) {
|
for(std::multimap<std::string, std::string>::const_iterator value_it = values.begin(); value_it != values.end(); value_it++) {
|
||||||
//Escape all the '"' by adding a second '"'
|
//Escape all the '"' by adding a second '"'
|
||||||
std::string value(value_it->second);
|
std::string value(value_it->second);
|
||||||
size_t found = value.find('"');
|
size_t found = value.find('"');
|
||||||
|
|
||||||
//while there are more ", insert second "s
|
//while there are more ", insert second "s
|
||||||
while (found != value.npos) {
|
while(found != value.npos) {
|
||||||
value.insert(found, 1, '"');
|
value.insert(found, 1, '"');
|
||||||
found = value.find('"', found+2);
|
found = value.find('"', found+2);
|
||||||
}
|
}
|
||||||
out << indentation << value_it->first << ": \"" << value << '"' << std::endl;
|
out << indentation << value_it->first << ": \"" << value << '"' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::multimap<std::string, node>::const_iterator child_it = children.begin(); child_it != children.end(); child_it++) {
|
for(std::multimap<std::string, node>::const_iterator child_it = children.begin(); child_it != children.end(); child_it++) {
|
||||||
out << indentation << child_it->first << ": {" << std::endl;
|
out << indentation << child_it->first << ": {" << std::endl;
|
||||||
child_it->second.write(out, depth+1);
|
child_it->second.write(out, depth+1);
|
||||||
out << indentation << '}' << std::endl;
|
out << indentation << '}' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char node::streamSkip(std::istream &in, const std::string &delimiters) {
|
char node::streamSkip(std::istream& in, const std::string& delimiters) {
|
||||||
char cur;
|
char cur;
|
||||||
|
|
||||||
//Return if the current char is part of delimiters[]
|
//Return if the current char is part of delimiters[]
|
||||||
while (in >> std::noskipws >> cur) {
|
while(in >> std::noskipws >> cur) {
|
||||||
if (delimiters.find_first_of(cur) != delimiters.npos) return cur;
|
if(delimiters.find_first_of(cur) != delimiters.npos) return cur;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char node::streamRead(std::istream &in, std::string &out, const std::string &delimiters) {
|
char node::streamRead(std::istream& in, std::string& out, const std::string& delimiters) {
|
||||||
char cur;
|
char cur;
|
||||||
|
|
||||||
//Return if the current char is part of delimiters[]
|
//Return if the current char is part of delimiters[]
|
||||||
while (in >> std::noskipws >> cur) {
|
while(in >> std::noskipws >> cur) {
|
||||||
if (delimiters.find(cur) != delimiters.npos) return cur;
|
if(delimiters.find(cur) != delimiters.npos) return cur;
|
||||||
out += cur;
|
out += cur;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char node::streamRead(std::istream &in, std::string &out, const char delimiter) {
|
char node::streamRead(std::istream& in, std::string& out, const char delimiter) {
|
||||||
char cur;
|
char cur;
|
||||||
|
|
||||||
//Return if the current char is delimiter
|
//Return if the current char is delimiter
|
||||||
while (in >> std::noskipws >> cur) {
|
while(in >> std::noskipws >> cur) {
|
||||||
if (delimiter == cur) return cur;
|
if(delimiter == cur) return cur;
|
||||||
out += cur;
|
out += cur;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
718
stfu/stf.hpp
718
stfu/stf.hpp
|
@ -1,359 +1,359 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2009 Maurice Bos and Nick Overdijk
|
Copyright (c) 2009 Maurice Bos and Nick Overdijk
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
* The names of the authors may not be used to endorse or promote
|
* The names of the authors may not be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
- Maurice Bos (maurice@bosbyte.nl)
|
- Maurice Bos (maurice@bosbyte.nl)
|
||||||
- Nick Overdijk (nick@dotsimplicity.net)
|
- Nick Overdijk (nick@dotsimplicity.net)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#ifndef STFU_HPP
|
#ifndef STFU_HPP
|
||||||
#define STFU_HPP
|
#define STFU_HPP
|
||||||
|
|
||||||
namespace stfu {
|
namespace stfu {
|
||||||
|
|
||||||
const static std::string not_found("search->No such child/value");
|
const static std::string not_found("search->No such child/value");
|
||||||
|
|
||||||
/*! \class node
|
/*! \class node
|
||||||
* \brief A node in an STF tree.
|
* \brief A node in an STF tree.
|
||||||
* \author Maurice Bos
|
* \author Maurice Bos
|
||||||
* \author Nick Overdijk
|
* \author Nick Overdijk
|
||||||
* \version 1.0
|
* \version 1.0
|
||||||
* \date 2009-04-25
|
* \date 2009-04-25
|
||||||
*
|
*
|
||||||
* When you read an STF file through a node (with read() for example), this node will be the root node, without a name. See the examples for more information.
|
* When you read an STF file through a node (with read() for example), this node will be the root node, without a name. See the examples for more information.
|
||||||
*/
|
*/
|
||||||
class node {
|
class node {
|
||||||
|
|
||||||
/** Overloaded ostream's operator<< */
|
/** Overloaded ostream's operator<< */
|
||||||
friend std::ostream &operator<< (std::ostream &out, const node &root);
|
friend std::ostream& operator<< (std::ostream& out, const node& root);
|
||||||
|
|
||||||
/** Returns whether it was succesful or not*/
|
/** Returns whether it was succesful or not*/
|
||||||
friend bool operator<< (std::ofstream &out, const node &root);
|
friend bool operator<< (std::ofstream& out, const node& root);
|
||||||
|
|
||||||
/** Acts like write(), but looks like this: "filename" << node */
|
/** Acts like write(), but looks like this: "filename" << node */
|
||||||
friend bool operator<< (const char *filename, const node &root);
|
friend bool operator<< (const char* filename, const node& root);
|
||||||
|
|
||||||
/** Overloaded istream's operator>> */
|
/** Overloaded istream's operator>> */
|
||||||
friend bool operator>> (std::istream &in, node &root);
|
friend bool operator>> (std::istream& in, node& root);
|
||||||
|
|
||||||
/** Acts like read(), but looks like this: "filename" >> node */
|
/** Acts like read(), but looks like this: "filename" >> node */
|
||||||
friend bool operator>> (const char *filename, node &root);
|
friend bool operator>> (const char* filename, node& root);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//@{
|
//@{
|
||||||
/** The values and children belonging to this node. To add, remove, do whatever: you CAN use these variables directly. To use indexing, use the member functions below*/
|
/** The values and children belonging to this node. To add, remove, do whatever: you CAN use these variables directly. To use indexing, use the member functions below*/
|
||||||
std::multimap<std::string, std::string> values;
|
std::multimap<std::string, std::string> values;
|
||||||
std::multimap<std::string, node> children;
|
std::multimap<std::string, node> children;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Clears the whole node recursively.
|
Clears the whole node recursively.
|
||||||
*/
|
*/
|
||||||
void clear() {
|
void clear() {
|
||||||
values.clear();
|
values.clear();
|
||||||
children.clear();
|
children.clear();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
Gets the std::string value from a variable
|
Gets the std::string value from a variable
|
||||||
\param name The name of the value you wish to retrieve
|
\param name The name of the value you wish to retrieve
|
||||||
\param index If there are more values with the same name, they are indexed. Here you can supply its indexnumber.
|
\param index If there are more values with the same name, they are indexed. Here you can supply its indexnumber.
|
||||||
\return The retrieved value
|
\return The retrieved value
|
||||||
*/
|
*/
|
||||||
std::string &value(const std::string &name, size_t index = 0);
|
std::string& value(const std::string& name, size_t index = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as value(), but for unnamed values
|
Same as value(), but for unnamed values
|
||||||
\note same as value("", index)
|
\note same as value("", index)
|
||||||
\param index If there are more unnamed values, they are indexed. Here you can supply its indexnumber.
|
\param index If there are more unnamed values, they are indexed. Here you can supply its indexnumber.
|
||||||
\return Same as value
|
\return Same as value
|
||||||
*/
|
*/
|
||||||
std::string &value(size_t index){
|
std::string& value(size_t index) {
|
||||||
return value("", index);
|
return value("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates and adds a value.
|
Creates and adds a value.
|
||||||
\param name The name of the value to be created
|
\param name The name of the value to be created
|
||||||
\return A reference to the value of the created value.
|
\return A reference to the value of the created value.
|
||||||
*/
|
*/
|
||||||
std::string &addValue(const std::string &name = "");
|
std::string& addValue(const std::string& name = "");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Const function for const objects to get a value. It's NOT possible to call value() on constant objects for value() isn't const.
|
Const function for const objects to get a value. It's NOT possible to call value() on constant objects for value() isn't const.
|
||||||
\param name Name of the value to be retrieved
|
\param name Name of the value to be retrieved
|
||||||
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a const std::string& to the value of value with the name and index specified
|
\return Returns a const std::string& to the value of value with the name and index specified
|
||||||
*/
|
*/
|
||||||
const std::string &getValue(const std::string &name, size_t index) const throw (std::out_of_range);
|
const std::string& getValue(const std::string& name, size_t index) const throw(std::out_of_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as getValue() const, but for unnamed values
|
Same as getValue() const, but for unnamed values
|
||||||
\note same as getValue("", index) const
|
\note same as getValue("", index) const
|
||||||
\param index If there are > 1 unnamed values, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed values, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a const std::string& to the value of value with the name and index specified
|
\return Returns a const std::string& to the value of value with the name and index specified
|
||||||
*/
|
*/
|
||||||
const std::string &getValue(size_t index) const throw (std::out_of_range){
|
const std::string& getValue(size_t index) const throw(std::out_of_range) {
|
||||||
return getValue("", index);
|
return getValue("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as getValue() const, but for non-const objects. The returned std::string& can safely be modified.
|
Same as getValue() const, but for non-const objects. The returned std::string& can safely be modified.
|
||||||
\param name Name of the value to be retrieved
|
\param name Name of the value to be retrieved
|
||||||
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a std::string& to the value of value with the name and index specified
|
\return Returns a std::string& to the value of value with the name and index specified
|
||||||
*/
|
*/
|
||||||
std::string &getValue(const std::string &name, size_t index = 0) throw (std::out_of_range);
|
std::string& getValue(const std::string& name, size_t index = 0) throw(std::out_of_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as getValue(), but for unnamed values
|
Same as getValue(), but for unnamed values
|
||||||
\note same as getValue("", index)
|
\note same as getValue("", index)
|
||||||
\param index If there are > 1 unnamed values, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed values, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a std::string& to the value of value with the name and index specified
|
\return Returns a std::string& to the value of value with the name and index specified
|
||||||
*/
|
*/
|
||||||
std::string &getValue(size_t index) throw (std::out_of_range){
|
std::string& getValue(size_t index) throw(std::out_of_range) {
|
||||||
return getValue("", index);
|
return getValue("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Removes a value. Surprise huh?
|
Removes a value. Surprise huh?
|
||||||
\param name Name of the value to be removed
|
\param name Name of the value to be removed
|
||||||
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
*/
|
*/
|
||||||
void removeValue(const std::string &name, size_t index = 0) throw (std::out_of_range);
|
void removeValue(const std::string& name, size_t index = 0) throw(std::out_of_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Removes an unnamed value.
|
Removes an unnamed value.
|
||||||
\note same as removeValue("", index);
|
\note same as removeValue("", index);
|
||||||
\param index If there are > 1 unnamed values, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed values, they are indexed. Here you can supply an indexnumber.
|
||||||
*/
|
*/
|
||||||
void removeValue(size_t index) throw (std::out_of_range){
|
void removeValue(size_t index) throw(std::out_of_range) {
|
||||||
removeValue("", index);
|
removeValue("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Renames a value.
|
Renames a value.
|
||||||
\param oldName Name of the value to be renamed
|
\param oldName Name of the value to be renamed
|
||||||
\param newName The name that the oldName-value should have
|
\param newName The name that the oldName-value should have
|
||||||
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
*/
|
*/
|
||||||
void renameValue(const std::string &oldName, const std::string &newName, size_t index = 0);
|
void renameValue(const std::string& oldName, const std::string& newName, size_t index = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Changes, adds or retrieves node
|
Changes, adds or retrieves node
|
||||||
\param name The name of the child you wish to retrieve, change or add.
|
\param name The name of the child you wish to retrieve, change or add.
|
||||||
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
\return The retrieved node
|
\return The retrieved node
|
||||||
|
|
||||||
If this index number is > the number of variables with that name, a new variable with that name is created with index = current number of same name variables + 1.
|
If this index number is > the number of variables with that name, a new variable with that name is created with index = current number of same name variables + 1.
|
||||||
So say you have 4 variables named "tree", you call child("tree", 10), another tree gets made with index 5, NOT 10.
|
So say you have 4 variables named "tree", you call child("tree", 10), another tree gets made with index 5, NOT 10.
|
||||||
*/
|
*/
|
||||||
node &child(const std::string &name, size_t index = 0);
|
node& child(const std::string& name, size_t index = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as child(), but for unnamed children.
|
Same as child(), but for unnamed children.
|
||||||
\note same as child("", index)
|
\note same as child("", index)
|
||||||
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
||||||
\return The retrieved node
|
\return The retrieved node
|
||||||
*/
|
*/
|
||||||
node &child(size_t index = 0){
|
node& child(size_t index = 0) {
|
||||||
return child("", index);
|
return child("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Guarranteed to add a child
|
Guarranteed to add a child
|
||||||
\param name Name for the child
|
\param name Name for the child
|
||||||
\return A reference to the created node
|
\return A reference to the created node
|
||||||
*/
|
*/
|
||||||
node &addChild(const std::string &name = "");
|
node& addChild(const std::string& name = "");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
As addChild(name), but copies data from newChild as well.
|
As addChild(name), but copies data from newChild as well.
|
||||||
\param name Name for the child
|
\param name Name for the child
|
||||||
\param newChild Data to copy from the child.
|
\param newChild Data to copy from the child.
|
||||||
\return A reference to the created node
|
\return A reference to the created node
|
||||||
*/
|
*/
|
||||||
node &addChild(const std::string &name, node &newChild);
|
node& addChild(const std::string& name, node& newChild);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
As addChild(name, newChild), but without name, for unnamed children
|
As addChild(name, newChild), but without name, for unnamed children
|
||||||
\note same as addChild("", newChild);
|
\note same as addChild("", newChild);
|
||||||
\param newChild Data to copy from the child.
|
\param newChild Data to copy from the child.
|
||||||
\return A reference to the created node
|
\return A reference to the created node
|
||||||
*/
|
*/
|
||||||
node &addChild(node &newChild){
|
node& addChild(node& newChild) {
|
||||||
return addChild("", newChild);
|
return addChild("", newChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Const function for const objects to get a node. It's NOT possible to call child() for this, for child() isn't const.
|
Const function for const objects to get a node. It's NOT possible to call child() for this, for child() isn't const.
|
||||||
\param name Name of the child to be retrieved
|
\param name Name of the child to be retrieved
|
||||||
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a const node& to the node with the name and index specified
|
\return Returns a const node& to the node with the name and index specified
|
||||||
*/
|
*/
|
||||||
const node &getChild(const std::string &name, size_t index = 0) const throw (std::out_of_range);
|
const node& getChild(const std::string& name, size_t index = 0) const throw(std::out_of_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Const function for const objects to get an unnamed const node&.
|
Const function for const objects to get an unnamed const node&.
|
||||||
\note same as getChild("", index) const;
|
\note same as getChild("", index) const;
|
||||||
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a const node& to the node with the name and index specified
|
\return Returns a const node& to the node with the name and index specified
|
||||||
*/
|
*/
|
||||||
const node &getChild(size_t index = 0) const throw (std::out_of_range){
|
const node& getChild(size_t index = 0) const throw(std::out_of_range) {
|
||||||
return getChild("", index);
|
return getChild("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as getChild() const, but for non-const objects. The returned child & can be modified
|
Same as getChild() const, but for non-const objects. The returned child & can be modified
|
||||||
\param name Name of the child to be retrieved
|
\param name Name of the child to be retrieved
|
||||||
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a node& to the node with the name and index specified
|
\return Returns a node& to the node with the name and index specified
|
||||||
*/
|
*/
|
||||||
node &getChild(const std::string &name, size_t index = 0) throw (std::out_of_range);
|
node& getChild(const std::string& name, size_t index = 0) throw(std::out_of_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Same as getChild() const, but for non-const objects.
|
Same as getChild() const, but for non-const objects.
|
||||||
\note same as getChild("", index);
|
\note same as getChild("", index);
|
||||||
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
||||||
\return Returns a node& to the node with the name and index specified
|
\return Returns a node& to the node with the name and index specified
|
||||||
*/
|
*/
|
||||||
node &getChild(size_t index = 0) throw (std::out_of_range){
|
node& getChild(size_t index = 0) throw(std::out_of_range) {
|
||||||
return getChild("", index);
|
return getChild("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Removes a child. Surprise huh?
|
Removes a child. Surprise huh?
|
||||||
\param name Name of the child to be removed
|
\param name Name of the child to be removed
|
||||||
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
*/
|
*/
|
||||||
void removeChild(const std::string &name, size_t index = 0) throw (std::out_of_range);
|
void removeChild(const std::string& name, size_t index = 0) throw(std::out_of_range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
As removeChild() for unnamed children.
|
As removeChild() for unnamed children.
|
||||||
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 unnamed children, they are indexed. Here you can supply an indexnumber.
|
||||||
*/
|
*/
|
||||||
void removeChild(size_t index = 0) throw (std::out_of_range){
|
void removeChild(size_t index = 0) throw(std::out_of_range) {
|
||||||
removeChild("", index);
|
removeChild("", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Renames a child.
|
Renames a child.
|
||||||
\param oldName Name of the child to be renamed
|
\param oldName Name of the child to be renamed
|
||||||
\param newName The name that the oldName-child should have
|
\param newName The name that the oldName-child should have
|
||||||
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
\param index If there are > 1 children with the same name, they are indexed. Here you can supply an indexnumber.
|
||||||
*/
|
*/
|
||||||
void renameChild(const std::string &oldName, const std::string &newName, size_t index = 0);
|
void renameChild(const std::string& oldName, const std::string& newName, size_t index = 0);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads the STF from an istream
|
Reads the STF from an istream
|
||||||
|
|
||||||
\return Returns whether it was succesful
|
\return Returns whether it was succesful
|
||||||
*/
|
*/
|
||||||
bool read(std::istream &in);
|
bool read(std::istream& in);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads the STF from a file
|
Reads the STF from a file
|
||||||
|
|
||||||
\return Returns whether it was succesful
|
\return Returns whether it was succesful
|
||||||
*/
|
*/
|
||||||
bool read(const char *filename);
|
bool read(const char* filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Writes the STF to an ostream with optional indentation
|
Writes the STF to an ostream with optional indentation
|
||||||
\param out ostream to write to
|
\param out ostream to write to
|
||||||
\param depth how much indentation to start with
|
\param depth how much indentation to start with
|
||||||
\param indent What std::string to use as indenation
|
\param indent What std::string to use as indenation
|
||||||
\return Returns whether it was succesful
|
\return Returns whether it was succesful
|
||||||
*/
|
*/
|
||||||
bool write(std::ostream &out, size_t depth = 0, std::string indent = "\t") const;
|
bool write(std::ostream& out, size_t depth = 0, std::string indent = "\t") const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Writes to a file. Simply first opens a file and passes that ostream to itself.
|
Writes to a file. Simply first opens a file and passes that ostream to itself.
|
||||||
\param filename File to write to
|
\param filename File to write to
|
||||||
\return Returns whether it was succesful
|
\return Returns whether it was succesful
|
||||||
*/
|
*/
|
||||||
bool write(const char *filename) const;
|
bool write(const char* filename) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char streamRead(std::istream &in,std::string &out, const std::string &delim);
|
char streamRead(std::istream& in,std::string& out, const std::string& delim);
|
||||||
char streamRead(std::istream &in, std::string &out, const char delim);
|
char streamRead(std::istream& in, std::string& out, const char delim);
|
||||||
char streamSkip(std::istream &in, const std::string &delim);
|
char streamSkip(std::istream& in, const std::string& delim);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
returns a T2&, not a const T2&. The functions getValue/getChild make sure this will be done correctly for const objects
|
returns a T2&, not a const T2&. The functions getValue/getChild make sure this will be done correctly for const objects
|
||||||
this function can NOT use get_indexed_it, because that function can't be const:
|
this function can NOT use get_indexed_it, because that function can't be const:
|
||||||
const_iterators can not be transformed into iterators, and the iterator is needed for erase(), which wants an iterator.
|
const_iterators can not be transformed into iterators, and the iterator is needed for erase(), which wants an iterator.
|
||||||
*/
|
*/
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
T2& get_indexed(const std::multimap<T1, T2> &container, const T1 &key, size_t index = 0) const throw (std::out_of_range) {
|
T2& get_indexed(const std::multimap<T1, T2> &container, const T1& key, size_t index = 0) const throw(std::out_of_range) {
|
||||||
size_t count = container.count(key);
|
size_t count = container.count(key);
|
||||||
|
|
||||||
if (count != 0 && count-1 >= index) {
|
if(count != 0 && count-1 >= index) {
|
||||||
typename std::multimap<T1, T2>::const_iterator it = container.find(key);
|
typename std::multimap<T1, T2>::const_iterator it = container.find(key);
|
||||||
while (index--) it++;
|
while(index--) it++;
|
||||||
return const_cast<T2&>(it->second);
|
return const_cast<T2&>(it->second);
|
||||||
} else {
|
} else {
|
||||||
throw std::out_of_range((std::string)"get_indexed->"+"Element " + key + "doesn't exist!");
|
throw std::out_of_range((std::string)"get_indexed->"+"Element " + key + "doesn't exist!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// template <typename T1, typename T2>
|
// template <typename T1, typename T2>
|
||||||
// typename multimap<T1, T2>::iterator get_indexed_it(multimap<T1, T2> &container, const T1 &key, size_t index = 0) throw (out_of_range) {
|
// typename multimap<T1, T2>::iterator get_indexed_it(multimap<T1, T2> &container, const T1 &key, size_t index = 0) throw (out_of_range) {
|
||||||
// size_t count = container.count(key);
|
// size_t count = container.count(key);
|
||||||
//
|
//
|
||||||
// if (count != 0 && count-1 >= index) {
|
// if (count != 0 && count-1 >= index) {
|
||||||
// typename multimap<T1, T2>::iterator it = container.find(key);
|
// typename multimap<T1, T2>::iterator it = container.find(key);
|
||||||
// while (index--) it++;
|
// while (index--) it++;
|
||||||
// return it;
|
// return it;
|
||||||
// } else {
|
// } else {
|
||||||
// throw out_of_range((std::string)"get_indexed_it->"+"Element " + key + "doesn't exist!");
|
// throw out_of_range((std::string)"get_indexed_it->"+"Element " + key + "doesn't exist!");
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template <typename Container, typename T>
|
template <typename Container, typename T>
|
||||||
typename Container::iterator get_indexed_it(Container& container, const T& key, size_t index = 0)
|
typename Container::iterator get_indexed_it(Container& container, const T& key, size_t index = 0)
|
||||||
throw (std::out_of_range) {
|
throw(std::out_of_range) {
|
||||||
typename Container::iterator it = container.find(key);
|
typename Container::iterator it = container.find(key);
|
||||||
while (index-- && it != container.end() && it->first==key) it++;
|
while(index-- && it != container.end() && it->first==key) it++;
|
||||||
if (it == container.end()) throw std::out_of_range("get_indexed_it(Container&, const T&, size_t)");
|
if(it == container.end()) throw std::out_of_range("get_indexed_it(Container&, const T&, size_t)");
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<std::string, std::string> value;
|
typedef std::pair<std::string, std::string> value;
|
||||||
typedef std::pair<std::string, node> child;
|
typedef std::pair<std::string, node> child;
|
||||||
|
|
||||||
typedef std::multimap<std::string, std::string>::iterator valueiterator;
|
typedef std::multimap<std::string, std::string>::iterator valueiterator;
|
||||||
typedef std::multimap<std::string, node>::iterator childiterator;
|
typedef std::multimap<std::string, node>::iterator childiterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // STFU_HPP
|
#endif // STFU_HPP
|
||||||
|
|
Reference in a new issue