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 <vector>
#include <ctemplate/str_ref.h>
#include <ctemplate/template_dictionary_interface.h>
#include <ctemplate/template_modifiers.h>
#include <ctemplate/template_string.h>
@ -89,7 +90,7 @@ class CTEMPLATE_DLL_DECL TemplateDictionary : public TemplateDictionaryInterface
static UnsafeArena* const NO_ARENA;
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
@ -114,6 +115,30 @@ void SetIntValue(const TemplateString variable, long value);
#endif
; // 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
// referenced when all other dictionaries fail. Note this is a
// 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.
TemplateString Memdup(const char* s, size_t slen);
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 Memdup(s.ptr_, s.length_);
return Memdup(s.data(), s.size());
}
// Used for recursive MakeCopy calls.
@ -343,10 +368,10 @@ void SetIntValue(const TemplateString variable, long value);
// of TemplateString, but we are
static std::string PrintableTemplateString(
const TemplateString& ts) {
return std::string(ts.ptr_, ts.length_);
return std::string(ts.data(), ts.size());
}
static bool InvalidTemplateString(const TemplateString& ts) {
return ts.ptr_ == NULL;
return ts.data() == NULL;
}
// Compilers differ about whether nested classes inherit our friendship.
// 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
// based on their id.
struct CTEMPLATE_DLL_DECL StringHash {
inline size_t operator()(const char* s) const;
inline size_t operator()(const std::string& s) const;
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 char* s) const {
return Hash(s, strlen(s));
};
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 min_buckets = 8; // 4 and 8 are the defaults
private:
@ -146,17 +158,13 @@ struct CTEMPLATE_DLL_DECL StaticTemplateString {
static const size_t min_buckets = 8; // 4 and 8 are the defaults
};
inline bool empty() const;
// 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;
inline bool empty() const {
return do_not_use_directly_.length_ == 0;
}
// Allows comparisons of StaticTemplateString objects as if they were
// strings. This is useful for STL.
inline bool operator==(const StaticTemplateString& x) const;
inline bool operator!=(const StaticTemplateString& x) const;
};
class CTEMPLATE_DLL_DECL TemplateString {
@ -173,43 +181,54 @@ class CTEMPLATE_DLL_DECL TemplateString {
: ptr_(s), length_(slen),
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)
: ptr_(s.do_not_use_directly_.ptr_),
length_(s.do_not_use_directly_.length_),
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.
inline bool operator==(const TemplateString& x) const;
inline bool operator==(const TemplateString& x) const {
return GetGlobalId() == x.GetGlobalId();
}
private:
// Only TemplateDictionaries and template expansion code can read these.
friend class OldTemplateDictionary;
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 StaticTemplateStringInitializer; // for AddToGlo...
friend struct TemplateStringHasher; // for GetGlobalId
friend class ::TemplateStringTest;
friend class ::StaticTemplateStringTest; // for GetGlobalId
friend TemplateId GlobalIdForTest(const char* ptr, int len);
friend TemplateId GlobalIdForSTS_INIT(const TemplateString& s);
TemplateString(); // no empty constructor allowed
TemplateString(const char* s, size_t slen, bool is_immutable, TemplateId 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.
// (Note this only checks .text of the main executable, not of
// shared libraries. So it may not be all that useful.)
@ -224,7 +243,9 @@ class CTEMPLATE_DLL_DECL TemplateString {
}
protected:
inline void CacheGlobalId(); // used by HashedTemplateString
inline void CacheGlobalId() { // used by HashedTemplateString
id_ = GetGlobalId();
};
private:
// 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);
}
inline std::string StaticTemplateString::ToString() const {
return std::string(do_not_use_directly_.ptr_,
do_not_use_directly_.length_);
}
inline bool StaticTemplateString::operator==(
const StaticTemplateString& x) const {
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));
}
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
// static-initialization time (using brace-initialization), but some
// things can't be set up then. This class is for those things; it