From 281f59536f8c16f9eacf175f8316a82f09629203 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 25 May 2018 12:43:26 -0400 Subject: IWYU: Define a macro to tell code it is preprocessing for iwyu There are some cases where satisfying IWYU breaks compilation, such as forward-declaring the `std::hash<>` template with C++ standard libraries that use an inline namespace inside `std`. Define a macro during include-what-you-use preprocessing so that code can adapt. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ee67cb..e20d770 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -285,7 +285,7 @@ if(CMake_RUN_IWYU) message(FATAL_ERROR "CMake_RUN_IWYU is ON but include-what-you-use is not found!") endif() set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE - "${IWYU_COMMAND};-Xiwyu;--mapping_file=${CMake_SOURCE_DIR}/Utilities/IWYU/mapping.imp;-w") + "${IWYU_COMMAND};-Xiwyu;--mapping_file=${CMake_SOURCE_DIR}/Utilities/IWYU/mapping.imp;-w;-DCMAKE_IWYU") endif() -- cgit v0.12 From 6d7c0740556fb06689c4d332fac685d70d83b1fe Mon Sep 17 00:00:00 2001 From: Le Minh Phuc Date: Wed, 23 May 2018 16:43:04 +0800 Subject: cmAlgorithms: Speed up cmRemoveDuplicates method Use a hash table instead of a sorted vector to track entries. Co-authored-by: Chu Qinghao --- Source/cmAlgorithms.h | 47 ++++++------------------------------------- Source/cmFindPackageCommand.h | 32 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 244dc1c..c4eb62b 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -275,55 +276,19 @@ typename Range::const_iterator cmRemoveMatching(Range& r, MatchRange const& m) ContainerAlgorithms::BinarySearcher(m)); } -namespace ContainerAlgorithms { - -template -struct RemoveDuplicatesAPI -{ - typedef typename Range::const_iterator const_iterator; - typedef typename Range::const_iterator value_type; - - static bool lessThan(value_type a, value_type b) { return *a < *b; } - static value_type uniqueValue(const_iterator a) { return a; } - template - static bool valueCompare(It it, const_iterator it2) - { - return **it != *it2; - } -}; - -template -struct RemoveDuplicatesAPI -{ - typedef typename Range::const_iterator const_iterator; - typedef T* value_type; - - static bool lessThan(value_type a, value_type b) { return a < b; } - static value_type uniqueValue(const_iterator a) { return *a; } - template - static bool valueCompare(It it, const_iterator it2) - { - return *it != *it2; - } -}; -} - template typename Range::const_iterator cmRemoveDuplicates(Range& r) { - typedef ContainerAlgorithms::RemoveDuplicatesAPI API; - typedef typename API::value_type T; - std::vector unique; - unique.reserve(r.size()); + typedef typename Range::value_type T; + std::unordered_set unique; std::vector indices; size_t count = 0; const typename Range::const_iterator end = r.end(); for (typename Range::const_iterator it = r.begin(); it != end; ++it, ++count) { - const typename std::vector::iterator low = std::lower_bound( - unique.begin(), unique.end(), API::uniqueValue(it), API::lessThan); - if (low == unique.end() || API::valueCompare(low, it)) { - unique.insert(low, API::uniqueValue(it)); + const typename std::unordered_set::iterator occur = unique.find(*it); + if (occur == unique.end()) { + unique.insert(*it); } else { indices.push_back(count); } diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 150a51d..68b5ec0 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -6,11 +6,25 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cm_kwiml.h" +#include #include #include #include #include +// IWYU insists we should forward-declare instead of including , +// but we cannot forward-declare reliably because some C++ standard libraries +// put the template in an inline namespace. +#ifdef CMAKE_IWYU +/* clang-format off */ +namespace std { + template struct hash; +} +/* clang-format on */ +#else +#include +#endif + #include "cmFindCommon.h" class cmCommand; @@ -194,6 +208,24 @@ private: } }; std::vector ConsideredConfigs; + + friend struct std::hash; +}; + +namespace std { + +template <> +struct hash +{ + typedef cmFindPackageCommand::ConfigFileInfo argument_type; + typedef size_t result_type; + + result_type operator()(argument_type const& s) const noexcept + { + result_type const h(std::hash{}(s.filename)); + return h; + } }; +} #endif -- cgit v0.12