aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2016-12-14 10:31:18 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2016-12-15 09:37:00 +0000
commitdd761e0893ff457103237e8a76fe3fea276698cc (patch)
tree6ed3be5aa2d598ce2e0f9fb3d70d1115eb2763ce
parent15f7a97650a8bce2ac2698bd189397260453e923 (diff)
Fully templatize the PersistentPool class
The old implementation was a wild mix of templates, overloads and, worst of all, implicit assumptions about the types of container items. This combination made it close to impossible to add support for serializing generic containers. Now we have a sensible interface that we can build upon. Change-Id: I82806eaf535c16fc861bededf1b06c681d2128c0 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r--src/lib/corelib/buildgraph/artifact.cpp12
-rw-r--r--src/lib/corelib/buildgraph/command.cpp58
-rw-r--r--src/lib/corelib/buildgraph/filedependency.cpp4
-rw-r--r--src/lib/corelib/buildgraph/nodeset.cpp4
-rw-r--r--src/lib/corelib/buildgraph/productbuilddata.cpp20
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.cpp8
-rw-r--r--src/lib/corelib/buildgraph/rescuableartifactdata.cpp14
-rw-r--r--src/lib/corelib/buildgraph/rulenode.cpp6
-rw-r--r--src/lib/corelib/buildgraph/transformer.cpp10
-rw-r--r--src/lib/corelib/language/artifactproperties.cpp2
-rw-r--r--src/lib/corelib/language/filetags.cpp4
-rw-r--r--src/lib/corelib/language/language.cpp187
-rw-r--r--src/lib/corelib/language/property.cpp20
-rw-r--r--src/lib/corelib/language/propertymapinternal.cpp2
-rw-r--r--src/lib/corelib/language/resolvedfilecontext.cpp20
-rw-r--r--src/lib/corelib/tools/codelocation.cpp4
-rw-r--r--src/lib/corelib/tools/error.cpp4
-rw-r--r--src/lib/corelib/tools/persistence.cpp46
-rw-r--r--src/lib/corelib/tools/persistence.h164
19 files changed, 298 insertions, 291 deletions
diff --git a/src/lib/corelib/buildgraph/artifact.cpp b/src/lib/corelib/buildgraph/artifact.cpp
index a00d7b623..6909f80fb 100644
--- a/src/lib/corelib/buildgraph/artifact.cpp
+++ b/src/lib/corelib/buildgraph/artifact.cpp
@@ -154,10 +154,10 @@ void Artifact::load(PersistentPool &pool)
for (NodeSet::const_iterator it = children.constBegin(); it != children.constEnd(); ++it)
(*it)->parents.insert(this);
- pool.loadContainer(childrenAddedByScanner);
- pool.loadContainer(fileDependencies);
- properties = pool.idLoadS<PropertyMapInternal>();
- transformer = pool.idLoadS<Transformer>();
+ pool.load(childrenAddedByScanner);
+ pool.load(fileDependencies);
+ pool.load(properties);
+ pool.load(transformer);
m_fileTags.load(pool);
unsigned char c;
pool.stream()
@@ -174,8 +174,8 @@ void Artifact::store(PersistentPool &pool) const
BuildGraphNode::store(pool);
// Do not store parents to avoid recursion.
children.store(pool);
- pool.storeContainer(childrenAddedByScanner);
- pool.storeContainer(fileDependencies);
+ pool.store(childrenAddedByScanner);
+ pool.store(fileDependencies);
pool.store(properties);
pool.store(transformer);
m_fileTags.store(pool);
diff --git a/src/lib/corelib/buildgraph/command.cpp b/src/lib/corelib/buildgraph/command.cpp
index 55b486dfb..7921e5ca9 100644
--- a/src/lib/corelib/buildgraph/command.cpp
+++ b/src/lib/corelib/buildgraph/command.cpp
@@ -95,20 +95,20 @@ void AbstractCommand::fillFromScriptValue(const QScriptValue *scriptValue, const
void AbstractCommand::load(PersistentPool &pool)
{
- m_description = pool.idLoadString();
- m_extendedDescription = pool.idLoadString();
- m_highlight = pool.idLoadString();
+ pool.load(m_description);
+ pool.load(m_extendedDescription);
+ pool.load(m_highlight);
pool.stream() >> m_ignoreDryRun;
pool.stream() >> m_silent;
m_codeLocation.load(pool);
- m_properties = pool.loadVariantMap();
+ pool.load(m_properties);
}
void AbstractCommand::store(PersistentPool &pool) const
{
- pool.storeString(m_description);
- pool.storeString(m_extendedDescription);
- pool.storeString(m_highlight);
+ pool.store(m_description);
+ pool.store(m_extendedDescription);
+ pool.store(m_highlight);
pool.stream() << m_ignoreDryRun;
pool.stream() << m_silent;
m_codeLocation.store(pool);
@@ -290,32 +290,32 @@ void ProcessCommand::fillFromScriptValue(const QScriptValue *scriptValue, const
void ProcessCommand::load(PersistentPool &pool)
{
AbstractCommand::load(pool);
- m_program = pool.idLoadString();
- m_arguments = pool.idLoadStringList();
- const QStringList envList = pool.idLoadStringList();
- m_workingDir = pool.idLoadString();
- m_stdoutFilterFunction = pool.idLoadString();
- m_stderrFilterFunction = pool.idLoadString();
- m_responseFileUsagePrefix = pool.idLoadString();
+ pool.load(m_program);
+ pool.load(m_arguments);
+ const QStringList envList = pool.load<QStringList>();
+ pool.load(m_workingDir);
+ pool.load(m_stdoutFilterFunction);
+ pool.load(m_stderrFilterFunction);
+ pool.load(m_responseFileUsagePrefix);
pool.stream() >> m_maxExitCode >> m_responseFileThreshold >> m_responseFileArgumentIndex;
- m_stdoutFilePath = pool.idLoadString();
- m_stderrFilePath = pool.idLoadString();
+ pool.load(m_stdoutFilePath);
+ pool.load(m_stderrFilePath);
getEnvironmentFromList(envList);
}
void ProcessCommand::store(PersistentPool &pool) const
{
AbstractCommand::store(pool);
- pool.storeString(m_program);
- pool.storeStringList(m_arguments);
- pool.storeStringList(m_environment.toStringList());
- pool.storeString(m_workingDir);
- pool.storeString(m_stdoutFilterFunction);
- pool.storeString(m_stderrFilterFunction);
- pool.storeString(m_responseFileUsagePrefix);
+ pool.store(m_program);
+ pool.store(m_arguments);
+ pool.store(m_environment.toStringList());
+ pool.store(m_workingDir);
+ pool.store(m_stdoutFilterFunction);
+ pool.store(m_stderrFilterFunction);
+ pool.store(m_responseFileUsagePrefix);
pool.stream() << m_maxExitCode << m_responseFileThreshold << m_responseFileArgumentIndex;
- pool.storeString(m_stdoutFilePath);
- pool.storeString(m_stderrFilePath);
+ pool.store(m_stdoutFilePath);
+ pool.store(m_stderrFilePath);
}
static QScriptValue js_JavaScriptCommand(QScriptContext *context, QScriptEngine *engine)
@@ -372,13 +372,13 @@ void JavaScriptCommand::fillFromScriptValue(const QScriptValue *scriptValue, con
void JavaScriptCommand::load(PersistentPool &pool)
{
AbstractCommand::load(pool);
- m_sourceCode = pool.idLoadString();
+ pool.load(m_sourceCode);
}
void JavaScriptCommand::store(PersistentPool &pool) const
{
AbstractCommand::store(pool);
- pool.storeString(m_sourceCode);
+ pool.store(m_sourceCode);
}
QList<AbstractCommandPtr> loadCommandList(PersistentPool &pool)
@@ -393,10 +393,10 @@ QList<AbstractCommandPtr> loadCommandList(PersistentPool &pool)
AbstractCommandPtr cmd;
switch (cmdType) {
case AbstractCommand::JavaScriptCommandType:
- cmd = pool.idLoadS<JavaScriptCommand>();
+ cmd = pool.load<JavaScriptCommandPtr>();
break;
case AbstractCommand::ProcessCommandType:
- cmd = pool.idLoadS<ProcessCommand>();
+ cmd = pool.load<ProcessCommandPtr>();
break;
default:
QBS_CHECK(false);
diff --git a/src/lib/corelib/buildgraph/filedependency.cpp b/src/lib/corelib/buildgraph/filedependency.cpp
index d57db17cb..62a55ad1a 100644
--- a/src/lib/corelib/buildgraph/filedependency.cpp
+++ b/src/lib/corelib/buildgraph/filedependency.cpp
@@ -77,14 +77,14 @@ const QString &FileResourceBase::filePath() const
void FileResourceBase::load(PersistentPool &pool)
{
- setFilePath(pool.idLoadString());
+ setFilePath(pool.load<QString>());
pool.stream()
>> m_timestamp;
}
void FileResourceBase::store(PersistentPool &pool) const
{
- pool.storeString(m_filePath);
+ pool.store(m_filePath);
pool.stream()
<< m_timestamp;
}
diff --git a/src/lib/corelib/buildgraph/nodeset.cpp b/src/lib/corelib/buildgraph/nodeset.cpp
index 3ed799fae..6ccb70bcd 100644
--- a/src/lib/corelib/buildgraph/nodeset.cpp
+++ b/src/lib/corelib/buildgraph/nodeset.cpp
@@ -75,10 +75,10 @@ void NodeSet::load(PersistentPool &pool)
BuildGraphNode *node = 0;
switch (static_cast<BuildGraphNode::Type>(t)) {
case BuildGraphNode::ArtifactNodeType:
- node = pool.idLoad<Artifact>();
+ node = pool.load<Artifact *>();
break;
case BuildGraphNode::RuleNodeType:
- node = pool.idLoad<RuleNode>();
+ node = pool.load<RuleNode *>();
break;
}
QBS_CHECK(node);
diff --git a/src/lib/corelib/buildgraph/productbuilddata.cpp b/src/lib/corelib/buildgraph/productbuilddata.cpp
index 7bd88e577..34701540c 100644
--- a/src/lib/corelib/buildgraph/productbuilddata.cpp
+++ b/src/lib/corelib/buildgraph/productbuilddata.cpp
@@ -66,9 +66,8 @@ static void loadArtifactSetByFileTag(PersistentPool &pool,
int elemCount;
pool.stream() >> elemCount;
for (int i = 0; i < elemCount; ++i) {
- const QVariant fileTag = pool.loadVariant();
- ArtifactSet artifacts;
- pool.loadContainer(artifacts);
+ const auto &fileTag = pool.load<QVariant>();
+ const auto &artifacts = pool.load<ArtifactSet>();
s.insert(FileTag::fromSetting(fileTag), artifacts);
}
}
@@ -81,7 +80,7 @@ void ProductBuildData::load(PersistentPool &pool)
pool.stream() >> count;
rescuableArtifactData.reserve(count);
for (int i = 0; i < count; ++i) {
- const QString filePath = pool.idLoadString();
+ const QString filePath = pool.load<QString>();
RescuableArtifactData elem;
elem.load(pool);
rescuableArtifactData.insert(filePath, elem);
@@ -90,10 +89,9 @@ void ProductBuildData::load(PersistentPool &pool)
pool.stream() >> count;
for (int i = 0; i < count; ++i) {
- const RulePtr r = pool.idLoadS<Rule>();
- ArtifactSet s;
- pool.loadContainer(s);
- artifactsWithChangedInputsPerRule.insert(r, s);
+ const auto &rule = pool.load<RulePtr>();
+ const auto &artifacts = pool.load<ArtifactSet>();
+ artifactsWithChangedInputsPerRule.insert(rule, artifacts);
}
}
@@ -104,7 +102,7 @@ static void storeArtifactSetByFileTag(PersistentPool &pool,
ProductBuildData::ArtifactSetByFileTag::ConstIterator it;
for (it = s.constBegin(); it != s.constEnd(); ++it) {
pool.store(it.key().toSetting());
- pool.storeContainer(it.value());
+ pool.store(it.value());
}
}
@@ -115,7 +113,7 @@ void ProductBuildData::store(PersistentPool &pool) const
pool.stream() << rescuableArtifactData.count();
for (AllRescuableArtifactData::ConstIterator it = rescuableArtifactData.constBegin();
it != rescuableArtifactData.constEnd(); ++it) {
- pool.storeString(it.key());
+ pool.store(it.key());
it.value().store(pool);
}
storeArtifactSetByFileTag(pool, artifactsByFileTag);
@@ -124,7 +122,7 @@ void ProductBuildData::store(PersistentPool &pool) const
for (ArtifactSetByRule::ConstIterator it = artifactsWithChangedInputsPerRule.constBegin();
it != artifactsWithChangedInputsPerRule.constEnd(); ++it) {
pool.store(it.key());
- pool.storeContainer(it.value());
+ pool.store(it.value());
}
}
diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp
index 0ffb43feb..a53433bd1 100644
--- a/src/lib/corelib/buildgraph/projectbuilddata.cpp
+++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp
@@ -348,15 +348,13 @@ void ProjectBuildData::load(PersistentPool &pool)
pool.stream() >> count;
fileDependencies.clear();
fileDependencies.reserve(count);
- for (; --count >= 0;) {
- FileDependency *fileDependency = pool.idLoad<FileDependency>();
- insertFileDependency(fileDependency);
- }
+ for (; --count >= 0;)
+ insertFileDependency(pool.load<FileDependency *>());
}
void ProjectBuildData::store(PersistentPool &pool) const
{
- pool.storeContainer(fileDependencies);
+ pool.store(fileDependencies);
}
diff --git a/src/lib/corelib/buildgraph/rescuableartifactdata.cpp b/src/lib/corelib/buildgraph/rescuableartifactdata.cpp
index aaa811cf0..bc651c5d4 100644
--- a/src/lib/corelib/buildgraph/rescuableartifactdata.cpp
+++ b/src/lib/corelib/buildgraph/rescuableartifactdata.cpp
@@ -60,9 +60,9 @@ void RescuableArtifactData::load(PersistentPool &pool)
pool.stream() >> c;
for (int i = 0; i < c; ++i) {
ChildData cd;
- cd.productName = pool.idLoadString();
- cd.productProfile = pool.idLoadString();
- cd.childFilePath = pool.idLoadString();
+ pool.load(cd.productName);
+ pool.load(cd.productProfile);
+ pool.load(cd.childFilePath);
pool.stream() >> cd.addedByScanner;
children << cd;
}
@@ -73,7 +73,7 @@ void RescuableArtifactData::load(PersistentPool &pool)
propertiesRequestedFromArtifactInCommands = restorePropertyHash(pool);
commands = loadCommandList(pool);
fileTags.load(pool);
- properties = pool.idLoadS<PropertyMapInternal>();
+ pool.load(properties);
}
void RescuableArtifactData::store(PersistentPool &pool) const
@@ -82,9 +82,9 @@ void RescuableArtifactData::store(PersistentPool &pool) const
pool.stream() << children.count();
foreach (const ChildData &cd, children) {
- pool.storeString(cd.productName);
- pool.storeString(cd.productProfile);
- pool.storeString(cd.childFilePath);
+ pool.store(cd.productName);
+ pool.store(cd.productProfile);
+ pool.store(cd.childFilePath);
pool.stream() << cd.addedByScanner;
}
diff --git a/src/lib/corelib/buildgraph/rulenode.cpp b/src/lib/corelib/buildgraph/rulenode.cpp
index ebe573e22..b9ebe621c 100644
--- a/src/lib/corelib/buildgraph/rulenode.cpp
+++ b/src/lib/corelib/buildgraph/rulenode.cpp
@@ -145,15 +145,15 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs,
void RuleNode::load(PersistentPool &pool)
{
BuildGraphNode::load(pool);
- m_rule = pool.idLoadS<Rule>();
- pool.loadContainer(m_oldInputArtifacts);
+ pool.load(m_rule);
+ pool.load(m_oldInputArtifacts);
}
void RuleNode::store(PersistentPool &pool) const
{
BuildGraphNode::store(pool);
pool.store(m_rule);
- pool.storeContainer(m_oldInputArtifacts);
+ pool.store(m_oldInputArtifacts);
}
ArtifactSet RuleNode::currentInputArtifacts() const
diff --git a/src/lib/corelib/buildgraph/transformer.cpp b/src/lib/corelib/buildgraph/transformer.cpp
index 3d0eedbf3..a8ae795ff 100644
--- a/src/lib/corelib/buildgraph/transformer.cpp
+++ b/src/lib/corelib/buildgraph/transformer.cpp
@@ -258,9 +258,9 @@ void Transformer::createCommands(const ScriptFunctionConstPtr &script,
void Transformer::load(PersistentPool &pool)
{
- rule = pool.idLoadS<Rule>();
- pool.loadContainer(inputs);
- pool.loadContainer(outputs);
+ pool.load(rule);
+ pool.load(inputs);
+ pool.load(outputs);
propertiesRequestedInPrepareScript = restorePropertySet(pool);
propertiesRequestedInCommands = restorePropertySet(pool);
propertiesRequestedFromArtifactInPrepareScript = restorePropertyHash(pool);
@@ -272,8 +272,8 @@ void Transformer::load(PersistentPool &pool)
void Transformer::store(PersistentPool &pool) const
{
pool.store(rule);
- pool.storeContainer(inputs);
- pool.storeContainer(outputs);
+ pool.store(inputs);
+ pool.store(outputs);
storePropertySet(pool, propertiesRequestedInPrepareScript);
storePropertySet(pool, propertiesRequestedInCommands);
storePropertyHash(pool, propertiesRequestedFromArtifactInPrepareScript);
diff --git a/src/lib/corelib/language/artifactproperties.cpp b/src/lib/corelib/language/artifactproperties.cpp
index eae9fb667..80054ff2d 100644
--- a/src/lib/corelib/language/artifactproperties.cpp
+++ b/src/lib/corelib/language/artifactproperties.cpp
@@ -56,7 +56,7 @@ ArtifactProperties::ArtifactProperties()
void ArtifactProperties::load(PersistentPool &pool)
{
m_fileTagsFilter.load(pool);
- m_propertyMap = pool.idLoadS<PropertyMapInternal>();
+ pool.load(m_propertyMap);
}
void ArtifactProperties::store(PersistentPool &pool) const
diff --git a/src/lib/corelib/language/filetags.cpp b/src/lib/corelib/language/filetags.cpp
index c451a24b5..f086de102 100644
--- a/src/lib/corelib/language/filetags.cpp
+++ b/src/lib/corelib/language/filetags.cpp
@@ -79,12 +79,12 @@ bool FileTags::matches(const FileTags &other) const
void FileTags::store(PersistentPool &pool) const
{
- pool.storeStringList(toStringList());
+ pool.store(toStringList());
}
void FileTags::load(PersistentPool &pool)
{
- *this = fromStringList(pool.idLoadStringList());
+ *this = fromStringList(pool.load<QStringList>());
}
LogWriter operator <<(LogWriter w, const FileTags &tags)
diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp
index 016adcaf4..75f705461 100644
--- a/src/lib/corelib/language/language.cpp
+++ b/src/lib/corelib/language/language.cpp
@@ -103,7 +103,7 @@ void FileTagger::setPatterns(const QStringList &patterns)
*/
void FileTagger::load(PersistentPool &pool)
{
- setPatterns(pool.idLoadStringList());
+ setPatterns(pool.load<QStringList>());
m_fileTags.load(pool);
}
@@ -112,7 +112,7 @@ void FileTagger::store(PersistentPool &pool) const
QStringList patterns;
foreach (const QRegExp &regExp, m_patterns)
patterns << regExp.pattern();
- pool.storeStringList(patterns);
+ pool.store(patterns);
m_fileTags.store(pool);
}
@@ -121,16 +121,16 @@ void Probe::load(PersistentPool &pool)
{
m_location.load(pool);
pool.stream() >> m_condition;
- m_configureScript = pool.idLoadString();
- m_properties = pool.loadVariantMap();
- m_initialProperties = pool.loadVariantMap();
+ pool.load(m_configureScript);
+ pool.load(m_properties);
+ pool.load(m_initialProperties);
}
void Probe::store(PersistentPool &pool) const
{
m_location.store(pool);
pool.stream() << condition();
- pool.storeString(m_configureScript);
+ pool.store(m_configureScript);
pool.store(m_properties);
pool.store(m_initialProperties);
}
@@ -147,15 +147,15 @@ void Probe::store(PersistentPool &pool) const
*/
void SourceArtifactInternal::load(PersistentPool &pool)
{
- absoluteFilePath = pool.idLoadString();
+ pool.load(absoluteFilePath);
fileTags.load(pool);
pool.stream() >> overrideFileTags;
- properties = pool.idLoadS<PropertyMapInternal>();
+ pool.load(properties);
}
void SourceArtifactInternal::store(PersistentPool &pool) const
{
- pool.storeString(absoluteFilePath);
+ pool.store(absoluteFilePath);
fileTags.store(pool);
pool.stream() << overrideFileTags;
pool.store(properties);
@@ -163,18 +163,18 @@ void SourceArtifactInternal::store(PersistentPool &pool) const
void SourceWildCards::load(PersistentPool &pool)
{
- prefix = pool.idLoadString();
- patterns = pool.idLoadStringList();
- excludePatterns = pool.idLoadStringList();
- pool.loadContainerS(files);
+ pool.load(prefix);
+ pool.load(patterns);
+ pool.load(excludePatterns);
+ pool.load(files);
}
void SourceWildCards::store(PersistentPool &pool) const
{
- pool.storeString(prefix);
- pool.storeStringList(patterns);
- pool.storeStringList(excludePatterns);
- pool.storeContainer(files);
+ pool.store(prefix);
+ pool.store(patterns);
+ pool.store(excludePatterns);
+ pool.store(files);
}
/*!
@@ -209,24 +209,24 @@ QList<SourceArtifactPtr> ResolvedGroup::allFiles() const
void ResolvedGroup::load(PersistentPool &pool)
{
- name = pool.idLoadString();
+ pool.load(name);
pool.stream() >> enabled;
location.load(pool);
- prefix = pool.idLoadString();
- pool.loadContainerS(files);
- wildcards = pool.idLoadS<SourceWildCards>();
- properties = pool.idLoadS<PropertyMapInternal>();
+ pool.load(prefix);
+ pool.load(files);
+ pool.load(wildcards);
+ pool.load(properties);
fileTags.load(pool);
pool.stream() >> overrideTags;
}
void ResolvedGroup::store(PersistentPool &pool) const
{
- pool.storeString(name);
+ pool.store(name);
pool.stream() << enabled;
location.store(pool);
- pool.storeString(prefix);
- pool.storeContainer(files);
+ pool.store(prefix);
+ pool.store(files);
pool.store(wildcards);
pool.store(properties);
fileTags.store(pool);
@@ -244,7 +244,7 @@ void ResolvedGroup::store(PersistentPool &pool) const
*/
void RuleArtifact::load(PersistentPool &pool)
{
- filePath = pool.idLoadString();
+ pool.load(filePath);
fileTags.load(pool);
pool.stream() >> alwaysUpdated;
location.load(pool);
@@ -256,8 +256,8 @@ void RuleArtifact::load(PersistentPool &pool)
bindings.reserve(i);
Binding binding;
for (; --i >= 0;) {
- binding.name = pool.idLoadStringList();
- binding.code = pool.idLoadString();
+ pool.load(binding.name);
+ pool.load(binding.code);
binding.location.load(pool);
bindings += binding;
}
@@ -265,7 +265,7 @@ void RuleArtifact::load(PersistentPool &pool)
void RuleArtifact::store(PersistentPool &pool) const
{
- pool.storeString(filePath);
+ pool.store(filePath);
fileTags.store(pool);
pool.stream() << alwaysUpdated;
location.store(pool);
@@ -274,8 +274,8 @@ void RuleArtifact::store(PersistentPool &pool) const
pool.stream() << bindings.count();
for (int i = bindings.count(); --i >= 0;) {
const Binding &binding = bindings.at(i);
- pool.storeStringList(binding.name);
- pool.storeString(binding.code);
+ pool.store(binding.name);
+ pool.store(binding.code);
binding.location.store(pool);
}
}
@@ -316,16 +316,16 @@ bool ScriptFunction::isValid() const
void ScriptFunction::load(PersistentPool &pool)
{
- sourceCode = pool.idLoadString();
- argumentNames = pool.idLoadStringList();
+ pool.load(sourceCode);
+ pool.load(argumentNames);
location.load(pool);
- fileContext = pool.idLoadS<ResolvedFileContext>();
+ pool.load(fileContext);
}
void ScriptFunction::store(PersistentPool &pool) const
{
- pool.storeString(sourceCode);
- pool.storeStringList(argumentNames);
+ pool.store(sourceCode);
+ pool.store(argumentNames);
location.store(pool);
pool.store(fileContext);
}
@@ -340,16 +340,16 @@ bool operator==(const ScriptFunction &a, const ScriptFunction &b)
void ResolvedModule::load(PersistentPool &pool)
{
- name = pool.idLoadString();
- moduleDependencies = pool.idLoadStringList();
- setupBuildEnvironmentScript = pool.idLoadS<ScriptFunction>();
- setupRunEnvironmentScript = pool.idLoadS<ScriptFunction>();
+ pool.load(name);
+ pool.load(moduleDependencies);
+ pool.load(setupBuildEnvironmentScript);
+ pool.load(setupRunEnvironmentScript);
}
void ResolvedModule::store(PersistentPool &pool) const
{
- pool.storeString(name);
- pool.storeStringList(moduleDependencies);
+ pool.store(name);
+ pool.store(moduleDependencies);
pool.store(setupBuildEnvironmentScript);
pool.store(setupRunEnvironmentScript);
}
@@ -405,10 +405,10 @@ bool Rule::requiresInputs() const
void Rule::load(PersistentPool &pool)
{
- name = pool.idLoadString();
- prepareScript = pool.idLoadS<ScriptFunction>();
- outputArtifactsScript = pool.idLoadS<ScriptFunction>();
- module = pool.idLoadS<ResolvedModule>();
+ pool.load(name);
+ pool.load(prepareScript);
+ pool.load(outputArtifactsScript);
+ pool.load(module);
inputs.load(pool);
outputFileTags.load(pool);
auxiliaryInputs.load(pool);
@@ -416,12 +416,12 @@ void Rule::load(PersistentPool &pool)
inputsFromDependencies.load(pool);
explicitlyDependsOn.load(pool);
pool.stream() >> multiplex >> alwaysRun;
- pool.loadContainerS(artifacts);
+ pool.load(artifacts);
}
void Rule::store(PersistentPool &pool) const
{
- pool.storeString(name);
+ pool.store(name);
pool.store(prepareScript);
pool.store(outputArtifactsScript);
pool.store(module);
@@ -432,7 +432,7 @@ void Rule::store(PersistentPool &pool) const
inputsFromDependencies.store(pool);
explicitlyDependsOn.store(pool);
pool.stream() << multiplex << alwaysRun;
- pool.storeContainer(artifacts);
+ pool.store(artifacts);
}
ResolvedProduct::ResolvedProduct()
@@ -496,47 +496,47 @@ void ResolvedProduct::load(PersistentPool &pool)
{
pool.stream() >> enabled;
fileTags.load(pool);
- name = pool.idLoadString();
- profile = pool.idLoadString();
- targetName = pool.idLoadString();
- sourceDirectory = pool.idLoadString();
- destinationDirectory = pool.idLoadString();
- missingSourceFiles = pool.idLoadStringList();
+ pool.load(name);
+ pool.load(profile);
+ pool.load(targetName);
+ pool.load(sourceDirectory);
+ pool.load(destinationDirectory);
+ pool.load(missingSourceFiles);
location.load(pool);
- productProperties = pool.loadVariantMap();
- moduleProperties = pool.idLoadS<PropertyMapInternal>();
- pool.loadContainerS(rules);
- pool.loadContainerS(dependencies);
- pool.loadContainerS(fileTaggers);
- pool.loadContainerS(modules);
- pool.loadContainerS(scanners);
- pool.loadContainerS(groups);
- pool.loadContainerS(artifactProperties);
- pool.loadContainerS(probes);
- buildData.reset(pool.idLoad<ProductBuildData>());
+ pool.load(productProperties);
+ pool.load(moduleProperties);
+ pool.load(rules);
+ pool.load(dependencies);
+ pool.load(fileTaggers);
+ pool.load(modules);
+ pool.load(scanners);
+ pool.load(groups);
+ pool.load(artifactProperties);
+ pool.load(probes);
+ buildData.reset(pool.load<ProductBuildData *>());
}
void ResolvedProduct::store(PersistentPool &pool) const
{
pool.stream() << enabled;
fileTags.store(pool);
- pool.storeString(name);
- pool.storeString(profile);
- pool.storeString(targetName);
- pool.storeString(sourceDirectory);
- pool.storeString(destinationDirectory);
- pool.storeStringList(missingSourceFiles);
+ pool.store(name);
+ pool.store(profile);
+ pool.store(targetName);
+ pool.store(sourceDirectory);
+ pool.store(destinationDirectory);
+ pool.store(missingSourceFiles);
location.store(pool);
pool.store(productProperties);
pool.store(moduleProperties);
- pool.storeContainer(rules);
- pool.storeContainer(dependencies);
- pool.storeContainer(fileTaggers);
- pool.storeContainer(modules);
- pool.storeContainer(scanners);
- pool.storeContainer(groups);
- pool.storeContainer(artifactProperties);
- pool.storeContainer(probes);
+ pool.store(rules);
+ pool.store(dependencies);
+ pool.store(fileTaggers);
+ pool.store(modules);
+ pool.store(scanners);
+ pool.store(groups);
+ pool.store(artifactProperties);
+ pool.store(probes);
pool.store(buildData.data());
}
@@ -878,7 +878,7 @@ QList<ResolvedProductPtr> ResolvedProject::allProducts() const
void ResolvedProject::load(PersistentPool &pool)
{
- name = pool.idLoadString();
+ pool.load(name);
location.load(pool);
int count;
pool.stream()
@@ -887,7 +887,7 @@ void ResolvedProject::load(PersistentPool &pool)
products.clear();
products.reserve(count);
for (; --count >= 0;) {
- ResolvedProductPtr rProduct = pool.idLoadS<ResolvedProduct>();
+ const auto &rProduct = pool.load<ResolvedProductPtr>();
if (rProduct->buildData) {
foreach (BuildGraphNode * const node, rProduct->buildData->nodes) {
node->product = rProduct;
@@ -903,17 +903,14 @@ void ResolvedProject::load(PersistentPool &pool)
pool.stream() >> count;
subProjects.clear();
subProjects.reserve(count);
- for (; --count >= 0;) {
- ResolvedProjectPtr p = pool.idLoadS<ResolvedProject>();
- subProjects.append(p);
- }
-
- m_projectProperties = pool.loadVariantMap();
+ for (; --count >= 0;)
+ subProjects.append(pool.load<ResolvedProjectPtr>());
+ pool.load(m_projectProperties);
}
void ResolvedProject::store(PersistentPool &pool) const
{
- pool.storeString(name);
+ pool.store(name);
location.store(pool);
pool.stream()
<< enabled
@@ -991,7 +988,7 @@ void TopLevelProject::store(Logger logger) const
void TopLevelProject::load(PersistentPool &pool)
{
ResolvedProject::load(pool);
- m_id = pool.idLoadString();
+ pool.load(m_id);
pool.stream() >> usedEnvironment;
pool.stream() >> canonicalFilePathResults;
pool.stream() >> fileExistsResults;
@@ -1011,7 +1008,7 @@ void TopLevelProject::load(PersistentPool &pool)
e.load(pool);
warningsEncountered << e;
}
- buildData.reset(pool.idLoad<ProjectBuildData>());
+ buildData.reset(pool.load<ProjectBuildData *>());
QBS_CHECK(buildData);
buildData->isDirty = false;
}
@@ -1019,7 +1016,7 @@ void TopLevelProject::load(PersistentPool &pool)
void TopLevelProject::store(PersistentPool &pool) const
{
ResolvedProject::store(pool);
- pool.storeString(m_id);
+ pool.store(m_id);
pool.stream() << usedEnvironment
<< canonicalFilePathResults
<< fileExistsResults
@@ -1269,11 +1266,11 @@ bool artifactPropertyListsAreEqual(const QList<ArtifactPropertiesPtr> &l1,
void ResolvedScanner::load(PersistentPool &pool)
{
- module = pool.idLoadS<ResolvedModule>();
+ pool.load(module);
inputs.load(pool);
pool.stream() >> recursive;
- searchPathsScript = pool.idLoadS<ScriptFunction>();
- scanScript = pool.idLoadS<ScriptFunction>();
+ pool.load(searchPathsScript);
+ pool.load(scanScript);
}
void ResolvedScanner::store(PersistentPool &pool) const
diff --git a/src/lib/corelib/language/property.cpp b/src/lib/corelib/language/property.cpp
index 2556a59a4..c0293baf9 100644
--- a/src/lib/corelib/language/property.cpp
+++ b/src/lib/corelib/language/property.cpp
@@ -48,8 +48,8 @@ void storePropertySet(PersistentPool &pool, const PropertySet &propertySet)
{
pool.stream() << propertySet.count();
foreach (const Property &p, propertySet) {
- pool.storeString(p.moduleName);
- pool.storeString(p.propertyName);
+ pool.store(p.moduleName);
+ pool.store(p.propertyName);
pool.stream() << p.value << static_cast<int>(p.kind);
}
}
@@ -62,8 +62,8 @@ PropertySet restorePropertySet(PersistentPool &pool)
propertySet.reserve(count);
while (--count >= 0) {
Property p;
- p.moduleName = pool.idLoadString();
- p.propertyName = pool.idLoadString();
+ pool.load(p.moduleName);
+ pool.load(p.propertyName);
int k;
pool.stream() >> p.value >> k;
p.kind = static_cast<Property::Kind>(k);
@@ -76,12 +76,12 @@ void storePropertyHash(PersistentPool &pool, const PropertyHash &propertyHash)
{
pool.stream() << propertyHash.count();
for (auto it = propertyHash.constBegin(); it != propertyHash.constEnd(); ++it) {
- pool.storeString(it.key());
+ pool.store(it.key());
const PropertySet &properties = it.value();
pool.stream() << properties.count();
foreach (const Property &p, properties) {
- pool.storeString(p.moduleName);
- pool.storeString(p.propertyName);
+ pool.store(p.moduleName);
+ pool.store(p.propertyName);
pool.stream() << p.value; // kind is always PropertyInModule
}
}
@@ -94,15 +94,15 @@ PropertyHash restorePropertyHash(PersistentPool &pool)
PropertyHash propertyHash;
propertyHash.reserve(count);
while (--count >= 0) {
- const QString artifactName = pool.idLoadString();
+ const auto &artifactName = pool.load<QString>();
int listCount;
pool.stream() >> listCount;
PropertySet list;
list.reserve(listCount);
while (--listCount >= 0) {
Property p;
- p.moduleName = pool.idLoadString();
- p.propertyName = pool.idLoadString();
+ pool.load(p.moduleName);
+ pool.load(p.propertyName);
pool.stream() >> p.value;
p.kind = Property::PropertyInModule;
list += p;
diff --git a/src/lib/corelib/language/propertymapinternal.cpp b/src/lib/corelib/language/propertymapinternal.cpp
index 1105f873f..d1b202fce 100644
--- a/src/lib/corelib/language/propertymapinternal.cpp
+++ b/src/lib/corelib/language/propertymapinternal.cpp
@@ -103,7 +103,7 @@ QString PropertyMapInternal::toJSLiteral() const
void PropertyMapInternal::load(PersistentPool &pool)
{
- m_value = pool.loadVariantMap();
+ pool.load(m_value);
}
void PropertyMapInternal::store(PersistentPool &pool) const
diff --git a/src/lib/corelib/language/resolvedfilecontext.cpp b/src/lib/corelib/language/resolvedfilecontext.cpp
index 9dc7ede8c..dba5b5fde 100644
--- a/src/lib/corelib/language/resolvedfilecontext.cpp
+++ b/src/lib/corelib/language/resolvedfilecontext.cpp
@@ -52,15 +52,15 @@ ResolvedFileContext::ResolvedFileContext(const FileContextBase &ctx)
void ResolvedFileContext::load(PersistentPool &pool)
{
- m_filePath = pool.idLoadString();
- m_jsExtensions = pool.idLoadStringList();
- m_searchPaths = pool.idLoadStringList();
+ pool.load(m_filePath);
+ pool.load(m_jsExtensions);
+ pool.load(m_searchPaths);
int count;
pool.stream() >> count;
for (int i = 0; i < count; ++i) {
JsImport jsi;
- jsi.scopeName = pool.idLoadString();
- jsi.filePaths = pool.idLoadStringList();
+ pool.load(jsi.scopeName);
+ pool.load(jsi.filePaths);
jsi.location.load(pool);
m_jsImports << jsi;
}
@@ -68,13 +68,13 @@ void ResolvedFileContext::load(PersistentPool &pool)
void ResolvedFileContext::store(PersistentPool &pool) const
{
- pool.storeString(m_filePath);
- pool.storeStringList(m_jsExtensions);
- pool.storeStringList(m_searchPaths);
+ pool.store(m_filePath);
+ pool.store(m_jsExtensions);
+ pool.store(m_searchPaths);
pool.stream() << m_jsImports.count();
foreach (const JsImport &jsi, m_jsImports) {
- pool.storeString(jsi.scopeName);
- pool.storeStringList(jsi.filePaths);
+ pool.store(jsi.scopeName);
+ pool.store(jsi.filePaths);
jsi.location.store(pool);
}
}
diff --git a/src/lib/corelib/tools/codelocation.cpp b/src/lib/corelib/tools/codelocation.cpp
index 34c068b85..c47faa4c5 100644
--- a/src/lib/corelib/tools/codelocation.cpp
+++ b/src/lib/corelib/tools/codelocation.cpp
@@ -127,7 +127,7 @@ void CodeLocation::load(Internal::PersistentPool &pool)
if (!isValid)
return;
d = new CodeLocationPrivate;
- d->filePath = pool.idLoadString();
+ pool.load(d->filePath);
pool.stream() >> d->line;
pool.stream() >> d->column;
}
@@ -136,7 +136,7 @@ void CodeLocation::store(Internal::PersistentPool &pool) const
{
if (d) {
pool.stream() << 1;
- pool.storeString(d->filePath);
+ pool.store(d->filePath);
pool.stream() << d->line;
pool.stream() << d->column;
} else {
diff --git a/src/lib/corelib/tools/error.cpp b/src/lib/corelib/tools/error.cpp
index 394fd8c88..48590a494 100644
--- a/src/lib/corelib/tools/error.cpp
+++ b/src/lib/corelib/tools/error.cpp
@@ -109,14 +109,14 @@ bool ErrorItem::isBacktraceItem() const
void ErrorItem::load(Internal::PersistentPool &pool)
{
- d->description = pool.idLoadString();
+ pool.load(d->description);
d->codeLocation.load(pool);
pool.stream() >> d->isBacktraceItem;
}
void ErrorItem::store(Internal::PersistentPool &pool) const
{
- pool.storeString(d->description);
+ pool.store(d->description);
d->codeLocation.store(pool);
pool.stream() << d->isBacktraceItem;
}
diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp
index 709e99fea..140766145 100644
--- a/src/lib/corelib/tools/persistence.cpp
+++ b/src/lib/corelib/tools/persistence.cpp
@@ -141,7 +141,7 @@ void PersistentPool::closeStream()
m_stream.setDevice(0);
}
-void PersistentPool::store(const PersistentObject *object)
+void PersistentPool::storePersistentObject(const PersistentObject *object)
{
if (!object) {
m_stream << -1;
@@ -158,7 +158,7 @@ void PersistentPool::store(const PersistentObject *object)
}
}
-void PersistentPool::store(const QVariantMap &map)
+void PersistentPool::storeVariantMap(const QVariantMap &map)
{
m_stream << map.count();
for (QVariantMap::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) {
@@ -180,7 +180,7 @@ QVariantMap PersistentPool::loadVariantMap()
return map;
}
-void PersistentPool::store(const QVariant &variant)
+void PersistentPool::storeVariant(const QVariant &variant)
{
const quint32 type = static_cast<quint32>(variant.type());
m_stream << type;
@@ -189,10 +189,10 @@ void PersistentPool::store(const QVariant &variant)
storeString(variant.toString());
break;
case QMetaType::QStringList:
- storeStringList(variant.toStringList());
+ store(variant.toStringList());
break;
case QMetaType::QVariantList:
- storeContainer(variant.toList());
+ store(variant.toList());
break;
case QMetaType::QVariantMap:
store(variant.toMap());
@@ -212,7 +212,7 @@ QVariant PersistentPool::loadVariant()
value = idLoadString();
break;
case QMetaType::QStringList:
- value = idLoadStringList();
+ value = load<QStringList>();
break;
case QMetaType::QVariantList: {
QVariantList l;
@@ -290,39 +290,5 @@ QString PersistentPool::idLoadString()
return loadString(id);
}
-void PersistentPool::storeStringSet(const QSet<QString> &t)
-{
- m_stream << t.count();
- foreach (const QString &s, t)
- storeString(s);
-}
-
-QSet<QString> PersistentPool::idLoadStringSet()
-{
- int i;
- m_stream >> i;
- QSet<QString> result;
- for (; --i >= 0;)
- result += idLoadString();
- return result;
-}
-
-void PersistentPool::storeStringList(const QStringList &t)
-{
- m_stream << t.count();
- foreach (const QString &s, t)
- storeString(s);
-}
-
-QStringList PersistentPool::idLoadStringList()
-{
- int i;
- m_stream >> i;
- QStringList result;
- for (; --i >= 0;)
- result += idLoadString();
- return result;
-}
-
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h
index 70e94a870..25529ccf7 100644
--- a/src/lib/corelib/tools/persistence.h
+++ b/src/lib/corelib/tools/persistence.h
@@ -49,6 +49,8 @@
#include <QVariantMap>
#include <QVector>
+#include <type_traits>
+
namespace qbs {
namespace Internal {
@@ -64,6 +66,18 @@ public:
QVariantMap projectConfig;
};
+ // We need a helper class template, because we require partial specialization for some of
+ // the aggregate types, which is not possible with function templates.
+ template<typename T, typename Enable = void> struct Helper { };
+
+ template<typename T> void store(const T &value) { Helper<T>().store(value, this); }
+ template<typename T> void load(T &value) { Helper<T>().load(value, this); }
+ template<typename T> T load() {
+ T tmp;
+ Helper<T>().load(tmp, this);
+ return tmp;
+ }
+
void load(const QString &filePath);
void setupWriteStream(const QString &filePath);
void finalizeWriteStream();
@@ -71,47 +85,29 @@ public:
void clear();
QDataStream &stream();
+ const HeadData &headData() const { return m_headData; }
+ void setHeadData(const HeadData &hd) { m_headData = hd; }
+
+private:
+ typedef int PersistentObjectId;
+
template <typename T> T *idLoad();
- template <typename T> void loadContainer(T &container);
template <class T> QSharedPointer<T> idLoadS();
- template <typename T> void loadContainerS(T &container);
+ template <class T> T *loadRaw(PersistentObjectId id);
+ template <class T> QSharedPointer<T> load(PersistentObjectId id);
- void store(const QSharedPointer<const PersistentObject> &ptr) { store(ptr.data()); }
- void store(const PersistentObject *object);
- template <typename T> void storeContainer(const T &container);
+ void storePersistentObject(const PersistentObject *object);
- void store(const QVariantMap &map);
+ void storeVariantMap(const QVariantMap &map);
QVariantMap loadVariantMap();
- void store(const QVariant &variant);
+ void storeVariant(const QVariant &variant);
QVariant loadVariant();
void storeString(const QString &t);
QString loadString(int id);
QString idLoadString();
- void storeStringSet(const QSet<QString> &t);
- QSet<QString> loadStringSet(const QList<int> &id);
- QSet<QString> idLoadStringSet();
-
- void storeStringList(const QStringList &t);
- QStringList loadStringList(const QList<int> &ids);
- QStringList idLoadStringList();
-
- const HeadData &headData() const { return m_headData; }
- void setHeadData(const HeadData &hd) { m_headData = hd; }
-
-private:
- typedef int PersistentObjectId;
-
- template<typename T> struct RemovePointer { typedef T Type; };
- template<typename T> struct RemovePointer<T*> { typedef T Type; };
- template <class T> struct RemoveConst { typedef T Type; };
- template <class T> struct RemoveConst<const T> { typedef T Type; };
-
- template <class T> T *loadRaw(PersistentObjectId id);
- template <class T> QSharedPointer<T> load(PersistentObjectId id);
-
QDataStream m_stream;
HeadData m_headData;
QVector<PersistentObject *> m_loadedRaw;
@@ -132,16 +128,6 @@ template <typename T> inline T *PersistentPool::idLoad()
return loadRaw<T>(id);
}
-template <typename T> inline void PersistentPool::loadContainer(T &container)
-{
- int count;
- stream() >> count;
- container.clear();
- container.reserve(count);
- for (int i = count; --i >= 0;)
- container += idLoad<typename RemovePointer<typename T::value_type>::Type>();
-}
-
template <class T> inline QSharedPointer<T> PersistentPool::idLoadS()
{
PersistentObjectId id;
@@ -149,25 +135,6 @@ template <class T> inline QSharedPointer<T> PersistentPool::idLoadS()
return load<T>(id);
}
-template <typename T> inline void PersistentPool::loadContainerS(T &container)
-{
- int count;
- stream() >> count;
- container.clear();
- container.reserve(count);
- for (int i = count; --i >= 0;)
- container += idLoadS<typename RemoveConst<typename T::value_type::value_type>::Type>();
-}
-
-template <typename T> inline void PersistentPool::storeContainer(const T &container)
-{
- stream() << container.count();
- typename T::const_iterator it = container.constBegin();
- const typename T::const_iterator itEnd = container.constEnd();
- for (; it != itEnd; ++it)
- store(*it);
-}
-
template <class T> inline T *PersistentPool::loadRaw(PersistentObjectId id)
{
if (id < 0)
@@ -208,6 +175,87 @@ template <class T> inline QSharedPointer<T> PersistentPool::load(PersistentObjec
return t;
}
+/***** Specializations of Helper class *****/
+
+template<typename T>
+struct PersistentPool::Helper<T, typename std::enable_if<std::is_integral<T>::value>::type>
+{
+ static void store(const T &value, PersistentPool *pool) { pool->stream() << value; }
+ static void load(T &value, PersistentPool *pool) { pool->stream() >> value; }
+};
+
+// TODO: Use constexpr function once we require MSVC 2015.
+template<typename T> struct IsPersistentObject
+{
+ static const bool value = std::is_base_of<PersistentObject, T>::value;
+};
+
+template<typename T>
+struct PersistentPool::Helper<QSharedPointer<T>,
+ typename std::enable_if<IsPersistentObject<T>::value>::type>
+{
+ static void store(const QSharedPointer<T> &value, PersistentPool *pool)
+ {
+ pool->store(value.data());
+ }
+ static void load(QSharedPointer<T> &value, PersistentPool *pool)
+ {
+ value = pool->idLoadS<typename std::remove_const<T>::type>();
+ }
+};
+
+template<typename T>
+struct PersistentPool::Helper<T *, typename std::enable_if<IsPersistentObject<T>::value>::type>
+{
+ static void store(const T *value, PersistentPool *pool) { pool->storePersistentObject(value); }
+ void load(T* &value, PersistentPool *pool) { value = pool->idLoad<T>(); }
+};
+
+template<> struct PersistentPool::Helper<QString>
+{
+ static void store(const QString &s, PersistentPool *pool) { pool->storeString(s); }
+ static void load(QString &s, PersistentPool *pool) { s = pool->idLoadString(); }
+};
+
+template<> struct PersistentPool::Helper<QVariant>
+{
+ static void store(const QVariant &v, PersistentPool *pool) { pool->storeVariant(v); }
+ static void load(QVariant &v, PersistentPool *pool) { v = pool->loadVariant(); }
+};
+
+template<> struct PersistentPool::Helper<QVariantMap>
+{
+ static void store(const QVariantMap &map, PersistentPool *pool) { pool->storeVariantMap(map); }
+ static void load(QVariantMap &map, PersistentPool *pool) { map = pool->loadVariantMap(); }
+};
+
+class ArtifactSet;
+template<typename T> struct IsSimpleContainer { static const bool value = false; };
+template<> struct IsSimpleContainer<ArtifactSet> { static const bool value = true; };
+template<> struct IsSimpleContainer<QStringList> { static const bool value = true; };
+template<typename T> struct IsSimpleContainer<QVector<T>> { static const bool value = true; };
+template<typename T> struct IsSimpleContainer<QList<T>> { static const bool value = true; };
+template<typename T> struct IsSimpleContainer<QSet<T>> { static const bool value = true; };
+
+template<typename T>
+struct PersistentPool::Helper<T, typename std::enable_if<IsSimpleContainer<T>::value>::type>
+{
+ static void store(const T &container, PersistentPool *pool)
+ {
+ pool->stream() << container.count();
+ for (auto it = container.cbegin(); it != container.cend(); ++it)
+ pool->store(*it);
+ }
+ static void load(T &container, PersistentPool *pool)
+ {
+ const int count = pool->load<int>();
+ container.clear();
+ container.reserve(count);
+ for (int i = count; --i >= 0;)
+ container += pool->load<typename T::value_type>();
+ }
+};
+
} // namespace Internal
} // namespace qbs