1
0
mirror of https://github.com/OlafvdSpek/ctemplate.git synced 2025-09-28 19:05:49 +08:00

Preprocess

This commit is contained in:
olafvdspek@gmail.com 2012-03-19 23:40:45 +00:00
parent 21c10669c1
commit 8d74ba6858
2 changed files with 80 additions and 82 deletions

View File

@ -55,6 +55,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <ctemplate/str_ref.h>
#include <ctemplate/template_dictionary_interface.h> #include <ctemplate/template_dictionary_interface.h>
#include <ctemplate/template_modifiers.h> #include <ctemplate/template_modifiers.h>
#include <ctemplate/template_string.h> #include <ctemplate/template_string.h>
@ -89,7 +90,7 @@ class CTEMPLATE_DLL_DECL TemplateDictionary : public TemplateDictionaryInterface
static UnsafeArena* const NO_ARENA; static UnsafeArena* const NO_ARENA;
std::string name() const { std::string name() const {
return std::string(name_.ptr_, name_.length_); return std::string(name_.data(), name_.size());
} }
// Returns a recursive copy of this dictionary. This dictionary // Returns a recursive copy of this dictionary. This dictionary
@ -107,13 +108,37 @@ class CTEMPLATE_DLL_DECL TemplateDictionary : public TemplateDictionaryInterface
// either a char* or a C++ string, or a TemplateString(s, slen). // either a char* or a C++ string, or a TemplateString(s, slen).
void SetValue(const TemplateString variable, const TemplateString value); void SetValue(const TemplateString variable, const TemplateString value);
void SetIntValue(const TemplateString variable, long value); void SetIntValue(const TemplateString variable, long value);
void SetFormattedValue(const TemplateString variable, const char* format, ...) void SetFormattedValue(const TemplateString variable, const char* format, ...)
#if 0 #if 0
__attribute__((__format__ (__printf__, 3, 4))) __attribute__((__format__ (__printf__, 3, 4)))
#endif #endif
; // starts at 3 because of implicit 1st arg 'this' ; // starts at 3 because of implicit 1st arg 'this'
class SetProxy {
public:
SetProxy(TemplateDictionary& dict, const TemplateString& variable) :
dict_(dict),
variable_(variable) {
}
void operator=(str_ref value) {
dict_.SetValue(variable_, TemplateString(value.data(), value.size()));
}
void operator=(long value) {
dict_.SetIntValue(variable_, value);
}
private:
TemplateDictionary& dict_;
const TemplateString& variable_;
};
SetProxy operator[](const TemplateString& variable) {
return SetProxy(*this, variable);
}
// We also let you set values in the 'global' dictionary which is // We also let you set values in the 'global' dictionary which is
// referenced when all other dictionaries fail. Note this is a // referenced when all other dictionaries fail. Note this is a
// static method: no TemplateDictionary instance needed. Since // static method: no TemplateDictionary instance needed. Since
@ -299,10 +324,10 @@ void SetIntValue(const TemplateString variable, long value);
// trailing-NUL check in the TemplateString version of Memdup. // trailing-NUL check in the TemplateString version of Memdup.
TemplateString Memdup(const char* s, size_t slen); TemplateString Memdup(const char* s, size_t slen);
TemplateString Memdup(const TemplateString& s) { TemplateString Memdup(const TemplateString& s) {
if (s.is_immutable() && s.ptr_[s.length_] == '\0') { if (s.is_immutable() && s.data()[s.size()] == '\0') {
return s; return s;
} }
return Memdup(s.ptr_, s.length_); return Memdup(s.data(), s.size());
} }
// Used for recursive MakeCopy calls. // Used for recursive MakeCopy calls.
@ -343,10 +368,10 @@ void SetIntValue(const TemplateString variable, long value);
// of TemplateString, but we are // of TemplateString, but we are
static std::string PrintableTemplateString( static std::string PrintableTemplateString(
const TemplateString& ts) { const TemplateString& ts) {
return std::string(ts.ptr_, ts.length_); return std::string(ts.data(), ts.size());
} }
static bool InvalidTemplateString(const TemplateString& ts) { static bool InvalidTemplateString(const TemplateString& ts) {
return ts.ptr_ == NULL; return ts.data() == NULL;
} }
// Compilers differ about whether nested classes inherit our friendship. // Compilers differ about whether nested classes inherit our friendship.
// The only thing DictionaryPrinter needs is IdToString, so just re-export. // The only thing DictionaryPrinter needs is IdToString, so just re-export.

View File

@ -91,10 +91,22 @@ struct StaticTemplateString;
// StaticTemplateString here, since they are hashed more efficiently // StaticTemplateString here, since they are hashed more efficiently
// based on their id. // based on their id.
struct CTEMPLATE_DLL_DECL StringHash { struct CTEMPLATE_DLL_DECL StringHash {
inline size_t operator()(const char* s) const; inline size_t operator()(const char* s) const {
inline size_t operator()(const std::string& s) const; return Hash(s, strlen(s));
inline bool operator()(const char* a, const char* b) const; // <, for MSVC };
inline bool operator()(const std::string& a, const std::string& b) const;
inline size_t operator()(const std::string& s) const {
return Hash(s.data(), s.size());
}
inline bool operator()(const char* a, const char* b) const {
return (a != b) && (strcmp(a, b) < 0); // <, for MSVC
}
inline bool operator()(const std::string& a, const std::string& b) const {
return a < b;
}
static const size_t bucket_size = 4; // These are required by MSVC static const size_t bucket_size = 4; // These are required by MSVC
static const size_t min_buckets = 8; // 4 and 8 are the defaults static const size_t min_buckets = 8; // 4 and 8 are the defaults
private: private:
@ -146,17 +158,13 @@ struct CTEMPLATE_DLL_DECL StaticTemplateString {
static const size_t min_buckets = 8; // 4 and 8 are the defaults static const size_t min_buckets = 8; // 4 and 8 are the defaults
}; };
inline bool empty() const; inline bool empty() const {
return do_not_use_directly_.length_ == 0;
// Use sparingly. Converting to a string loses information about the }
// id of the template string, making operations require extra hash_compare
// computations.
inline std::string ToString() const;
// Allows comparisons of StaticTemplateString objects as if they were // Allows comparisons of StaticTemplateString objects as if they were
// strings. This is useful for STL. // strings. This is useful for STL.
inline bool operator==(const StaticTemplateString& x) const; inline bool operator==(const StaticTemplateString& x) const;
inline bool operator!=(const StaticTemplateString& x) const;
}; };
class CTEMPLATE_DLL_DECL TemplateString { class CTEMPLATE_DLL_DECL TemplateString {
@ -173,46 +181,57 @@ class CTEMPLATE_DLL_DECL TemplateString {
: ptr_(s), length_(slen), : ptr_(s), length_(slen),
is_immutable_(InTextSegment(s)), id_(kIllegalTemplateId) { is_immutable_(InTextSegment(s)), id_(kIllegalTemplateId) {
} }
TemplateString(const TemplateString& s)
: ptr_(s.ptr_), length_(s.length_),
is_immutable_(s.is_immutable_), id_(s.id_) {
}
TemplateString(const StaticTemplateString& s) TemplateString(const StaticTemplateString& s)
: ptr_(s.do_not_use_directly_.ptr_), : ptr_(s.do_not_use_directly_.ptr_),
length_(s.do_not_use_directly_.length_), length_(s.do_not_use_directly_.length_),
is_immutable_(true), id_(s.do_not_use_directly_.id_) { is_immutable_(true), id_(s.do_not_use_directly_.id_) {
} }
inline bool empty() const; const char* begin() const {
return ptr_;
}
const char* end() const {
return ptr_ + length_;
}
const char* data() const {
return ptr_;
}
size_t size() const {
return length_;
}
inline bool empty() const {
return length_ == 0;
};
inline bool is_immutable() const {
return is_immutable_;
}
// STL requires this to be public for hash_map, though I'd rather not. // STL requires this to be public for hash_map, though I'd rather not.
inline bool operator==(const TemplateString& x) const; inline bool operator==(const TemplateString& x) const {
return GetGlobalId() == x.GetGlobalId();
}
private: private:
// Only TemplateDictionaries and template expansion code can read these. // Only TemplateDictionaries and template expansion code can read these.
friend class OldTemplateDictionary;
friend class TemplateDictionary; friend class TemplateDictionary;
friend class TemplateDictionaryPeer; // TDP::GetSectionValue()
friend class Template; // for StringToTemplate()
friend class VariableTemplateNode; // VTN::Expand()
friend class TemplateCache; // for GetGlobalId friend class TemplateCache; // for GetGlobalId
friend class StaticTemplateStringInitializer; // for AddToGlo... friend class StaticTemplateStringInitializer; // for AddToGlo...
friend struct TemplateStringHasher; // for GetGlobalId friend struct TemplateStringHasher; // for GetGlobalId
friend class ::TemplateStringTest;
friend class ::StaticTemplateStringTest; // for GetGlobalId
friend TemplateId GlobalIdForTest(const char* ptr, int len); friend TemplateId GlobalIdForTest(const char* ptr, int len);
friend TemplateId GlobalIdForSTS_INIT(const TemplateString& s); friend TemplateId GlobalIdForSTS_INIT(const TemplateString& s);
TemplateString(); // no empty constructor allowed
TemplateString(const char* s, size_t slen, bool is_immutable, TemplateId id) TemplateString(const char* s, size_t slen, bool is_immutable, TemplateId id)
: ptr_(s), length_(slen), is_immutable_(is_immutable), id_(id) { : ptr_(s), length_(slen), is_immutable_(is_immutable), id_(id) {
} }
inline bool is_immutable() const;
// This returns true if s is in the .text segment of the binary. // This returns true if s is in the .text segment of the binary.
// (Note this only checks .text of the main executable, not of // (Note this only checks .text of the main executable, not of
// shared libraries. So it may not be all that useful.) // shared libraries. So it may not be all that useful.)
// This requires the gnu linker (and probably elf), to define // This requires the gnu linker (and probably elf), to define
// _start and data_start. // _start and data_start.
static bool InTextSegment(const char* s) { static bool InTextSegment(const char* s) {
@ -224,7 +243,9 @@ class CTEMPLATE_DLL_DECL TemplateString {
} }
protected: protected:
inline void CacheGlobalId(); // used by HashedTemplateString inline void CacheGlobalId() { // used by HashedTemplateString
id_ = GetGlobalId();
};
private: private:
// Returns the global id, computing it for the first time if // Returns the global id, computing it for the first time if
@ -297,11 +318,6 @@ inline bool StaticTemplateString::Hasher::operator()(
return TemplateIdHasher()(id_a, id_b); return TemplateIdHasher()(id_a, id_b);
} }
inline std::string StaticTemplateString::ToString() const {
return std::string(do_not_use_directly_.ptr_,
do_not_use_directly_.length_);
}
inline bool StaticTemplateString::operator==( inline bool StaticTemplateString::operator==(
const StaticTemplateString& x) const { const StaticTemplateString& x) const {
return (do_not_use_directly_.length_ == x.do_not_use_directly_.length_ && return (do_not_use_directly_.length_ == x.do_not_use_directly_.length_ &&
@ -310,49 +326,6 @@ inline bool StaticTemplateString::operator==(
do_not_use_directly_.length_) == 0)); do_not_use_directly_.length_) == 0));
} }
inline bool StaticTemplateString::operator!=(
const StaticTemplateString& x) const {
return !(*this == x);
}
inline bool StaticTemplateString::empty() const {
return do_not_use_directly_.length_ == 0;
}
inline bool TemplateString::operator==(const TemplateString& x) const {
return (GetGlobalId() == x.GetGlobalId());
}
bool TemplateString::empty() const {
return length_ == 0;
}
inline void TemplateString::CacheGlobalId() {
id_ = GetGlobalId();
}
inline bool TemplateString::is_immutable() const { return is_immutable_; }
inline size_t StringHash::operator()(const char* s) const {
return Hash(s, strlen(s));
}
inline size_t StringHash::operator()(const std::string& s) const {
return Hash(s.data(), s.size());
}
inline bool StringHash::operator()(const char* a, const char* b) const {
return (a != b) && (strcmp(a, b) < 0); // <, for MSVC
}
inline bool StringHash::operator()(const std::string& a, const std::string& b) const {
return a < b;
}
// We set up as much of StaticTemplateString as we can at // We set up as much of StaticTemplateString as we can at
// static-initialization time (using brace-initialization), but some // static-initialization time (using brace-initialization), but some
// things can't be set up then. This class is for those things; it // things can't be set up then. This class is for those things; it