diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 44f87dba80..55879de720 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -148,6 +148,8 @@ add_library( cmComputeTargetDepends.cxx cmConfigureLog.h cmConfigureLog.cxx + cmConstStack.h + cmConstStack.tcc cmCPackPropertiesGenerator.h cmCPackPropertiesGenerator.cxx cmCryptoHash.cxx @@ -460,8 +462,6 @@ add_library( cmSourceFileLocationKind.h cmSourceGroup.cxx cmSourceGroup.h - cmStack.h - cmStack.tcc cmStandardLevel.h cmStandardLevelResolver.cxx cmStandardLevelResolver.h diff --git a/Source/cmStack.h b/Source/cmConstStack.h similarity index 50% rename from Source/cmStack.h rename to Source/cmConstStack.h index 1c11090a98..d6059e7022 100644 --- a/Source/cmStack.h +++ b/Source/cmConstStack.h @@ -5,31 +5,19 @@ #include "cmConfigure.h" // IWYU pragma: keep #include -#include -enum class cmStackType +/** Base class template for CRTP to represent a stack of constant values. + Provide value semantics, but use efficient reference-counting underneath + to avoid copies. */ +template +class cmConstStack { - Const, - Mutable, -}; - -template -struct cmStackEntry; - -/** Base class template for CRTP to represent a stack of values. - Copies of the stack share data; mutating data on one copy will - change the data on all copies. */ -template -class cmStack -{ - using Entry = cmStackEntry; - + struct Entry; std::shared_ptr TopEntry; public: /** Default-construct an empty stack. */ - cmStack(); + cmConstStack(); /** Get a stack with the given call context added to the top. */ Stack Push(T value) const; @@ -41,21 +29,11 @@ public: /** Get the value at the top of the stack. This may be called only if Empty() would return false. */ T const& Top() const; - template - typename std::enable_if::type& Top(); /** Return true if this stack is empty. */ bool Empty() const; protected: - using Base = cmStack; - - cmStack(std::shared_ptr parent, T value); - cmStack(std::shared_ptr top); + cmConstStack(std::shared_ptr parent, T value); + cmConstStack(std::shared_ptr top); }; - -/** Specialization of cmStack for CRTP to represent a stack of constant values. - Provide value semantics, but use efficient reference-counting underneath - to avoid copies. */ -template -using cmConstStack = cmStack; diff --git a/Source/cmConstStack.tcc b/Source/cmConstStack.tcc new file mode 100644 index 0000000000..ee69c9c478 --- /dev/null +++ b/Source/cmConstStack.tcc @@ -0,0 +1,62 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ + +#include +#include +#include + +template +struct cmConstStack::Entry +{ + Entry(std::shared_ptr parent, T value) + : Value(std::move(value)) + , Parent(std::move(parent)) + { + } + + T Value; + std::shared_ptr Parent; +}; + +template +cmConstStack::cmConstStack() = default; + +template +Stack cmConstStack::Push(T value) const +{ + return Stack(this->TopEntry, std::move(value)); +} + +template +Stack cmConstStack::Pop() const +{ + assert(this->TopEntry); + return Stack(this->TopEntry->Parent); +} + +template +T const& cmConstStack::Top() const +{ + assert(this->TopEntry); + return this->TopEntry->Value; +} + +template +bool cmConstStack::Empty() const +{ + return !this->TopEntry; +} + +template +cmConstStack::cmConstStack(std::shared_ptr parent, + T value) + : TopEntry( + std::make_shared(std::move(parent), std::move(value))) +{ +} + +template +cmConstStack::cmConstStack(std::shared_ptr top) + : TopEntry(std::move(top)) +{ +} diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index c2dfc08be5..acdfa67853 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1225,8 +1225,8 @@ bool cmFindPackageCommand::FindPackage( FlushDebugBufferOnExit flushDebugBufferOnExit(*this); PushPopRootPathStack pushPopRootPathStack(*this); SetRestoreFindDefinitions setRestoreFindDefinitions(*this); - cmFindPackageStackRAII findPackageStackRAII(this->Makefile, this->Name, - this->PackageInfo); + cmMakefile::FindPackageStackRAII findPackageStackRAII( + this->Makefile, this->Name, this->PackageInfo); // See if we have been told to delegate to FetchContent or some other // redirected config package first. We have to check all names that diff --git a/Source/cmFindPackageStack.cxx b/Source/cmFindPackageStack.cxx index 6f5045ae74..0803049a06 100644 --- a/Source/cmFindPackageStack.cxx +++ b/Source/cmFindPackageStack.cxx @@ -3,13 +3,5 @@ #define cmFindPackageStack_cxx #include "cmFindPackageStack.h" -#include "cmStack.tcc" // IWYU pragma: keep -template class cmStack; - -template cmFindPackageCall& -cmStack::Top(); - -cmFindPackageCall const& cmFindPackageStack::Top() const -{ - return this->cmStack::Top(); -} +#include "cmConstStack.tcc" // IWYU pragma: keep +template class cmConstStack; diff --git a/Source/cmFindPackageStack.h b/Source/cmFindPackageStack.h index 3a5804120b..e3ac8ca78e 100644 --- a/Source/cmFindPackageStack.h +++ b/Source/cmFindPackageStack.h @@ -10,9 +10,7 @@ #include -#include "cmStack.h" - -class cmMakefile; +#include "cmConstStack.h" /** * This data represents the actual contents of find_package @@ -43,43 +41,15 @@ public: unsigned int Index; }; -/** - * RAII type to manage the find_package call stack. - */ -// Note: implemented in cmMakefile.cxx -class cmFindPackageStackRAII -{ - cmMakefile* Makefile; - -public: - cmFindPackageStackRAII(cmMakefile* mf, std::string const& pkg, - std::shared_ptr pkgInfo); - ~cmFindPackageStackRAII(); - - cmFindPackageStackRAII(cmFindPackageStackRAII const&) = delete; - cmFindPackageStackRAII& operator=(cmFindPackageStackRAII const&) = delete; -}; - /** * Represents a stack of find_package calls with efficient value semantics. */ class cmFindPackageStack - : protected cmStack + : public cmConstStack { - using cmStack::cmStack; - friend cmFindPackageStack::Base; - friend class cmFindPackageStackRAII; - -public: - using cmStack::Push; - using cmStack::Pop; - using cmStack::Empty; - - cmFindPackageCall const& Top() const; + using cmConstStack::cmConstStack; + friend class cmConstStack; }; #ifndef cmFindPackageStack_cxx -extern template class cmStack; - -extern template cmFindPackageCall& -cmStack::Top(); +extern template class cmConstStack; #endif diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index d3e62885f4..036788aced 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -454,9 +454,8 @@ bool cmListFile::ParseString(cm::string_view str, char const* virtual_filename, return !parseError; } -#include "cmStack.tcc" -template class cmStack; +#include "cmConstStack.tcc" +template class cmConstStack; std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc) { diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 32093d2d46..fd3b7b413c 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -13,8 +13,8 @@ #include #include +#include "cmConstStack.h" #include "cmList.h" -#include "cmStack.h" #include "cmSystemTools.h" /** \class cmListFileCache @@ -170,12 +170,11 @@ bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs); class cmListFileBacktrace : public cmConstStack { - using cmStack::cmStack; - friend cmListFileBacktrace::Base; + using cmConstStack::cmConstStack; + friend class cmConstStack; }; #ifndef cmListFileCache_cxx -extern template class cmStack; +extern template class cmConstStack; #endif // Wrap type T as a value with a backtrace. For purposes of diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 714c84c86c..e968723bf4 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4241,7 +4241,7 @@ cmMakefile::MacroPushPop::~MacroPushPop() this->Makefile->PopMacroScope(this->ReportError); } -cmFindPackageStackRAII::cmFindPackageStackRAII( +cmMakefile::FindPackageStackRAII::FindPackageStackRAII( cmMakefile* mf, std::string const& name, std::shared_ptr pkgInfo) : Makefile(mf) @@ -4255,7 +4255,7 @@ cmFindPackageStackRAII::cmFindPackageStackRAII( this->Makefile->FindPackageStackNextIndex++; } -cmFindPackageStackRAII::~cmFindPackageStackRAII() +cmMakefile::FindPackageStackRAII::~FindPackageStackRAII() { this->Makefile->FindPackageStackNextIndex = this->Makefile->FindPackageStack.Top().Index + 1; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 856c02b85a..73ab2124b8 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1034,7 +1034,21 @@ public: // searches std::deque> FindPackageRootPathStack; - friend class cmFindPackageStackRAII; + /** + * RAII type to manage the find_package call stack. + */ + class FindPackageStackRAII + { + cmMakefile* Makefile; + + public: + FindPackageStackRAII(cmMakefile* mf, std::string const& pkg, + std::shared_ptr pkgInfo); + ~FindPackageStackRAII(); + + FindPackageStackRAII(FindPackageStackRAII const&) = delete; + FindPackageStackRAII& operator=(FindPackageStackRAII const&) = delete; + }; class DebugFindPkgRAII { diff --git a/Source/cmStack.tcc b/Source/cmStack.tcc deleted file mode 100644 index 210833b453..0000000000 --- a/Source/cmStack.tcc +++ /dev/null @@ -1,85 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file LICENSE.rst or https://cmake.org/licensing for details. */ - -#include -#include -#include - -template -struct cmStackEntry -{ - cmStackEntry(std::shared_ptr parent, T value) - : Value(std::move(value)) - , Parent(std::move(parent)) - { - } - - T mutable Value; - std::shared_ptr Parent; -}; - -template -struct cmStackEntry -{ - cmStackEntry(std::shared_ptr parent, T value) - : Value(std::move(value)) - , Parent(std::move(parent)) - { - } - - T Value; - std::shared_ptr Parent; -}; - -template -cmStack::cmStack() = default; - -template -Stack cmStack::Push(T value) const -{ - return Stack(this->TopEntry, std::move(value)); -} - -template -Stack cmStack::Pop() const -{ - assert(this->TopEntry); - return Stack(this->TopEntry->Parent); -} - -template -T const& cmStack::Top() const -{ - assert(this->TopEntry); - return this->TopEntry->Value; -} - -template -template -typename std::enable_if::type& cmStack::Top() -{ - static_assert(Mutable == cmStackType::Mutable, - "T& cmStack::Top should only exist for mutable cmStack"); - assert(this->TopEntry); - return this->TopEntry->Value; -} - -template -bool cmStack::Empty() const -{ - return !this->TopEntry; -} - -template -cmStack::cmStack(std::shared_ptr parent, - T value) - : TopEntry( - std::make_shared(std::move(parent), std::move(value))) -{ -} - -template -cmStack::cmStack(std::shared_ptr top) - : TopEntry(std::move(top)) -{ -} diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index 02b9bed33c..a613bce1c9 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -66,12 +66,8 @@ { include: [ "", private, "\"cmCursesStandardIncludes.h\"", public ] }, { include: [ "\"form.h\"", private, "\"cmCursesStandardIncludes.h\"", public ] }, - # Help IWYU understand our explicit instantiation for cmStack. - { symbol: [ "cmStack::cmStack", private, "\"cmStack.h\"", public ] }, - { symbol: [ "cmStack::Empty", private, "\"cmStack.h\"", public ] }, - { symbol: [ "cmStack::Top", private, "\"cmStack.h\"", public ] }, - { symbol: [ "cmStack::Pop", private, "\"cmStack.h\"", public ] }, - { symbol: [ "cmStack::Push", private, "\"cmStack.h\"", public ] }, + # Help IWYU understand our explicit instantiation for cmConstStack. + { symbol: [ "cmConstStack::cmConstStack", private, "\"cmConstStack.h\"", public ] }, ] # vim: set ft=toml: