Fix osrm-contract, tests, on Windows

As part of graph contraction, node renumbering leads to
in-place permuting of graph state, including boolean vector elements.

std::vector<bool> returns proxy objects when referencing individual
bits. To correctly swap bool elements using MSVC, we need to explicitly
apply std::vector<bool>::swap.

Making this change fixes osrm-contract on Windows.

We also correct failing tests and other undefined behaviours
(mainly iterator access outside boundaries) highlighted by MSVC.
This commit is contained in:
Michael Bell
2020-11-14 18:02:56 +00:00
parent 98fd17589d
commit 96acdaf0d5
13 changed files with 153 additions and 62 deletions
+15 -10
View File
@@ -36,7 +36,7 @@ template <typename BlockPolicy, storage::Ownership Ownership>
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const detail::IndexedDataImpl<BlockPolicy, Ownership> &index_data);
}
} // namespace serialization
template <int N, typename T = std::string> struct VariableGroupBlock
{
@@ -346,7 +346,7 @@ template <typename GroupBlockPolicy, storage::Ownership Ownership> struct Indexe
const GroupBlockPolicy block;
block.ReadRefrencedBlock(blocks[block_idx], internal_idx, first, last);
return adapt(&*first, &*last);
return adapt(first, last);
}
friend void serialization::read<GroupBlockPolicy, Ownership>(storage::tar::FileReader &reader,
@@ -359,30 +359,35 @@ template <typename GroupBlockPolicy, storage::Ownership Ownership> struct Indexe
const IndexedDataImpl &index_data);
private:
template <class T = ResultType>
template <typename Iter, typename T>
using IsValueIterator =
std::enable_if_t<std::is_same<T, typename std::iterator_traits<Iter>::value_type>::value>;
template <typename T = ResultType, typename Iter, typename = IsValueIterator<Iter, ValueType>>
typename std::enable_if<!std::is_same<T, StringView>::value, T>::type
adapt(const ValueType *first, const ValueType *last) const
adapt(const Iter first, const Iter last) const
{
return ResultType(first, last);
}
template <class T = ResultType>
template <typename T = ResultType, typename Iter, typename = IsValueIterator<Iter, ValueType>>
typename std::enable_if<std::is_same<T, StringView>::value, T>::type
adapt(const ValueType *first, const ValueType *last) const
adapt(const Iter first, const Iter last) const
{
return ResultType(first, std::distance(first, last));
auto diff = std::distance(first, last);
return diff == 0 ? ResultType() : ResultType(&*first, diff);
}
template <typename T> using Vector = util::ViewOrVector<T, Ownership>;
Vector<BlockReference> blocks;
Vector<ValueType> values;
};
}
} // namespace detail
template <typename GroupBlockPolicy>
using IndexedData = detail::IndexedDataImpl<GroupBlockPolicy, storage::Ownership::Container>;
template <typename GroupBlockPolicy>
using IndexedDataView = detail::IndexedDataImpl<GroupBlockPolicy, storage::Ownership::View>;
}
}
} // namespace util
} // namespace osrm
#endif // OSRM_INDEXED_DATA_HPP
+18 -7
View File
@@ -10,11 +10,22 @@ namespace osrm
namespace util
{
template <typename RandomAccesIterator, typename IndexT>
void inplacePermutation(RandomAccesIterator begin,
RandomAccesIterator end,
namespace permutation_detail
{
template <typename T> static inline void swap(T &a, T &b) { std::swap(a, b); }
static inline void swap(std::vector<bool>::reference a, std::vector<bool>::reference b)
{
std::vector<bool>::swap(a, b);
}
} // namespace permutation_detail
template <typename RandomAccessIterator, typename IndexT>
void inplacePermutation(RandomAccessIterator begin,
RandomAccessIterator end,
const std::vector<IndexT> &old_to_new)
{
std::size_t size = std::distance(begin, end);
BOOST_ASSERT(old_to_new.size() == size);
// we need a little bit auxililary space since we need to mark
@@ -40,10 +51,10 @@ void inplacePermutation(RandomAccesIterator begin,
for (; new_index != index; old_index = new_index, new_index = old_to_new[new_index])
{
was_replaced[old_index] = true;
std::swap(buffer, begin[new_index]);
permutation_detail::swap(buffer, begin[new_index]);
}
was_replaced[old_index] = true;
std::swap(buffer, begin[index]);
permutation_detail::swap(buffer, begin[index]);
}
}
@@ -56,7 +67,7 @@ std::vector<IndexT> orderingToPermutation(const std::vector<IndexT> &ordering)
return permutation;
}
}
}
} // namespace util
} // namespace osrm
#endif