forked from qt-creator/qt-creator
Clang: Fix set_union bug
std::set_union in libC++ is broken for move iterators. We has to use temporarily our own implementation which can be removed if we move to a newer version of XCode. Task-number: QTCREATORBUG-22246 Change-Id: I8fccc8aab5f8af738aa2e589ba65924363cd818d Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "generatedfiles.h"
|
#include "generatedfiles.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
void GeneratedFiles::update(V2::FileContainers &&fileContainers)
|
void GeneratedFiles::update(V2::FileContainers &&fileContainers)
|
||||||
@@ -36,7 +38,7 @@ void GeneratedFiles::update(V2::FileContainers &&fileContainers)
|
|||||||
return first.filePath < second.filePath;
|
return first.filePath < second.filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::set_union(std::make_move_iterator(fileContainers.begin()),
|
Utils::set_union(std::make_move_iterator(fileContainers.begin()),
|
||||||
std::make_move_iterator(fileContainers.end()),
|
std::make_move_iterator(fileContainers.end()),
|
||||||
std::make_move_iterator(m_fileContainers.begin()),
|
std::make_move_iterator(m_fileContainers.begin()),
|
||||||
std::make_move_iterator(m_fileContainers.end()),
|
std::make_move_iterator(m_fileContainers.end()),
|
||||||
@@ -55,7 +57,7 @@ void GeneratedFiles::update(const V2::FileContainers &fileContainers)
|
|||||||
return first.filePath < second.filePath;
|
return first.filePath < second.filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::set_union(fileContainers.begin(),
|
Utils::set_union(fileContainers.begin(),
|
||||||
fileContainers.end(),
|
fileContainers.end(),
|
||||||
std::make_move_iterator(m_fileContainers.begin()),
|
std::make_move_iterator(m_fileContainers.begin()),
|
||||||
std::make_move_iterator(m_fileContainers.end()),
|
std::make_move_iterator(m_fileContainers.end()),
|
||||||
|
@@ -862,4 +862,70 @@ std::make_signed_t<typename Container::size_type> ssize(Container container)
|
|||||||
{
|
{
|
||||||
return static_cast<std::make_signed_t<typename Container::size_type>>(container.size());
|
return static_cast<std::make_signed_t<typename Container::size_type>>(container.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Compare>
|
||||||
|
struct CompareIter
|
||||||
|
{
|
||||||
|
Compare compare;
|
||||||
|
|
||||||
|
explicit constexpr CompareIter(Compare compare)
|
||||||
|
: compare(std::move(compare))
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename Iterator1, typename Iterator2>
|
||||||
|
constexpr bool operator()(Iterator1 it1, Iterator2 it2)
|
||||||
|
{
|
||||||
|
return bool(compare(*it1, *it2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
|
||||||
|
OutputIterator set_union_impl(InputIterator1 first1,
|
||||||
|
InputIterator1 last1,
|
||||||
|
InputIterator2 first2,
|
||||||
|
InputIterator2 last2,
|
||||||
|
OutputIterator result,
|
||||||
|
Compare comp)
|
||||||
|
{
|
||||||
|
auto compare = CompareIter<Compare>(comp);
|
||||||
|
|
||||||
|
while (first1 != last1 && first2 != last2) {
|
||||||
|
if (compare(first1, first2)) {
|
||||||
|
*result = *first1;
|
||||||
|
++first1;
|
||||||
|
} else if (compare(first2, first1)) {
|
||||||
|
*result = *first2;
|
||||||
|
++first2;
|
||||||
|
} else {
|
||||||
|
*result = *first1;
|
||||||
|
++first1;
|
||||||
|
++first2;
|
||||||
|
}
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::copy(first2, last2, std::copy(first1, last1, result));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
|
||||||
|
OutputIterator set_union(InputIterator1 first1,
|
||||||
|
InputIterator1 last1,
|
||||||
|
InputIterator2 first2,
|
||||||
|
InputIterator2 last2,
|
||||||
|
OutputIterator result,
|
||||||
|
Compare comp)
|
||||||
|
{
|
||||||
|
return Utils::set_union_impl(first1, last1, first2, last2, result, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
|
||||||
|
OutputIterator set_union(InputIterator1 first1,
|
||||||
|
InputIterator1 last1,
|
||||||
|
InputIterator2 first2,
|
||||||
|
InputIterator2 last2,
|
||||||
|
OutputIterator result)
|
||||||
|
{
|
||||||
|
return Utils::set_union_impl(
|
||||||
|
first1, last1, first2, last2, result, std::less<typename InputIterator1::value_type>{});
|
||||||
|
}
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
#include <progresscounter.h>
|
#include <progresscounter.h>
|
||||||
#include <sqlitetransaction.h>
|
#include <sqlitetransaction.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
void PchTaskQueue::addPchTasks(PchTasks &&newPchTasks, PchTasks &destination)
|
void PchTaskQueue::addPchTasks(PchTasks &&newPchTasks, PchTasks &destination)
|
||||||
@@ -42,7 +44,7 @@ void PchTaskQueue::addPchTasks(PchTasks &&newPchTasks, PchTasks &destination)
|
|||||||
|
|
||||||
PchTasks mergedPchTasks;
|
PchTasks mergedPchTasks;
|
||||||
mergedPchTasks.reserve(destination.size() + newPchTasks.size());
|
mergedPchTasks.reserve(destination.size() + newPchTasks.size());
|
||||||
std::set_union(std::make_move_iterator(newPchTasks.begin()),
|
Utils::set_union(std::make_move_iterator(newPchTasks.begin()),
|
||||||
std::make_move_iterator(newPchTasks.end()),
|
std::make_move_iterator(newPchTasks.end()),
|
||||||
std::make_move_iterator(destination.begin()),
|
std::make_move_iterator(destination.begin()),
|
||||||
std::make_move_iterator(destination.end()),
|
std::make_move_iterator(destination.end()),
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "pchtaskqueueinterface.h"
|
#include "pchtaskqueueinterface.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets,
|
void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets,
|
||||||
@@ -48,7 +50,7 @@ Result merge(Container &&first, Container &&second)
|
|||||||
Result result;
|
Result result;
|
||||||
result.reserve(first.size() + second.size());
|
result.reserve(first.size() + second.size());
|
||||||
|
|
||||||
std::set_union(std::make_move_iterator(first.begin()),
|
Utils::set_union(std::make_move_iterator(first.begin()),
|
||||||
std::make_move_iterator(first.end()),
|
std::make_move_iterator(first.end()),
|
||||||
std::make_move_iterator(second.begin()),
|
std::make_move_iterator(second.begin()),
|
||||||
std::make_move_iterator(second.end()),
|
std::make_move_iterator(second.end()),
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <projectpartcontainer.h>
|
#include <projectpartcontainer.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
@@ -48,7 +50,7 @@ struct ArgumentsEntry
|
|||||||
ProjectPartIds mergedIds;
|
ProjectPartIds mergedIds;
|
||||||
mergedIds.reserve(ids.size() + newIds.size());
|
mergedIds.reserve(ids.size() + newIds.size());
|
||||||
|
|
||||||
std::set_union(std::make_move_iterator(ids.begin()),
|
Utils::set_union(std::make_move_iterator(ids.begin()),
|
||||||
std::make_move_iterator(ids.end()),
|
std::make_move_iterator(ids.end()),
|
||||||
std::make_move_iterator(newIds.begin()),
|
std::make_move_iterator(newIds.begin()),
|
||||||
std::make_move_iterator(newIds.end()),
|
std::make_move_iterator(newIds.end()),
|
||||||
|
Reference in New Issue
Block a user