1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22#ifndef __STRING_H__ 23#define __STRING_H__ 24 25#include <string> 26#include <cstdarg> 27#include <vector> 28#include <sstream> 29#include <bitset> 30 31namespace LibUtil 32{ 33 using std::string; 34 using std::vector; 35 36 class String : public string 37 { 38 public: 39 static String format(const String& format_, ...); 40 static String format(const String& format_, va_list args_); 41 template<class T> static String toString(const T& value_); 42 static String toBitString(unsigned int value_, unsigned int num_bits_); 43 template<class T> static T fromString(const String& str_); 44 45 private: 46 static const unsigned int msBufferSize; 47 48 public: 49 String(); 50 String(const string& str_); 51 String(const char* str_, size_t n); 52 String(const char* str_); 53 String(size_t n, char c); 54 String(int value_); 55 String(unsigned int value_); 56 String(long value_); 57 String(unsigned long value_); 58 String(float value_); 59 String(double value_); 60 String(bool value_); 61 ~String(); 62 63 public: 64 // Remove leading and trailing whitespace 65 String& trim(); 66 // Substitute str1 with str2 67 String& substitute(const String& str1_, const String& str2_); 68 // Split the String into vector of Strings separated by delimiters_ 69 vector<String> split(const char* delimiters_) const; 70 vector<String> split(const String* delimiters_, unsigned int num_delimiters_ = 1) const; 71 vector<String> splitByString(const String& delimiters_) const; 72 73 // Check if contains str 74 bool contain(const String& str_) const; 75 76 public: 77 // Convertions 78 const char* toCString() const; 79 int toInt() const; 80 unsigned int toUInt() const; 81 long toLong() const; 82 unsigned long toULong() const; 83 float toFloat() const; 84 double toDouble() const; 85 bool toBool() const; 86 operator const char*() const; 87 operator int() const; 88 operator unsigned int() const; 89 operator long() const; 90 operator unsigned long() const; 91 operator float() const; 92 operator double() const; 93 operator bool() const; 94 String& operator=(char c_); 95 }; 96 97 template<class T> String String::toString(const T& value_) 98 { 99 std::ostringstream ost; 100 ost << value_; 101 return ost.str(); 102 } 103 104 template<> inline String String::toString<bool>(const bool& value_) 105 { 106 if(value_ == true) 107 { 108 return "TRUE"; 109 } 110 else 111 { 112 return "FALSE"; 113 } 114 } 115 116 inline String String::toBitString(unsigned int value_, unsigned int num_bits_) 117 { 118 std::bitset<sizeof(unsigned int)*8> bitSet(value_); 119 String ret = String(bitSet.to_string()); 120 ret = ret.substr(ret.length()-num_bits_); 121 return ret; 122 } 123 124 template<class T> T String::fromString(const String& str_) 125 { 126 T ret; 127 std::istringstream ist(str_); 128 ist >> ret; 129 return ret; 130 } 131 132 template<> inline String String::fromString<String>(const String& str_) 133 { 134 return str_; 135 } 136 137 template<> inline bool String::fromString<bool>(const String& str_) 138 { 139 bool ret; 140 if((str_ == String("TRUE")) || (str_ == String("true"))) 141 { 142 ret = true; 143 } 144 else if((str_ == string("FALSE")) || (str_ == String("false"))) 145 { 146 ret = false; 147 } 148 else 149 { 150 //std::cerr << "Invalid bool value: " << str_ << std::endl; 151 throw ("Invalid bool value: " + str_); 152 } 153 return ret; 154 } 155 156 template<class T> String arrayToString( 157 const T* array_, unsigned int start_index_, unsigned int end_index_, 158 const String& delimiters_ 159 ) 160 { 161 // Ensure end_index_ >= start_index_ + 1 162 if(end_index_ <= start_index_) 163 { 164 throw("Invalid index range: start_index = " + (String)start_index_ + ", end_index = " + (String)end_index_); 165 } 166 167 String ret = "["; 168 for(unsigned int i = start_index_; i < (end_index_-1); ++i) 169 { 170 ret += (String)array_[i] + delimiters_; 171 } 172 ret += (String)array_[end_index_-1] + "]"; 173 return ret; 174 } 175 176 template<class T> String arrayToString(const T* array_, unsigned int num_elements_) 177 { 178 return arrayToString(array_, 0, num_elements_, ", "); 179 } 180 181 template<class T> String arrayToString(const T* array_, unsigned int start_index_, unsigned int end_index_) 182 { 183 return arrayToString(array_, start_index_, end_index_); 184 } 185 186 template<class T> String vectorToString( 187 const vector<T>& vector_, unsigned int start_index_, unsigned int end_index_, 188 const String& delimiters_ 189 ) 190 { 191 // Ensure end_index_ >= start_index_ + 1, or if the vector is empty 192 if((end_index_ <= start_index_) || (end_index_ > vector_.size())) 193 { 194 // If the vector is empty, return empty array 195 if (vector_.size() == 0) 196 return "[]"; 197 198 throw("Invalid index range: start_index = " + (String)start_index_ + ", end_index = " + (String)end_index_); 199 } 200 201 String ret = "["; 202 for(unsigned int i = start_index_; i < (end_index_-1); ++i) 203 { 204 ret += (String)vector_[i] + delimiters_; 205 } 206 ret += (String)vector_[end_index_-1] + "]"; 207 return ret; 208 } 209 210 template<class T> String vectorToString(const vector<T>& vector_) 211 { 212 return vectorToString(vector_, 0, vector_.size(), ", "); 213 } 214 215 template<class T> String vectorToString(const vector<T>& vector_, unsigned int num_elements_) 216 { 217 return vectorToString(vector_, 0, num_elements_, ", "); 218 } 219 220 template<class T> String vectorToString(const vector<T>& vector_, unsigned int start_index_, unsigned int end_index_) 221 { 222 return vectorToString(vector_, start_index_, end_index_); 223 } 224 225 template<class T> vector<T> castStringVector(const vector<String>& vector_) 226 { 227 vector<T> ret_vector; 228 for(unsigned int i = 0; i < vector_.size(); ++i) 229 { 230 ret_vector.push_back((T)vector_[i]); 231 } 232 return ret_vector; 233 } 234 235 std::istream& safeGetline(std::istream& is_, String& str_); 236} // namespace LibUtil 237 238#endif // __STRING_H__ 239 240