diff options
author | Brad King <brad.king@kitware.com> | 2009-07-22 18:22:45 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2009-07-22 18:22:45 (GMT) |
commit | fd10589995fe942ceecbc0e1d5f869a534abdbba (patch) | |
tree | ccf5fcb2f87b072108fb9f859d311e345720007a /Source/cmDefinitions.cxx | |
parent | 267085f338c917f72950ca55f5cc09760cb4a894 (diff) | |
download | CMake-fd10589995fe942ceecbc0e1d5f869a534abdbba.zip CMake-fd10589995fe942ceecbc0e1d5f869a534abdbba.tar.gz CMake-fd10589995fe942ceecbc0e1d5f869a534abdbba.tar.bz2 |
ENH: Improve dynamic variable scope implementation
Previously each new variable scope (subdirectory or function call) in
the CMake language created a complete copy of the key->value definition
map. This avoids the copy using transitive lookups up the scope stack.
Results of queries answered by parents are stored locally to maintain
locality of reference.
The class cmDefinitions replaces cmMakefile::DefinitionsMap, and is
aware of its enclosing scope. Each scope stores only the definitions
set (or unset!) inside it relative to the enclosing scope.
Diffstat (limited to 'Source/cmDefinitions.cxx')
-rw-r--r-- | Source/cmDefinitions.cxx | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx new file mode 100644 index 0000000..13bfc6a --- /dev/null +++ b/Source/cmDefinitions.cxx @@ -0,0 +1,167 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmDefinitions.h" + +//---------------------------------------------------------------------------- +cmDefinitions::Def cmDefinitions::NoDef; + +//---------------------------------------------------------------------------- +cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent) +{ +} + +//---------------------------------------------------------------------------- +void cmDefinitions::Reset(cmDefinitions* parent) +{ + this->Up = parent; + this->Map.clear(); +} + +//---------------------------------------------------------------------------- +cmDefinitions::Def const& +cmDefinitions::GetInternal(const char* key) +{ + MapType::const_iterator i = this->Map.find(key); + if(i != this->Map.end()) + { + return i->second; + } + else if(cmDefinitions* up = this->Up) + { + // Query the parent scope and store the result locally. + Def def = up->GetInternal(key); + return this->Map.insert(MapType::value_type(key, def)).first->second; + } + return this->NoDef; +} + +//---------------------------------------------------------------------------- +cmDefinitions::Def const& +cmDefinitions::SetInternal(const char* key, Def const& def) +{ + if(this->Up || def.Exists) + { + // In lower scopes we store keys, defined or not. + MapType::iterator i = this->Map.find(key); + if(i == this->Map.end()) + { + i = this->Map.insert(MapType::value_type(key, def)).first; + } + else + { + i->second = def; + } + return i->second; + } + else + { + // In the top-most scope we need not store undefined keys. + this->Map.erase(key); + return this->NoDef; + } +} + +//---------------------------------------------------------------------------- +const char* cmDefinitions::Get(const char* key) +{ + Def const& def = this->GetInternal(key); + return def.Exists? def.c_str() : 0; +} + +//---------------------------------------------------------------------------- +const char* cmDefinitions::Set(const char* key, const char* value) +{ + Def const& def = this->SetInternal(key, Def(value)); + return def.Exists? def.c_str() : 0; +} + +//---------------------------------------------------------------------------- +cmDefinitions cmDefinitions::Closure() const +{ + return cmDefinitions(ClosureTag(), this); +} + +//---------------------------------------------------------------------------- +cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root): + Up(0) +{ + std::set<cmStdString> undefined; + this->ClosureImpl(undefined, root); +} + +//---------------------------------------------------------------------------- +void cmDefinitions::ClosureImpl(std::set<cmStdString>& undefined, + cmDefinitions const* defs) +{ + // Consider local definitions. + for(MapType::const_iterator mi = defs->Map.begin(); + mi != defs->Map.end(); ++mi) + { + // Use this key if it is not already set or unset. + if(this->Map.find(mi->first) == this->Map.end() && + undefined.find(mi->first) == undefined.end()) + { + if(mi->second.Exists) + { + this->Map.insert(*mi); + } + else + { + undefined.insert(mi->first); + } + } + } + + // Traverse parents. + if(cmDefinitions const* up = defs->Up) + { + this->ClosureImpl(undefined, up); + } +} + +//---------------------------------------------------------------------------- +std::set<cmStdString> cmDefinitions::ClosureKeys() const +{ + std::set<cmStdString> defined; + std::set<cmStdString> undefined; + this->ClosureKeys(defined, undefined); + return defined; +} + +//---------------------------------------------------------------------------- +void cmDefinitions::ClosureKeys(std::set<cmStdString>& defined, + std::set<cmStdString>& undefined) const +{ + // Consider local definitions. + for(MapType::const_iterator mi = this->Map.begin(); + mi != this->Map.end(); ++mi) + { + // Use this key if it is not already set or unset. + if(defined.find(mi->first) == defined.end() && + undefined.find(mi->first) == undefined.end()) + { + std::set<cmStdString>& m = mi->second.Exists? defined : undefined; + m.insert(mi->first); + } + } + + // Traverse parents. + if(cmDefinitions const* up = this->Up) + { + up->ClosureKeys(defined, undefined); + } +} |