]>
Commit | Line | Data |
---|---|---|
aa389a19 FCE |
1 | // -*- C++ -*- |
2 | // Copyright (C) 2015 Red Hat Inc. | |
3 | // | |
4 | // This file is part of systemtap, and is free software. You can | |
5 | // redistribute it and/or modify it under the terms of the GNU General | |
6 | // Public License (GPL); either version 2, or (at your option) any | |
7 | // later version. | |
8 | ||
9 | ||
10 | #ifndef STRINGTABLE_H | |
11 | #define STRINGTABLE_H | |
12 | ||
13 | #include <string> | |
3dd76f53 AJ |
14 | #include <cstring> |
15 | ||
16 | #if defined(HAVE_BOOST_UTILITY_STRING_REF_HPP) | |
91f252b7 | 17 | #include <boost/version.hpp> |
aa389a19 FCE |
18 | #include <boost/utility/string_ref.hpp> //header with string_ref |
19 | ||
7eae03f8 FCE |
20 | // XXX: experimental tunables |
21 | #define INTERNED_STRING_FIND_MEMMEM 1 /* perf stat indicates a very slight benefit */ | |
22 | #define INTERNED_STRING_CUSTOM_HASH 1 /* maybe an abbreviated hash function for long strings? */ | |
924f8d22 | 23 | #define INTERNED_STRING_INSTRUMENT 0 /* write out hash logs ... super super slow */ |
47d349b1 FCE |
24 | |
25 | struct interned_string: public boost::string_ref | |
26 | { | |
27 | // all these construction operations intern the incoming string | |
3e4547ad | 28 | interned_string(): boost::string_ref() {} |
47d349b1 FCE |
29 | interned_string(const char* value); |
30 | interned_string(const std::string& value); | |
47d349b1 FCE |
31 | interned_string& operator = (const std::string& value); |
32 | interned_string& operator = (const char* value); | |
91f252b7 AJ |
33 | |
34 | #if BOOST_VERSION < 105400 | |
35 | std::string to_string () const { return std::string(this->data(), this->size()); } | |
36 | ||
37 | // some comparison operators that aren't available in boost 1.53 | |
38 | bool operator == (const char* y) { return compare(boost::string_ref(y)) == 0; } | |
39 | bool operator == (const std::string& y) { return compare(boost::string_ref(y)) == 0; } | |
40 | friend bool operator == (interned_string x, interned_string y) { return x.compare(y) == 0; } | |
41 | friend bool operator == (const char * x, interned_string y) | |
42 | { | |
43 | return y.compare(boost::string_ref(x)) == 0; | |
44 | } | |
45 | friend bool operator == (const std::string& x, interned_string y) | |
46 | { | |
47 | return y.compare(boost::string_ref(x)) == 0; | |
48 | } | |
49 | ||
50 | bool operator != (const char* y) { return compare(boost::string_ref(y)) != 0; } | |
51 | bool operator != (const std::string& y) { return compare(boost::string_ref(y)) != 0; } | |
52 | friend bool operator != (interned_string x, interned_string y) { return x.compare(y) != 0; } | |
53 | friend bool operator != (const char * x, interned_string y) | |
54 | { | |
55 | return y.compare(boost::string_ref(x)) != 0; | |
56 | } | |
57 | friend bool operator != (const std::string& x, interned_string y) | |
58 | { | |
59 | return y.compare(boost::string_ref(x)) != 0; | |
60 | } | |
61 | #endif | |
62 | ||
47d349b1 | 63 | // easy out-conversion operators |
45a63356 | 64 | operator std::string () const { return this->to_string(); } |
3e4547ad | 65 | |
7371cd19 | 66 | // return an efficient substring reference |
07ebb812 FCE |
67 | interned_string substr(size_t pos = 0, size_t len = npos) const |
68 | { | |
7371cd19 | 69 | return boost::string_ref::substr(pos, len); |
07ebb812 | 70 | } |
45a63356 FCE |
71 | |
72 | // boost oversights | |
73 | template <typename F> | |
7eae03f8 | 74 | size_t find (const F& f, size_t start_pos) |
45a63356 | 75 | { |
7371cd19 | 76 | size_t x = this->substr(start_pos).find(f); |
45a63356 FCE |
77 | if (x == boost::string_ref::npos) |
78 | return x; | |
79 | else | |
80 | return x + start_pos; | |
81 | } | |
82 | ||
83 | template <typename F> | |
7eae03f8 | 84 | size_t find (const F& f) const |
45a63356 FCE |
85 | { |
86 | return boost::string_ref::find(f); | |
87 | } | |
7eae03f8 FCE |
88 | |
89 | #if INTERNED_STRING_FIND_MEMMEM | |
90 | size_t find (const boost::string_ref& f) const; | |
91 | size_t find (const std::string& f) const; | |
92 | size_t find (const char *f) const; | |
93 | #endif | |
45a63356 | 94 | |
47d349b1 | 95 | private: |
07ebb812 | 96 | static interned_string intern(const std::string& value); |
7371cd19 JS |
97 | |
98 | // This is private so we can be sure of ownership, from our interned string table. | |
99 | interned_string(const boost::string_ref& value): boost::string_ref(value) {} | |
47d349b1 | 100 | }; |
3dd76f53 | 101 | #else /* !defined(HAVE_BOOST_UTILITY_STRING_REF_HPP) */ |
47d349b1 | 102 | |
3dd76f53 AJ |
103 | struct interned_string : public std::string { |
104 | interned_string(): std::string() {} | |
105 | interned_string(const char* value): std::string (value ? :"") {} | |
106 | interned_string(const std::string& value): std::string(value) {} | |
107 | std::string to_string() const {return (std::string) *this; } | |
108 | void remove_prefix (size_t n) {*this = this->substr(n);} | |
109 | interned_string substr(size_t pos = 0, size_t len = npos) const | |
110 | { | |
111 | return (interned_string)std::string::substr(pos, len); | |
112 | } | |
113 | bool starts_with(const char* value) const | |
114 | { | |
115 | return (this->compare(0, std::strlen(value), value) == 0); | |
116 | } | |
117 | ||
118 | bool starts_with(const std::string& value) const | |
119 | { | |
120 | return (this->compare(0, value.length(), value) == 0); | |
121 | } | |
7371cd19 JS |
122 | |
123 | private: | |
124 | // c_str is not allowed on boost::string_ref, so add a private unimplemented | |
125 | // declaration here to prevent the use of string::c_str accidentally. | |
126 | const char* c_str() const; | |
3dd76f53 | 127 | }; |
47d349b1 | 128 | |
3dd76f53 | 129 | #endif /* defined(HAVE_BOOST_UTILITY_STRING_REF_HPP) */ |
47d349b1 | 130 | |
aa389a19 FCE |
131 | |
132 | #endif // STRINGTABLE_H | |
133 | ||
134 | /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ |