Minsky
str.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2013
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef STR_H
20 #define STR_H
21 #include <string>
22 #include <sstream>
23 #include <algorithm>
24 #include <vector>
25 #include <memory>
26 #include <string.h>
27 #include <xvector.h>
28 
29 namespace minsky
30 {
32  // works better than std::to_string
33  template <class T> std::string str(T x) {
34  std::ostringstream s;
35  s<<x;
36  return s.str();
37  }
38 
39  using civita::str;
40 
41  // needed for remove_if below
42  inline bool IsNotalnum(char x) {return !std::isalnum(x);}
43  // strip non alphanum characters - eg signs
44  inline void stripNonAlnum(std::string& x) {
45  x.erase(std::remove_if(x.begin(), x.end(), IsNotalnum), x.end());
46  }
47 
48  // removes white space from beginning and end
49  inline std::string trimWS(const std::string& s)
50  {
51  int start=0, end=s.length()-1;
52  while (start<int(s.length()) && isspace(s[start])) ++start;
53  while (end>=0 && isspace(s[end])) --end;
54  if (end>=start)
55  return s.substr(start,end-start+1);
56  else
57  return "";
58  }
59 
63  inline std::string stripActive(const std::string& s) {
64  std::string r; r.reserve(s.length());
65  for (size_t i=0; i<s.length(); ++i)
66  if (s[i]=='\\')
67  r+="∖";
68  else if (isspace(s[i]))
69  r+="␣";
70  else
71  r+=s[i];
72  if (r.empty()) return "_";
73  return r;
74  }
75 
77  template <class F> struct OnStackExit
78  {
79  F f;
80  OnStackExit(F f): f(f) {}
81  ~OnStackExit() {f();}
82  };
83 
85  template <class F> OnStackExit<F> onStackExit(F f) {return OnStackExit<F>(f);}
86 
88  template <class T, class V>
89  void remove(std::vector<T>& x, const V& v)
90  {x.erase(std::remove(x.begin(),x.end(),v),x.end());}
91 
92  template <class T, class D>
93  std::unique_ptr<T,D> uniqueDeleter(T* x, D d)
94  {return std::unique_ptr<T,D>(x,d);}
95 
98 
100  inline unsigned numBytes(unsigned char x)
101  {
102  if ((x&0xF8) == 0xF0)
103  return 4;
104  if ((x&0xF0) == 0xE0)
105  return 3;
106  if ((x&0xE0) == 0xC0)
107  return 2;
108  return 1;
109  }
110 
112  inline size_t prevIndex(const std::string& str, size_t index)
113  {
114  if (index>str.length()) return prevIndex(str, str.length());
115  for (size_t i=4; i>1; --i)
116  if (index>=i && numBytes(str[index-i])==i)
117  return index-i;
118  return index>0? index-1: 0;
119  }
120 
121  // an iomanip implementing single UTF8 character getting via >>
122  struct GetUtf8Char
123  {
124  std::string* c; // pointer, not ref, to get around constness rules
125  GetUtf8Char(std::string& c): c(&c) {}
126  };
127 
128  inline std::istream& operator>>(std::istream& i, const GetUtf8Char& g)
129  {
130  char c;
131  g.c->clear();
132  if (i.get(c))
133  {
134  *g.c+=c;
135  unsigned n=numBytes(c)-1;
136  for (unsigned j=0; j<n; ++j)
137  {
138  if (i.get(c))
139  *g.c+=c;
140  }
141  }
142  return i;
143  }
144 
147  inline void stripByteOrderingMarker(std::istream& s)
148  {
149  char bom[4]="\0\0\0";
150  s.get(bom,4);
151  if (strcmp(bom,"\357\273\277")==0) return; //skipped BOM
152  if (memcmp(bom,"\0\0\376",3)==0)
153  if (s && s.get()=='\377') // UTF-32(BE) file detected
154  throw std::runtime_error("Only UTF-8 encoded files supported");
155  if (strncmp(bom,"\376\377",2)==0 || strncmp(bom,"\377\376",2)==0)
156  // UTF-16 or UTF-32(LE) file detected
157  throw std::runtime_error("Only UTF-8 encoded files supported");
158  s.seekg(0); //rewind input stream
159  }
160 
162  inline std::string CSVQuote(const std::string& x, char sep)
163  {
164  std::string r;
165  bool needsQuoting=false;
166  for (auto c: x)
167  {
168  r+=c;
169  if (c=='"') {r+='"'; needsQuoting=true;}
170  if (c==sep) needsQuoting=true;
171  }
172  if (needsQuoting) return "\""+r+"\"";
173  return r;
174  }
175 
176 }
177 #endif
function f
Definition: canvas.m:1
GetUtf8Char(std::string &c)
Definition: str.h:125
unsigned numBytes(unsigned char x)
a wrapper around std::ofstream that checks the write succeeded, throwing an exception if not ...
Definition: str.h:100
std::istream & operator>>(std::istream &i, const GetUtf8Char &g)
Definition: str.h:128
void stripNonAlnum(std::string &x)
Definition: str.h:44
arrange for a functional to be called on stack exit
Definition: str.h:77
void remove(std::vector< T > &x, const V &v)
remove an element from a vector. V must be comparable to a T
Definition: str.h:89
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
std::string trimWS(const std::string &s)
Definition: str.h:49
size_t prevIndex(const std::string &str, size_t index)
return index of previous character to index
Definition: str.h:112
std::string stripActive(const std::string &s)
repaces characters that cause interpretation by TCL, backslashes are replaced by the set minus operat...
Definition: str.h:63
OnStackExit< F > onStackExit(F f)
generator function
Definition: str.h:85
std::string str(T x)
utility function to create a string representation of a numeric type
Definition: str.h:33
std::string * c
Definition: str.h:124
OnStackExit(F f)
Definition: str.h:80
std::unique_ptr< T, D > uniqueDeleter(T *x, D d)
Definition: str.h:93
bool IsNotalnum(char x)
Definition: str.h:42
std::string CSVQuote(const std::string &x, char sep)
quotes a string if it contains a separator character, and double quotes quotes
Definition: str.h:162
void stripByteOrderingMarker(std::istream &s)
checks if the input stream has the UTF-8 byte ordering marker, and removes it if present ...
Definition: str.h:147