Browse Source

removed using namespace from stfu, moved the file reading part to a place where it belongs

master
Joshua Moerman 15 years ago
parent
commit
a5d7513e56
  1. 74
      Attractor.cpp
  2. 1
      Attractor.hpp
  3. 77
      AttractorKernel.cpp
  4. 10
      AttractorKernel.hpp
  5. 69
      attractors/testUnravelNew.stf
  6. 471
      stfu/stf.cpp
  7. 101
      stfu/stf.hpp

74
Attractor.cpp

@ -6,18 +6,9 @@
#include <string> #include <string>
#include "stfu/stf.hpp" #include "stfu/stf.hpp"
#include "AttractorKernel.hpp"
#include "Projector.hpp" #include "Projector.hpp"
#include "AttractorKernel.hpp"
#include "kernels/Logistic.hpp"
#include "kernels/Lorenz3D.hpp"
#include "kernels/Polynomial.hpp"
#include "kernels/PolynomialA3D.hpp"
#include "kernels/Unravel3D.hpp"
Attractor::Attractor() {
myAttractor = new Lorenz3D();
}
Attractor::Attractor(const char* const fileName) { Attractor::Attractor(const char* const fileName) {
// opening file // opening file
@ -25,69 +16,10 @@ Attractor::Attractor(const char* const fileName) {
stfu::node system; stfu::node system;
system.read(fileName); system.read(fileName);
stfu::node attractor = system.getChild("attractor"); stfu::node attractor = system.getChild("AttractorKernel");
// reading basic stuff
std::string attractorType = attractor.getValue("type");
const std::string attractorDimension = attractor.getValue("dimensions");
for ( unsigned int i = 0; attractorType[i] != '\0'; i++ ) {
attractorType[i] = tolower(attractorType[i]);
}
const unsigned int dimension = atoi(attractorDimension.c_str());
std::cout << " Formula: " << attractorType << std::endl;
std::cout << " Dimensions: " << dimension << std::endl;
// depending on type, make the formula object myAttractor = AttractorKernel::createAttractorKernel(attractor);
if ( attractorType == "lorenz" ){
if ( dimension == 3 ) {
myAttractor = new Lorenz3D();
} else {
std::cerr << "something wrong";
exit(37);
}
} else if ( attractorType == "polynomial" ) {
const std::string attractorOrde = attractor.getValue("orde");
const unsigned int orde = atoi(attractorOrde.c_str());
std::cout << " Orde: " << orde << std::endl;
myAttractor = new Polynomial(dimension, orde);
} else if ( attractorType == "polynomial a" ) {
if ( dimension == 3 ) {
myAttractor = new PolynomialA3D();
} else {
std::cerr << "something wrong";
exit(37);
}
} else if ( attractorType == "logistic" ) {
myAttractor = new Logistic(dimension);
} else if ( attractorType == "unravel" ) {
if ( dimension == 3 ) {
myAttractor = new Unravel3D();
} else {
std::cerr << "somtheing wrong";
exit(37);
}
} else {
std::cout << "'" << attractorType << "' not recognized" << std::endl;
exit(3);
}
// read parameters
const unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
for ( unsigned int i = 0; i < numberOfParameters; i++ ) {
stfu::node attractorParameters = attractor.getChild("parameters");
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
std::cout << " Parameter " << i << " set to " << (*myAttractor)[i] << ", ";
}
std::cout << std::endl << " Reading file complete" << std::endl;
} }
Attractor::~Attractor(){ Attractor::~Attractor(){

1
Attractor.hpp

@ -16,7 +16,6 @@ public:
// should be private really // should be private really
std::vector<Projector *> projectors; std::vector<Projector *> projectors;
Attractor();
Attractor(const char* const filename); Attractor(const char* const filename);
~Attractor(); ~Attractor();

77
AttractorKernel.cpp

@ -82,3 +82,80 @@ unsigned int AttractorKernel::getDimension() const{
return dimension; return dimension;
} }
#pragma mark -
#pragma mark factory function
#include "AttractorKernel.hpp"
#include "kernels/Logistic.hpp"
#include "kernels/Lorenz3D.hpp"
#include "kernels/Polynomial.hpp"
#include "kernels/PolynomialA3D.hpp"
#include "kernels/Unravel3D.hpp"
AttractorKernel * AttractorKernel::createAttractorKernel(stfu::node& attractor){
AttractorKernel * myAttractor = NULL;
// reading basic stuff
const std::string attractorType = attractor.getValue("type");
const std::string attractorDimension = attractor.getValue("dimensions");
// for ( unsigned int i = 0; attractorType[i] != '\0'; i++ ) {
// attractorType[i] = tolower(attractorType[i]);
// }
const unsigned int dimension = atoi(attractorDimension.c_str());
std::cout << " Formula: " << attractorType << std::endl;
std::cout << " Dimensions: " << dimension << std::endl;
// depending on type, make the formula object
if ( attractorType == "lorenz" ){
if ( dimension == 3 ) {
myAttractor = new Lorenz3D();
} else {
std::cerr << "something wrong";
exit(37);
}
} else if ( attractorType == "polynomial" ) {
const std::string attractorOrde = attractor.getValue("orde");
const unsigned int orde = atoi(attractorOrde.c_str());
std::cout << " Orde: " << orde << std::endl;
myAttractor = new Polynomial(dimension, orde);
} else if ( attractorType == "polynomial a" ) {
if ( dimension == 3 ) {
myAttractor = new PolynomialA3D();
} else {
std::cerr << "something wrong";
exit(37);
}
} else if ( attractorType == "logistic" ) {
myAttractor = new Logistic(dimension);
} else if ( attractorType == "unravel" ) {
if ( dimension == 3 ) {
myAttractor = new Unravel3D();
} else {
std::cerr << "something wrong";
exit(37);
}
} else {
std::cout << "'" << attractorType << "' not recognized" << std::endl;
exit(3);
}
// read parameters
const unsigned int numberOfParameters = myAttractor->getNumberOfParameters();
for ( unsigned int i = 0; i < numberOfParameters; i++ ) {
stfu::node attractorParameters = attractor.getChild("parameters");
(*myAttractor)[i] = atof(attractorParameters.getValue(i).c_str());
std::cout << " Parameter " << i << " set to " << (*myAttractor)[i] << ", ";
}
std::cout << std::endl << " Reading file complete" << std::endl;
return myAttractor;
}

10
AttractorKernel.hpp

@ -1,10 +1,8 @@
#ifndef ATTRACTORKERNEL_HPP #ifndef ATTRACTORKERNEL_HPP
#define ATTRACTORKERNEL_HPP #define ATTRACTORKERNEL_HPP
#include "stfu/stf.hpp"
/*
ABC
*/
class AttractorKernel { class AttractorKernel {
private: private:
@ -38,15 +36,15 @@ public:
// 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 * vector() const{
// return vectorNew;
// }
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
static AttractorKernel * createAttractorKernel(stfu::node& attractorKernel);
}; };
#endif // ATTRACTORKERNEL_HPP #endif // ATTRACTORKERNEL_HPP

69
attractors/testUnravelNew.stf

@ -0,0 +1,69 @@
input: "AttractorKernel"
output: "Canvas"
iterations: "100000"
AttractorKernel: {
type: "unravel"
dimensions: "3"
parameters:
{
:"-0.78"
:"2.042"
:"1.22"
:"-1.267"
:"1.37"
:"2.3"
:"-2.195"
}
}
projections: Applied in order they appear {
:{
type: "auto center"
}
:{
type: "lineair map"
matrix:
{
:{ :"1" :"0" :"0" }
:{ :"0" :"1" :"0" }
}
}
}
Canvas: {
type: "2D canvas"
output: "png"
width: "6400"
height: "6400"
colors: "3"
imageConversion: description how to show the abstract canvas classe
{
colorMatrix: desciribing lineair map from canvas colors to RGB colorspace
{
:{ :"1" :"0" :"0" }
:{ :"0" :"1" :"0" }
:{ :"0" :"0" :"1" }
}
vibrancy: "0"
gamma: "-2.5"
exposure: "3"
}
pngFile: png options
{
fileName: leave empty to autogenerate filename
=> ""
compression: "9"
author: "Joshua Moerman"
title: "Unravel"
description: "A unravel-type attractor made with AwesomeAttractor"
}
}

471
stfu/stf.cpp

@ -37,240 +37,239 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "stf.hpp" #include "stf.hpp"
using namespace std; namespace stfu{
using stfu::node;
using stfu::child; std::ostream &operator<< (std::ostream &out, const node &root) {
using stfu::value; root.write(out);
return out;
ostream &stfu::operator<< (ostream &out, const node &root) { }
root.write(out);
return out; bool operator<< (const char *filename, const node &root){
} return root.write(filename);
}
bool stfu:: operator<< (const char *filename, const node &root){
return root.write(filename); bool operator<< (std::ofstream &out, const node &root) {
} return root.write(out);
}
bool stfu::operator<< (ofstream &out, const node &root) {
return root.write(out); bool operator>> (std::istream &in, node &root) {
} return root.read(in);
}
bool stfu::operator>> (istream &in, node &root) {
return root.read(in); bool operator>> (const char *filename, node &root) {
} return root.read(filename);
}
bool stfu::operator>> (const char *filename, node &root) {
return root.read(filename); 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);
}
const string &node::getValue(const string &name, size_t index) const throw (out_of_range) {
return get_indexed<string, string>(values, name, index); /*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) {
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*/ }
string &node::getValue(const string &name, size_t index) throw (out_of_range) {
return get_indexed<string, string>(values, name, index); std::string &node::addValue(const std::string &name) {
} return values.insert(std::pair<std::string, std::string>(name, std::string()))->second;
}
string &node::addValue(const string &name) {
return values.insert(pair<string, string>(name, string()))->second; std::string &node::value(const std::string &name, size_t index) {
} try {
return getValue(name, index);
string &node::value(const string &name, size_t index) { } catch (std::out_of_range &e) {
try { //it doesn't exist: create it
return getValue(name, index); return addValue(name);
} catch (out_of_range &e) { }
//it doesn't exist: create it }
return addValue(name);
} void node::removeValue(const std::string &name, size_t index) throw (std::out_of_range) {
} values.erase(get_indexed_it(values, name, index));
return;
void node::removeValue(const string &name, size_t index) throw (out_of_range) { }
values.erase(get_indexed_it(values, name, index));
return; void node::renameValue(const std::string &oldName, const std::string &newName, size_t index) {
} addValue(newName) = value(oldName, index);
removeValue(oldName, index);
void node::renameValue(const string &oldName, const string &newName, size_t index) { }
addValue(newName) = value(oldName, index);
removeValue(oldName, index);
} 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);
}
const node &node::getChild(const string &name, size_t index) const throw (out_of_range) {
return get_indexed<string, node>(children, name, index); node &node::getChild(const std::string &name, size_t index) throw (std::out_of_range) {
} return get_indexed<std::string, node>(children, name, index);
}
node &node::getChild(const string &name, size_t index) throw (out_of_range) {
return get_indexed<string, node>(children, name, index); node &node::addChild(const std::string &name) {
} return children.insert(std::pair<std::string, node>(name, node()))->second;
}
node &node::addChild(const string &name) {
return children.insert(pair<string, node>(name, node()))->second; node &node::addChild(const std::string &name, node &newNode) {
} return children.insert(std::pair<std::string, node>(name, newNode))->second;
}
node &node::addChild(const string &name, node &newNode) {
return children.insert(pair<string, node>(name, newNode))->second; node &node::child(const std::string &name, size_t index) {
} //if there's no such child, add one
try {
node &node::child(const string &name, size_t index) { return getChild(name, index);
//if there's no such child, add one } catch (std::out_of_range &e) {
try { //it doesn't exist: create it
return getChild(name, index); return addChild(name);
} catch (out_of_range &e) { }
//it doesn't exist: create it }
return addChild(name);
} void node::renameChild(const std::string &oldName, const std::string &newName, size_t index) {
} node copy = child(oldName, index);
removeChild(oldName, index);
void node::renameChild(const string &oldName, const string &newName, size_t index) { addChild(newName) = copy;
node copy = child(oldName, index); }
removeChild(oldName, index);
addChild(newName) = copy; void node::removeChild(const std::string &name, size_t index) throw (std::out_of_range) {
} children.erase(get_indexed_it(children, name, index));
return;
void node::removeChild(const string &name, size_t index) throw (out_of_range) { }
children.erase(get_indexed_it(children, name, index));
return; bool node::read(const char *filename) {
} std::ifstream f(filename);
bool node::read(const char *filename) { if (!f.good()) return false;
ifstream f(filename);
bool success = read(f);
if (!f.good()) return false; f.close();
bool success = read(f); return success;
f.close(); }
return success; bool node::read(std::istream &in) {
} while (1) {
in >> std::ws; //Skip whitespace
bool node::read(istream &in) {
while (1) { //if end of node is reached, return
in >> ws; //Skip whitespace if (in.peek() == '}') {
in.ignore();
//if end of node is reached, return return true;
if (in.peek() == '}') { }
in.ignore();
return true; if (in.eof()) {
} return true; //End of the file is reached
}
if (in.eof()) {
return true; //End of the file is reached std::string name;
} char type; // '{' or '"'
streamRead(in, name, ':'); //Read name (all chars before ':')
string name; type = streamSkip(in,"\"{"); //Skip everything until '{' or '"'
char type; // '{' or '"'
streamRead(in, name, ':'); //Read name (all chars before ':') switch (type) {
type = streamSkip(in,"\"{"); //Skip everything until '{' or '"'
//in case of value
switch (type) { case '"': {
std::string value;
//in case of value while (1) {
case '"': { if (streamRead(in, value, '"') == 0) { //Read to the closing-"
string value; return false;
while (1) { }
if (streamRead(in, value, '"') == 0) { //Read to the closing-" if (in.peek() == '"') {
return false; in.ignore();
} value += '"';
if (in.peek() == '"') { continue;
in.ignore(); } else {
value += '"'; break;
continue; }
} else { }
break; this->values.insert(std::pair<std::string,std::string>(name, value));
} break;
} }
this->values.insert(pair<string,string>(name, value));
break; //in case of child
} case '{': {
node sub;
//in case of child if (!sub.read(in)) { //Recursively read the subnode
case '{': { return false;
node sub; }
if (!sub.read(in)) { //Recursively read the subnode this->children.insert(std::pair<std::string,node>(name,sub));
return false; break;
} }
this->children.insert(pair<string,node>(name,sub));
break; default:
} return false;
}
default: }
return false; }
}
} /*Writes to a file using it's overloaded self*/
} bool node::write(const char *filename) const {
std::ofstream f(filename);
/*Writes to a file using it's overloaded self*/
bool node::write(const char *filename) const { if (!f.good()) {
ofstream f(filename); return false;
}
if (!f.good()) {
return false; bool success = write(f);
} f.close();
bool success = write(f); return success;
f.close(); }
return success; // 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 {
std::string indentation;
// TODO (Nick#1#): Make write() not put unnamed values on a new line, children are okay. for (size_t i = 0; i < depth; i++) {
bool node::write(ostream &out, size_t depth, string indent) const { indentation += indent;
string indentation; }
for (size_t i = 0; i < depth; i++) {
indentation += indent; 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 '"'
std::string value(value_it->second);
for (multimap<string, string>::const_iterator value_it = values.begin(); value_it != values.end(); value_it++) { size_t found = value.find('"');
//Escape all the '"' by adding a second '"'
string value(value_it->second); //while there are more ", insert second "s
size_t found = value.find('"'); while (found != value.npos) {
value.insert(found, 1, '"');
//while there are more ", insert second "s found = value.find('"', found+2);
while (found != value.npos) { }
value.insert(found, 1, '"'); out << indentation << value_it->first << ": \"" << value << '"' << std::endl;
found = value.find('"', found+2); }
}
out << indentation << value_it->first << ": \"" << value << '"' << endl; 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;
child_it->second.write(out, depth+1);
for (multimap<string, node>::const_iterator child_it = children.begin(); child_it != children.end(); child_it++) { out << indentation << '}' << std::endl;
out << indentation << child_it->first << ": {" << endl; }
child_it->second.write(out, depth+1);
out << indentation << '}' << endl; return true;
} }
return true; char node::streamSkip(std::istream &in, const std::string &delimiters) {
} char cur;
char node::streamSkip(istream &in, const string &delimiters) { //Return if the current char is part of delimiters[]
char cur; while (in >> std::noskipws >> cur) {
if (delimiters.find_first_of(cur) != delimiters.npos) return cur;
//Return if the current char is part of delimiters[] }
while (in >> noskipws >> cur) { return 0;
if (delimiters.find_first_of(cur) != delimiters.npos) return cur; }
}
return 0; char node::streamRead(std::istream &in, std::string &out, const std::string &delimiters) {
} char cur;
char node::streamRead(istream &in, string &out, const string &delimiters) { //Return if the current char is part of delimiters[]
char cur; while (in >> std::noskipws >> cur) {
if (delimiters.find(cur) != delimiters.npos) return cur;
//Return if the current char is part of delimiters[] out += cur;
while (in >> noskipws >> cur) { }
if (delimiters.find(cur) != delimiters.npos) return cur; return 0;
out += cur; }
}
return 0; char node::streamRead(std::istream &in, std::string &out, const char delimiter) {
} char cur;
char node::streamRead(istream &in, string &out, const char delimiter) { //Return if the current char is delimiter
char cur; while (in >> std::noskipws >> cur) {
if (delimiter == cur) return cur;
//Return if the current char is delimiter out += cur;
while (in >> noskipws >> cur) { }
if (delimiter == cur) return cur; return 0;
out += cur; }
}
return 0;
} }

