00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00017 #ifndef __DERS__TEXT_HPP__
00018 #define __DERS__TEXT_HPP__
00019
00020 #include <ders/config.hpp>
00021 #include <ders/sh_ptr.hpp>
00022
00023 namespace ders {
00024
00025 struct ch_rng;
00026
00027 class text;
00028 typedef sh_ptr<text> sh_text;
00029
00030 sh_text nt(mem_pool& mp);
00031 sh_text nt(mem_pool& mp, const char* str);
00032 sh_text nt(mem_pool& mp, const char* b, const char* e);
00033 sh_text nt(mem_pool& mp, const ch_rng& r);
00034 sh_text nt(mem_pool& mp, const text& t);
00035 sh_text nt(mem_pool& mp, const sh_text& sht);
00036
00037 bool operator==(const ch_rng& r1, const ch_rng& r2);
00038 bool operator!=(const ch_rng& r1, const ch_rng& r2);
00039 bool operator< (const ch_rng& r1, const ch_rng& r2);
00040 bool operator<=(const ch_rng& r1, const ch_rng& r2);
00041 bool operator> (const ch_rng& r1, const ch_rng& r2);
00042 bool operator>=(const ch_rng& r1, const ch_rng& r2);
00043
00047 struct ch_rng {
00048 const char* beg;
00049 const char* end;
00050
00051 ch_rng(const char* str);
00052 ch_rng(const char* b, const char* e);
00053 ch_rng(const text& t);
00054 ch_rng(const sh_text& sht);
00055
00056 int size() const { return end-beg; }
00057 };
00058
00062 class text {
00063 mem_pool& mp;
00064 char* buf;
00065 int resd;
00066 int used;
00067
00068 void init(const ch_rng& r);
00069
00070 public:
00071 explicit text(mem_pool& m) : mp(m) { init(ch_rng(0, 0)); }
00072 text(mem_pool& m, const ch_rng& r) : mp(m) { init(r); }
00073 text(const text& t) : mp(t.mp) { init(ch_rng(t)); }
00074 ~text() { mp.deallocate(buf, resd); }
00075
00076 text& operator=(const text& t) { return *this=ch_rng(t); }
00077 text& operator=(const ch_rng& r);
00078
00079 text& append(const ch_rng& r);
00080 text& append(char byte);
00081
00082 int size() const { return used; }
00083 int capacity() const { return resd; }
00084
00085 void reserve(int sz);
00086 void clear() { used=0; }
00087 void uninitialized_resize(int sz);
00088
00089 char* begin() { return buf; }
00090 const char* begin() const { return buf; }
00091 char* end() { return buf+used; }
00092 const char* end() const { return buf+used; }
00093
00094 const char* c_str() const;
00095
00096 char& front() { return *begin(); }
00097 char front() const { return *begin(); }
00098 char& back() { return *(end()-1); }
00099 char back() const { return *(end()-1); }
00100
00101 char* find(char ch);
00102 const char* find(char ch) const;
00103 char* rfind(char ch);
00104 const char* rfind(char ch) const;
00105
00106 char* find(const ch_rng& r);
00107 const char* find(const ch_rng& r) const;
00108 char* rfind(const ch_rng& r);
00109 const char* rfind(const ch_rng& r) const;
00110
00111 bool starts(const ch_rng& r) const;
00112 bool ends(const ch_rng& r) const;
00113 };
00114
00115 namespace detail {
00116
00117 int compare(const ch_rng& r1, const ch_rng& r2);
00118
00119 }
00120
00121 inline sh_text nt(mem_pool& mp)
00122 { return nt(mp, ch_rng(0, 0)); }
00123
00124 inline sh_text nt(mem_pool& mp, const char* str)
00125 { return nt(mp, ch_rng(str)); }
00126
00127 inline sh_text nt(mem_pool& mp, const char* b, const char* e)
00128 { return nt(mp, ch_rng(b, e)); }
00129
00130 inline sh_text nt(mem_pool& mp, const text& t)
00131 { return nt(mp, ch_rng(t)); }
00132
00133 inline sh_text nt(mem_pool& mp, const sh_text& sht)
00134 { return nt(mp, ch_rng(sht)); }
00135
00136 inline bool operator!=(const ch_rng& r1, const ch_rng& r2)
00137 { return !(r1==r2); }
00138
00139 inline bool operator<(const ch_rng& r1, const ch_rng& r2)
00140 { return detail::compare(r1, r2)<0; }
00141
00142 inline bool operator<=(const ch_rng& r1, const ch_rng& r2)
00143 { return detail::compare(r1, r2)<=0; }
00144
00145 inline bool operator>(const ch_rng& r1, const ch_rng& r2)
00146 { return detail::compare(r1, r2)>0; }
00147
00148 inline bool operator>=(const ch_rng& r1, const ch_rng& r2)
00149 { return detail::compare(r1, r2)>=0; }
00150
00151 inline ch_rng::ch_rng(const char* b, const char* e) : beg(b), end(e)
00152 { assert(beg!=0 && beg<=end || beg==0 && end==0); }
00153
00154 inline ch_rng::ch_rng(const text& t) : beg(t.begin()), end(t.end())
00155 { assert(beg!=0 && beg<=end); }
00156
00157 inline ch_rng::ch_rng(const sh_text& sht) : beg(sht->begin()), end(sht->end())
00158 { assert(beg!=0 && beg<=end); }
00159
00160 inline const char* text::find(char ch) const
00161 { return const_cast<text*>(this)->find(ch); }
00162
00163 inline const char* text::rfind(char ch) const
00164 { return const_cast<text*>(this)->rfind(ch); }
00165
00166 inline const char* text::find(const ch_rng& r) const
00167 { return const_cast<text*>(this)->find(r); }
00168
00169 inline const char* text::rfind(const ch_rng& r) const
00170 { return const_cast<text*>(this)->rfind(r); }
00171
00172 }
00173
00174 #endif // __DERS__TEXT_HPP__
00175