Movie editor: Backport UTF-32 stuff from master
[lsnes.git] / include / library / string.hpp
bloba70decee06e06b649d57352467c56a9700baa861
1 #ifndef _library__string__hpp__included__
2 #define _library__string__hpp__included__
4 #include <string>
5 #include <sstream>
6 #include <stdexcept>
7 #include <vector>
8 #include <boost/lexical_cast.hpp>
9 #include "utf8.hpp"
11 /**
12 * Strip trailing CR if any.
14 std::string strip_CR(const std::string& str);
16 /**
17 * Strip trailing CR if any.
19 void istrip_CR(std::string& str);
21 /**
22 * Return first character or -1 if empty.
24 int firstchar(const std::string& str);
26 /**
27 * String formatter
29 class stringfmt
31 public:
32 stringfmt() {}
33 std::string str() { return x.str(); }
34 std::u32string str32() { return to_u32string(x.str()); }
35 template<typename T> stringfmt& operator<<(const T& y) { x << y; return *this; }
36 void throwex() { throw std::runtime_error(x.str()); }
37 private:
38 std::ostringstream x;
41 /**
42 * Extract token out of string.
44 * Parameter str: The original string and the rest of the string on return.
45 * Parameter tok: The extracted token will be written here.
46 * Parameter sep: The characters to split on (empty always extracts the rest).
47 * Parameter seq: If true, skip whole sequence of token ending characters.
48 * Returns: The character token splitting occured on (-1 if end of string, -2 if string is empty).
50 int extract_token(std::string& str, std::string& tok, const char* sep, bool seq = false) throw(std::bad_alloc);
52 class regex_results
54 public:
55 regex_results();
56 regex_results(std::vector<std::string> res);
57 operator bool() const;
58 bool operator!() const;
59 size_t size() const;
60 const std::string& operator[](size_t i) const;
61 private:
62 bool matched;
63 std::vector<std::string> results;
66 /**
67 * Regexp a string and return matches.
69 * Parameter regex: The regexp to apply.
70 * Parameter str: The string to apply the regexp to.
71 * Parameter ex: If non-null and string does not match, throw this as std::runtime_error.
72 * Returns: The captures.
74 regex_results regex(const std::string& regex, const std::string& str, const char* ex = NULL)
75 throw(std::bad_alloc, std::runtime_error);
77 /**
78 * Regexp a string and return match result.
80 * Parameter regex: The regexp to apply.
81 * Parameter str: The string to apply the regexp to.
82 * Returns: True if matches, false if not.
84 bool regex_match(const std::string& regex, const std::string& str) throw(std::bad_alloc, std::runtime_error);
86 /**
87 * Cast string to bool.
89 * The following is true: 'on', 'true', 'yes', '1', 'enable', 'enabled'.
90 * The following is false: 'off', 'false', 'no', '0', 'disable', 'disabled'.
91 * Parameter str: The string to cast.
92 * Returns: -1 if string is bad, 0 if false, 1 if true.
94 int string_to_bool(const std::string& cast_to_bool);
96 /**
97 * \brief Typeconvert string.
99 template<typename T> inline T parse_value(const std::string& value) throw(std::bad_alloc, std::runtime_error)
101 try {
102 //Hack, since lexical_cast lets negative values slip through.
103 if(!std::numeric_limits<T>::is_signed && value.length() && value[0] == '-') {
104 throw std::runtime_error("Unsigned values can't be negative");
106 //Hack for inability of lexical_cast to deal with chars like we want.
107 if(sizeof(T) > 1)
108 return boost::lexical_cast<T>(value);
109 else {
110 short v = boost::lexical_cast<short>(value);
111 if(v > 255 || v < -128 || (v > 127 && std::numeric_limits<T>::is_signed))
112 throw std::runtime_error("Value out of range");
113 return static_cast<T>(v);
115 } catch(std::exception& e) {
116 throw std::runtime_error("Can't parse value '" + value + "': " + e.what());
120 template<> inline std::string parse_value(const std::string& value) throw(std::bad_alloc, std::runtime_error)
122 return value;
125 #endif