#ifndef __BLOP_BLOPUTILS_H__ #define __BLOP_BLOPUTILS_H__ #include "array.h" #include "frame.h" #include "pad.h" #include "var.h" #include "length.h" #include "function.h" #include "constants.h" #include "text.h" #include <algorithm> namespace blop { bool isfinite(double v); bool isnan(double v); bool isinf(double v); bool isnormal(double v); // -------------------------------------------------------------------------------- std::istream *openin(const var &filename); std::ostream *openout(const var &filename); // -------------------------------------------------------------------------------- length axislength(axis *a, double from, double to=unset); length x1len(double a,double b=unset); length x2len(double a,double b=unset); length y1len(double a,double b=unset); length y2len(double a,double b=unset); // return the length along the x1/x2/y1/y2 axes: // - from the origin to 'a', if 'b'==unset, // - from 'a' to 'b', if 'b' is not unset // -------------------------------------------------------------------------------- // Print the current canvas to a terminal void print(terminal *term); // ---------- system -------------------------------------------------------------- // Like the usual 'system(const char *cmd)' function of C, // but for 'var' argument int system(const var &); // Run a command in the background, return it's process-id. This process-id is also // automatically registered, and will be waited for before quitting the program. int system_bg(const var &cmd); // ---------- shell --------------------------------------------------------------- // The same as the 'system' function, but the same shell process // is used for all subsequent calls. For example a 'cd /tmp' command // processed by this function will have an effect for all later calls // of this function. These two commands list the /tmp directory: // shell("cd /tmp"); // shell("ls"); void shell(const var &command); // ---------- readcmd ------------------------------------------------------------- // Read the output of the provided command (which is executed // in /bin/sh). The first character MAY be a '<', in which // case it is removed from it (this is introduced in order to // match the 'plot' command, where the initial '<' in the filename // to be plotted indicates that it is to be treated as a pipe) // If 'rc' is provided, the return code of the command // is returned in this variable var readcmd(const var &cmd,int *rc = 0); int readcmd(const var &cmd, array &out, const var &separator = "\n", int *rc = 0); int readcmd(const var &cmd, std::vector<std::string> &out, const var &separator = "\n", int *rc = 0); // ---------- readfile ------------------------------------------------------------ // Reads and returns the content of the provided file. The second version reads // the file, and splits its contents (by default at newlines) into the array 'out', // and returns the number of entries in out var readfile(const var &filename); int readfile(const var &filename, array &out, const var &separator = "\n"); // ---------- draw the content of a file ------------------------------------------ text &fdraw_file_content(const var &filename); text &pdraw_file_content(const var &filename); text &cdraw_file_content(const var &filename); // Create a sequence of numbers array sequence(var start, var stop, var step=1); // ---------- split and join ------------------------------------------------------ // Splits the string 's' into the vector 'out', and returns the number of entries array split(const var &s, const var &separator = " \t\n"); int split(const string &s,const string &separator, std::vector<std::string> &out); var join(const array &a, const var &separator = array::outfs()); var join(const std::vector<double> &a, const var &separator = array::outfs()); var join(const std::vector<std::string> &a, const var &separator = array::outfs()); // ---------- split a data line (interpret quoation marks, etc) ------------------- void split_quoted(std::string line, std::vector<blop::var> &fields); // ---------- getfield ----------------------------------------------------------- // Split the provided string 's' at characters specified by 'separator', and return // the 'i'th element var getfield(const var &s, unsigned int i, const var &separator = " \t\n"); // ---------- getline ------------------------------------------------------------ // Read a line from the input stream and return it in 'v' (the first version) // or immediately split it as well (at whitespaces) into the array 'a' // line_separator specifies the character to be interpreted as end-of-line (only // the first character of this string is used) // field_separator contains the characters at which the line will be split // (it will be the second argument to the 'split' function described above) istream &getline(istream &, var &v, const var &line_separator = "\n"); istream &getline(istream &, array &a, const var &line_separator = "\n", const var &field_separator = "\t "); istream &getline(istream &, std::vector<std::string> &a, const std::string &line_separator = "\n", const std::string &field_separator = "\t "); // ---------- tolatex ------------------------------------------------------------ // Transform a string (possibly containing _, $, and other latex-special chars) // to latex, where these characters are escaped var tolatex(const var &); // ---------- parallel_sort ------------------------------------------------------- // Sort two arrays based on the values of the first array. The elements of the second // array will correspond to the same elements of the first array. template <class A, class B> class LessThanPairFirst { public: // compare by the 'first' element of a pair (if they are equal, // compare by the 'second' element of the pair) bool operator()(const std::pair<A,B> &a, const std::pair<A,B> &b) { if(a.first<b.first) return true; if(a.first<=b.first && a.second<b.second) return true; return false; } }; template <class Container1, class Container2> void parallel_sort(Container1 &v1,Container2 &v2) { std::vector<std::pair<typename Container1::value_type,typename Container2::value_type> > a; const unsigned int n = std::min(v1.size(),v2.size()); for(unsigned int i=0; i<n; ++i) { a.push_back(std::pair<typename Container1::value_type,typename Container2::value_type>(v1[i],v2[i])); } sort(a.begin(), a.end(), LessThanPairFirst<typename Container1::value_type, typename Container2::value_type>()); for(unsigned int i=0; i<n; ++i) { v1[i] = a[i].first; v2[i] = a[i].second; } } void parallel_sort(std::vector<double> &x, std::vector<double> &y); void parallel_sort(std::vector<blop::var> &x, std::vector<blop::var> &y); void parallel_sort(array &x, array &y); // A utility class to in-line initialize a std::vector. Usage: // vector<int> i = initvector(1)(2)(3)(4)(5); // vector<double> d = initvector(1.1)(2.2)(3.3); // vector<double> d2 = initvector<double>(1)(2)(3); template <typename T> class vector_initializer { private: std::vector<T> vector_; public: vector_initializer(const T &t) { vector_.push_back(t); } vector_initializer<T> &operator()(const T &t) { vector_.push_back(t); return *this; } operator std::vector<T>() const { return vector_; } }; template <typename T> vector_initializer<T> initvector(const T &t) { return vector_initializer<T>(t); } } #endif