Updated tstring to use t_token as a replacement for string...

...to speed up comparisons, copying and hashing.
This commit is contained in:
Thonsew 2011-09-08 19:15:47 +00:00
parent 3d29107eff
commit 87b5cd1ec4
2 changed files with 96 additions and 47 deletions

View File

@ -44,6 +44,7 @@ namespace {
std::vector<std::string> id_to_textdomain;
std::map<std::string, unsigned int> textdomain_to_id;
static const n_token::t_token z_empty("");
}
size_t t_string_base::hash_value() const {
@ -214,6 +215,14 @@ t_string_base::t_string_base(const t_string_base& string) :
{
}
t_string_base::t_string_base(const t_token& string) :
value_(string),
translated_value_(),
translation_timestamp_(0),
translatable_(false),
last_untranslatable_(false)
{
}
t_string_base::t_string_base(const std::string& string) :
value_(string),
translated_value_(),
@ -224,14 +233,14 @@ t_string_base::t_string_base(const std::string& string) :
}
t_string_base::t_string_base(const std::string& string, const std::string& textdomain) :
value_(1, ID_TRANSLATABLE_PART),
value_(std::string(1, ID_TRANSLATABLE_PART)),
translated_value_(),
translation_timestamp_(0),
translatable_(true),
last_untranslatable_(false)
{
if (string.empty()) {
value_.clear();
value_ = z_empty;
translatable_ = false;
return;
}
@ -247,9 +256,9 @@ t_string_base::t_string_base(const std::string& string, const std::string& textd
id = idi->second;
}
value_ += char(id & 0xff);
value_ += char(id >> 8);
value_ += string;
value_ = t_token(static_cast<std::string const &>(value_) + char(id & 0xff));
value_ = t_token(static_cast<std::string const &>(value_) + char(id >> 8));
value_ = t_token(static_cast<std::string const &>(value_) + string );
}
t_string_base::t_string_base(const char* string) :
@ -306,11 +315,11 @@ std::string t_string_base::to_serialized() const
if(w.translatable()) {
chunk.translatable_ = true;
chunk.last_untranslatable_ = false;
chunk.value_ = TRANSLATABLE_PART + w.textdomain() +
TEXTDOMAIN_SEPARATOR + substr;
chunk.value_ = t_token( TRANSLATABLE_PART + w.textdomain() +
TEXTDOMAIN_SEPARATOR + substr );
} else {
chunk.translatable_ = false;
chunk.value_ = substr;
chunk.value_ = t_token(substr);
}
res += chunk;
@ -330,21 +339,22 @@ t_string_base& t_string_base::operator=(const t_string_base& string)
return *this;
}
t_string_base& t_string_base::operator=(const std::string& string)
t_string_base& t_string_base::operator=(const t_token& string)
{
value_ = string;
translated_value_ = "";
translated_value_ = z_empty;
translation_timestamp_ = 0;
translatable_ = false;
last_untranslatable_ = false;
return *this;
}
t_string_base& t_string_base::operator=(const std::string& string){ return operator=(t_token(string));}
t_string_base& t_string_base::operator=(const char* string)
{
value_ = string;
translated_value_ = "";
value_ = t_token(string);
translated_value_ = z_empty;
translation_timestamp_ = 0;
translatable_ = false;
last_untranslatable_ = false;
@ -359,13 +369,19 @@ t_string_base t_string_base::operator+(const t_string_base& string) const
return res;
}
t_string_base t_string_base::operator+(const std::string& string) const
t_string_base t_string_base::operator+(const t_token& string) const
{
t_string_base res(*this);
res += string;
return res;
}
t_string_base t_string_base::operator+(const std::string& string) const{
t_string_base res(*this);
res += string;
return res;
}
t_string_base t_string_base::operator+(const char* string) const
{
t_string_base res(*this);
@ -384,32 +400,33 @@ t_string_base& t_string_base::operator+=(const t_string_base& string)
if(translatable_ || string.translatable_) {
if(!translatable_) {
value_ = UNTRANSLATABLE_PART + value_;
value_ = t_token(UNTRANSLATABLE_PART + static_cast<std::string const &>(value_));
translatable_ = true;
last_untranslatable_ = true;
} else
translated_value_ = "";
} else {
translated_value_ = z_empty;
}
if(string.translatable_) {
if (last_untranslatable_ && string.value_[0] == UNTRANSLATABLE_PART)
value_.append(string.value_.begin() + 1, string.value_.end());
if (last_untranslatable_ && (static_cast<std::string const &>(string.value_))[0] == UNTRANSLATABLE_PART)
value_= t_token(static_cast<std::string const &>(value_) + std::string(static_cast<std::string const &>(string.value_).begin() + 1, static_cast<std::string const &>(string.value_).end()) );
else
value_ += string.value_;
value_ = t_token(static_cast<std::string const &>(value_) + static_cast<std::string const &>(string.value_));
last_untranslatable_ = string.last_untranslatable_;
} else {
if (!last_untranslatable_) {
value_ += UNTRANSLATABLE_PART;
value_ = t_token(static_cast<std::string const &>(value_) + UNTRANSLATABLE_PART);
last_untranslatable_ = true;
}
value_ += string.value_;
value_ = t_token(static_cast<std::string const &>(value_) + static_cast<std::string const &>(string.value_));
}
} else {
value_ += string.value_;
value_ = t_token(static_cast<std::string const &>(value_) + static_cast<std::string const &>(string.value_));
}
return *this;
}
t_string_base& t_string_base::operator+=(const std::string& string)
t_string_base& t_string_base::operator+=(const t_token& string)
{
if (string.empty())
return *this;
@ -420,17 +437,18 @@ t_string_base& t_string_base::operator+=(const std::string& string)
if(translatable_) {
if (!last_untranslatable_) {
value_ += UNTRANSLATABLE_PART;
value_ = t_token(static_cast<std::string const &>(value_) + UNTRANSLATABLE_PART);
last_untranslatable_ = true;
}
value_ += string;
translated_value_ = "";
value_ = t_token( static_cast<std::string const &>( value_) + static_cast<std::string const &>( string));
translated_value_ = z_empty;
} else {
value_ += string;
value_ = t_token( static_cast<std::string const &>( value_ )+ static_cast<std::string const &>( string));
}
return *this;
}
t_string_base& t_string_base::operator+=(const std::string& string) {return operator+=(t_token(string));}
t_string_base& t_string_base::operator+=(const char* string)
{
@ -443,13 +461,13 @@ t_string_base& t_string_base::operator+=(const char* string)
if(translatable_) {
if (!last_untranslatable_) {
value_ += UNTRANSLATABLE_PART;
value_ = t_token(static_cast<std::string const &>(value_) + UNTRANSLATABLE_PART );
last_untranslatable_ = true;
}
value_ += string;
translated_value_ = "";
value_ = t_token(static_cast<std::string const &>(value_ ) + string);
translated_value_ = z_empty;
} else {
value_ += string;
value_ = t_token(static_cast<std::string const &>(value_ ) + string);
}
return *this;
@ -462,12 +480,12 @@ bool t_string_base::operator==(const t_string_base &that) const
bool t_string_base::operator==(const std::string &that) const
{
return !translatable_ && value_ == that;
return !translatable_ && value_ == t_token(that);
}
bool t_string_base::operator==(const char *that) const
{
return !translatable_ && value_ == that;
return !translatable_ && value_ == t_token(std::string(that));
}
bool t_string_base::operator<(const t_string_base &that) const
@ -475,7 +493,7 @@ bool t_string_base::operator<(const t_string_base &that) const
return value_ < that.value_;
}
const std::string& t_string_base::str() const
const t_string_base::t_token& t_string_base::token() const
{
if(!translatable_)
return value_;
@ -483,15 +501,15 @@ const std::string& t_string_base::str() const
if (translatable_ && !translated_value_.empty() && translation_timestamp_ == language_counter)
return translated_value_;
translated_value_.clear();
translated_value_=z_empty;
for(walker w(*this); !w.eos(); w.next()) {
std::string part(w.begin(), w.end());
if(w.translatable()) {
translated_value_ += dsgettext(w.textdomain().c_str(), part.c_str());
translated_value_ = t_token(static_cast<std::string const &>(translated_value_ ) + dsgettext(w.textdomain().c_str(), part.c_str()));
} else {
translated_value_ += part;
translated_value_ = t_token(static_cast<std::string const &>(translated_value_ ) + part);
}
}
@ -519,6 +537,9 @@ t_string::t_string(const char *o) : super(base(o))
{
}
t_string::t_string(const t_token &o) : super(base(o))
{
}
t_string::t_string(const std::string &o) : super(base(o))
{
}
@ -526,6 +547,8 @@ t_string::t_string(const std::string &o) : super(base(o))
t_string::t_string(const std::string &o, const std::string &textdomain) : super(base(o, textdomain))
{
}
t_string &t_string::operator=(t_token const &o) { super::operator=(base(o)); return *this; }
t_string &t_string::operator=(std::string const &o) { super::operator=(base(o)); return *this; }
t_string &t_string::operator=(const t_string &o)
{

View File

@ -19,6 +19,7 @@
#include "shared_object.hpp"
#include <string>
#include "token.hpp"
/**
* Helper class for translatable strings.
@ -27,6 +28,7 @@ class t_string;
class t_string_base
{
public:
typedef n_token::t_token t_token;
class walker
{
public:
@ -63,6 +65,7 @@ public:
~t_string_base();
/** Default implementation, but defined out-of-line for efficiency reasons. */
t_string_base(const t_string_base&);
t_string_base(const t_token& string);
t_string_base(const std::string& string);
t_string_base(const std::string& string, const std::string& textdomain);
t_string_base(const char* string);
@ -72,35 +75,39 @@ public:
/** Default implementation, but defined out-of-line for efficiency reasons. */
t_string_base& operator=(const t_string_base&);
t_string_base& operator=(const t_token&);
t_string_base& operator=(const std::string&);
t_string_base& operator=(const char*);
t_string_base operator+(const t_string_base&) const;
t_string_base operator+(const t_token&) const;
t_string_base operator+(const std::string&) const;
t_string_base operator+(const char*) const;
t_string_base& operator+=(const t_string_base&);
t_string_base& operator+=(const t_token&);
t_string_base& operator+=(const std::string&);
t_string_base& operator+=(const char*);
bool operator==(const t_string_base &) const;
bool operator==(const t_token & that ) const {return !translatable_ && value_ == that;};
bool operator==(const std::string &) const;
bool operator==(const char* string) const;
bool operator!=(const t_string_base &that) const
{ return !operator==(that); }
bool operator!=(const std::string &that) const
{ return !operator==(that); }
bool operator!=(const char *that) const
{ return !operator==(that); }
bool operator!=(const t_string_base &that) const { return !operator==(that); }
bool operator!=(const t_token &that) const { return !operator==(that); }
bool operator!=(const std::string &that) const { return !operator==(that); }
bool operator!=(const char *that) const { return !operator==(that); }
bool operator<(const t_string_base& string) const;
bool empty() const { return value_.empty(); }
std::string::size_type size() const { return str().size(); }
std::string::size_type size() const { return static_cast<std::string const &>(token()).size(); }
operator const t_token&() const { return token(); }
const t_token& token() const;
operator const std::string&() const { return str(); }
const std::string& str() const;
const std::string& str() const { return static_cast<std::string const &>(token()); }
const char* c_str() const { return str().c_str(); }
bool translatable() const { return translatable_; }
// Warning: value() may contain platform dependant prefix bytes !
@ -110,8 +117,8 @@ public:
size_t hash_value() const;
private:
std::string value_;
mutable std::string translated_value_;
t_token value_;
mutable t_token translated_value_;
mutable unsigned translation_timestamp_;
bool translatable_, last_untranslatable_;
};
@ -125,6 +132,7 @@ public:
typedef shared_object<t_string_base> super;
typedef t_string_base base;
typedef t_string_base::walker walker;
typedef typename base::t_token t_token;
/** Default implementation, but defined out-of-line for efficiency reasons. */
t_string();
@ -137,9 +145,18 @@ public:
t_string(const base &);
t_string(const char *);
explicit t_string(const t_token &);
t_string(const std::string &);
t_string(const std::string &str, const std::string &textdomain);
t_string &operator=(t_token const &);
///todo restore these 2 lines when config::attribute is castable to t_token
// template <typename X> t_string &operator=(X const &o) {
// operator=(static_cast<t_token const &>(o)); return *this; }
template <typename X> t_string &operator=(X const &o) {
operator=(n_token::t_token(o)); return *this; }
t_string &operator=(std::string const &);
t_string &operator=(const char *o);
static t_string from_serialized(const std::string& string) { return t_string(base::from_serialized(string)); }
@ -148,18 +165,22 @@ public:
operator t_string_base() const { return get(); }
t_string operator+(const t_string& o) const { return get() + o.get(); }
t_string operator+(const t_token& o) const { return get() + o; }
t_string operator+(const std::string& o) const { return get() + o; }
t_string operator+(const char* o) const { return get() + o; }
t_string& operator+=(const t_string& o) { set(base(get()) += o.get()); return *this; }
t_string& operator+=(const t_token& o) { set(base(get()) += o); return *this; }
t_string& operator+=(const std::string& o) { set(base(get()) += o); return *this; }
t_string& operator+=(const char* o) { set(base(get()) += o); return *this; }
bool operator==(const t_string& o) const { return get() == o.get(); }
bool operator==(const t_token& o) const { return get() == o; }
bool operator==(const std::string& o) const { return get() == o; }
bool operator==(const char* o) const { return get() == o; }
bool operator!=(const t_string& o) const { return !operator==(o); }
bool operator!=(const t_token& o) const { return !operator==(o); }
bool operator!=(const std::string& o) const { return !operator==(o); }
bool operator!=(const char* o) const { return !operator==(o); }
@ -168,6 +189,8 @@ public:
bool empty() const { return get().empty(); }
std::string::size_type size() const { return get().size(); }
//operator const t_token&() const { return get(); }
const t_token& token() const { return get().token(); }
operator const std::string&() const { return get(); }
const std::string& str() const { return get().str(); }
const char* c_str() const { return get().c_str(); }
@ -181,10 +204,13 @@ public:
const t_string_base& get() const { return super::get(); }
};
inline std::ostream& operator<<(std::ostream& os, const t_string& str) { return os << str.get(); }
inline bool operator==(const n_token::t_token &a, const t_string &b) { return b == a; }
inline bool operator==(const std::string &a, const t_string &b) { return b == a; }
inline bool operator==(const char *a, const t_string &b) { return b == a; }
inline bool operator!=(const n_token::t_token &a, const t_string &b) { return b != a; }
inline bool operator!=(const std::string &a, const t_string &b) { return b != a; }
inline bool operator!=(const char *a, const t_string &b) { return b != a; }
inline t_string operator+(const n_token::t_token &a, const t_string &b) { return t_string(a) + b; }
inline t_string operator+(const std::string &a, const t_string &b) { return t_string(a) + b; }
inline t_string operator+(const char *a, const t_string &b) { return t_string(a) + b; }
#endif