101
stfu/stf.hpp

@ -39,8 +39,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define STFU_HPP #define STFU_HPP
namespace stfu { namespace stfu {
using namespace std;
const static 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.
@ -54,16 +54,16 @@ namespace stfu {
class node { class node {
/** Overloaded ostream's operator<< */ /** Overloaded ostream's operator<< */
friend ostream &operator<< (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<< (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>> (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);
@ -71,8 +71,8 @@ namespace stfu {
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*/
multimap<string, string> values; std::multimap<std::string, std::string> values;
multimap<string, node> children; std::multimap<std::string, node> children;
//@} //@}
/** /**
@ -83,19 +83,20 @@ namespace stfu {
children.clear(); children.clear();
} }
/** /**
Gets the 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
*/ */
string &value(const 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. \return Same as value \param index If there are more unnamed values, they are indexed. Here you can supply its indexnumber.
\return Same as value
*/ */
string &value(size_t index){ std::string &value(size_t index){
return value("", index); return value("", index);
} }
@ -104,41 +105,41 @@ namespace stfu {
\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.
*/ */
string &addValue(const 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 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 string &getValue(const string &name, size_t index) const throw (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 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 string &getValue(size_t index) const throw (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 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 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
*/ */
string &getValue(const string &name, size_t index = 0) throw (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 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
*/ */
string &getValue(size_t index) throw (out_of_range){ std::string &getValue(size_t index) throw (std::out_of_range){
return getValue("", index); return getValue("", index);
} }
@ -147,14 +148,14 @@ namespace stfu {
\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 string &name, size_t index = 0) throw (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 (out_of_range){ void removeValue(size_t index) throw (std::out_of_range){
removeValue("", index); removeValue("", index);
} }
@ -164,7 +165,7 @@ namespace stfu {
\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 string &oldName, const 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
@ -175,7 +176,7 @@ namespace stfu {
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 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.
@ -192,7 +193,7 @@ namespace stfu {
\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 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.
@ -200,7 +201,7 @@ namespace stfu {
\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 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
@ -218,7 +219,7 @@ namespace stfu {
\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 string &name, size_t index = 0) const throw (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&.
@ -226,7 +227,7 @@ namespace stfu {
\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 (out_of_range){ const node &getChild(size_t index = 0) const throw (std::out_of_range){
return getChild("", index); return getChild("", index);
} }
@ -236,7 +237,7 @@ namespace stfu {
\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 string &name, size_t index = 0) throw (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.
@ -244,7 +245,7 @@ namespace stfu {
\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 (out_of_range){ node &getChild(size_t index = 0) throw (std::out_of_range){
return getChild("", index); return getChild("", index);
} }
@ -253,13 +254,13 @@ namespace stfu {
\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 string &name, size_t index = 0) throw (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 (out_of_range){ void removeChild(size_t index = 0) throw (std::out_of_range){
removeChild("", index); removeChild("", index);
} }
@ -269,7 +270,7 @@ namespace stfu {
\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 string &oldName, const string &newName, size_t index = 0); void renameChild(const std::string &oldName, const std::string &newName, size_t index = 0);
/** /**
@ -277,7 +278,7 @@ namespace stfu {
\return Returns whether it was succesful \return Returns whether it was succesful
*/ */
bool read(istream &in); bool read(std::istream &in);
/** /**
Reads the STF from a file Reads the STF from a file
@ -290,10 +291,10 @@ namespace stfu {
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 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(ostream &out, size_t depth = 0, 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.
@ -303,9 +304,9 @@ namespace stfu {
bool write(const char *filename) const; bool write(const char *filename) const;
private: private:
char streamRead(istream &in,string &out, const string &delim); char streamRead(std::istream &in,std::string &out, const std::string &delim);
char streamRead(istream &in, string &out, const char delim); char streamRead(std::istream &in, std::string &out, const char delim);
char streamSkip(istream &in, const 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
@ -313,15 +314,15 @@ namespace stfu {
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 multimap<T1, T2> &container, const T1 &key, size_t index = 0) const throw (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 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 out_of_range((string)"get_indexed->"+"Element " + key + "doesn't exist!"); throw std::out_of_range((std::string)"get_indexed->"+"Element " + key + "doesn't exist!");
} }
} }
@ -334,25 +335,25 @@ namespace stfu {
// while (index--) it++; // while (index--) it++;
// return it; // return it;
// } else { // } else {
// throw out_of_range((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 (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 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 pair<string, string> value; typedef std::pair<std::string, std::string> value;
typedef pair<string, node> child; typedef std::pair<std::string, node> child;
typedef multimap<string, string>::iterator valueiterator; typedef std::multimap<std::string, std::string>::iterator valueiterator;
typedef multimap<string, node>::iterator childiterator; typedef std::multimap<std::string, node>::iterator childiterator;
} }
#endif // STFU_HPP #endif // STFU_HPP