summaryrefslogtreecommitdiffstats
path: root/util.h
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-09-02 16:14:08 -0700
committerJosh Stone <jistone@redhat.com>2009-09-02 16:14:08 -0700
commitaca66a36681ac7cbf7fcc2eac4dafc83d6559ef9 (patch)
tree0e8f39ae14f5793b37b0565c4a17811b696c9f9b /util.h
parentd185503c723ded087ff987e8fa08c2418e60006b (diff)
downloadsystemtap-steved-aca66a36681ac7cbf7fcc2eac4dafc83d6559ef9.tar.gz
systemtap-steved-aca66a36681ac7cbf7fcc2eac4dafc83d6559ef9.tar.xz
systemtap-steved-aca66a36681ac7cbf7fcc2eac4dafc83d6559ef9.zip
Unify lex_cast* and avoid string copies
We always use lex_cast either to string or from string, so I made that explicit, and got rid of some string copies in the process. There was also stringify(), which was redundant to lex_cast<string>. We also always used lex_cast_hex to string, so that's now hard-coded and again eliminated a string copy. For lex_cast_qstring<string>, there's no need to write the streamify the input, so a specialization now operates directly on the input. Hopefully this is a bit cleaner, and I do measure it to be a little faster on scripts with many probes.
Diffstat (limited to 'util.h')
-rw-r--r--util.h68
1 files changed, 36 insertions, 32 deletions
diff --git a/util.h b/util.h
index 1577bb54..b38d01fd 100644
--- a/util.h
+++ b/util.h
@@ -23,38 +23,35 @@ int kill_stap_spawn(int sig);
// stringification generics
-template <typename T>
-inline std::string
-stringify(T t)
+template <typename IN>
+inline std::string lex_cast(IN const & in)
{
- std::ostringstream s;
- s << t;
- return s.str ();
+ std::ostringstream ss;
+ if (!(ss << in))
+ throw std::runtime_error("bad lexical cast");
+ return ss.str();
}
-template <typename OUT, typename IN>
-inline OUT lex_cast(IN const & in)
+template <typename OUT>
+inline OUT lex_cast(std::string const & in)
{
- std::stringstream ss;
+ std::istringstream ss(in);
OUT out;
- // NB: ss >> string out assumes that "in" renders to one word
- if (!(ss << in && ss >> out))
+ if (!(ss >> out && ss.eof()))
throw std::runtime_error("bad lexical cast");
return out;
}
-template <typename OUT, typename IN>
-inline OUT
+template <typename IN>
+inline std::string
lex_cast_hex(IN const & in)
{
- std::stringstream ss;
- OUT out;
- // NB: ss >> string out assumes that "in" renders to one word
- if (!(ss << "0x" << std::hex << in && ss >> out))
+ std::ostringstream ss;
+ if (!(ss << std::showbase << std::hex << in))
throw std::runtime_error("bad lexical cast");
- return out;
+ return ss.str();
}
@@ -65,32 +62,39 @@ inline std::string
lex_cast_qstring(IN const & in)
{
std::stringstream ss;
- std::string out, out2;
if (!(ss << in))
throw std::runtime_error("bad lexical cast");
- out = ss.str(); // "in" is expected to render to more than one word
- out2 += '"';
- for (unsigned i=0; i<out.length(); i++)
+ return lex_cast_qstring(ss.str());
+}
+
+
+template <>
+inline std::string
+lex_cast_qstring(std::string const & in)
+{
+ std::string out;
+ out += '"';
+ for (const char *p = in.c_str(); *p; ++p)
{
- unsigned char c = out[i];
+ unsigned char c = *p;
if (! isprint(c))
{
- out2 += '\\';
+ out += '\\';
// quick & dirty octal converter
- out2 += "01234567" [(c >> 6) & 0x07];
- out2 += "01234567" [(c >> 3) & 0x07];
- out2 += "01234567" [(c >> 0) & 0x07];
+ out += "01234567" [(c >> 6) & 0x07];
+ out += "01234567" [(c >> 3) & 0x07];
+ out += "01234567" [(c >> 0) & 0x07];
}
else if (c == '"' || c == '\\')
{
- out2 += '\\';
- out2 += c;
+ out += '\\';
+ out += c;
}
else
- out2 += c;
+ out += c;
}
- out2 += '"';
- return out2;
+ out += '"';
+ return out;
}
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */