Update LLVM from stable upstream (#1653)

Replace CheckedMalloc with upstream safe_malloc.
This commit is contained in:
Peter Johnson
2019-04-27 20:33:08 -07:00
committed by GitHub
parent 3cf4f38f5d
commit 2de3bf7f58
59 changed files with 4839 additions and 841 deletions

View File

@@ -21,6 +21,7 @@
#include "wpi/iterator.h"
#include "wpi/iterator_range.h"
#include "wpi/optional.h"
#include "wpi/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -52,6 +53,29 @@ using ValueOfRange = typename std::remove_reference<decltype(
} // end namespace detail
//===----------------------------------------------------------------------===//
// Extra additions to <type_traits>
//===----------------------------------------------------------------------===//
template <typename T>
struct negation : std::integral_constant<bool, !bool(T::value)> {};
template <typename...> struct conjunction : std::true_type {};
template <typename B1> struct conjunction<B1> : B1 {};
template <typename B1, typename... Bn>
struct conjunction<B1, Bn...>
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template <typename T> struct make_const_ptr {
using type =
typename std::add_pointer<typename std::add_const<T>::type>::type;
};
template <typename T> struct make_const_ref {
using type = typename std::add_lvalue_reference<
typename std::add_const<T>::type>::type;
};
//===----------------------------------------------------------------------===//
// Extra additions to <functional>
//===----------------------------------------------------------------------===//
@@ -176,6 +200,12 @@ void adl_swap(T &&lhs, T &&rhs) noexcept(
adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs));
}
/// Test whether \p RangeOrContainer is empty. Similar to C++17 std::empty.
template <typename T>
constexpr bool empty(const T &RangeOrContainer) {
return adl_begin(RangeOrContainer) == adl_end(RangeOrContainer);
}
// mapped_iterator - This is a simple iterator adapter that causes a function to
// be applied whenever operator* is invoked on the iterator.
@@ -403,6 +433,8 @@ make_filter_range(RangeT &&Range, PredicateT Pred) {
// forward declarations required by zip_shortest/zip_first
template <typename R, typename UnaryPredicate>
bool all_of(R &&range, UnaryPredicate P);
template <typename R, typename UnaryPredicate>
bool any_of(R &&range, UnaryPredicate P);
template <size_t... I> struct index_sequence;
@@ -553,6 +585,132 @@ detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
}
namespace detail {
template <typename Iter>
static Iter next_or_end(const Iter &I, const Iter &End) {
if (I == End)
return End;
return std::next(I);
}
template <typename Iter>
static auto deref_or_none(const Iter &I, const Iter &End)
-> wpi::optional<typename std::remove_const<
typename std::remove_reference<decltype(*I)>::type>::type> {
if (I == End)
return nullopt;
return *I;
}
template <typename Iter> struct ZipLongestItemType {
using type =
wpi::optional<typename std::remove_const<typename std::remove_reference<
decltype(*std::declval<Iter>())>::type>::type>;
};
template <typename... Iters> struct ZipLongestTupleType {
using type = std::tuple<typename ZipLongestItemType<Iters>::type...>;
};
template <typename... Iters>
class zip_longest_iterator
: public iterator_facade_base<
zip_longest_iterator<Iters...>,
typename std::common_type<
std::forward_iterator_tag,
typename std::iterator_traits<Iters>::iterator_category...>::type,
typename ZipLongestTupleType<Iters...>::type,
typename std::iterator_traits<typename std::tuple_element<
0, std::tuple<Iters...>>::type>::difference_type,
typename ZipLongestTupleType<Iters...>::type *,
typename ZipLongestTupleType<Iters...>::type> {
public:
using value_type = typename ZipLongestTupleType<Iters...>::type;
private:
std::tuple<Iters...> iterators;
std::tuple<Iters...> end_iterators;
template <size_t... Ns>
bool test(const zip_longest_iterator<Iters...> &other,
index_sequence<Ns...>) const {
return wpi::any_of(
std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
std::get<Ns>(other.iterators)...},
identity<bool>{});
}
template <size_t... Ns> value_type deref(index_sequence<Ns...>) const {
return value_type(
deref_or_none(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
}
template <size_t... Ns>
decltype(iterators) tup_inc(index_sequence<Ns...>) const {
return std::tuple<Iters...>(
next_or_end(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...);
}
public:
zip_longest_iterator(std::pair<Iters &&, Iters &&>... ts)
: iterators(std::forward<Iters>(ts.first)...),
end_iterators(std::forward<Iters>(ts.second)...) {}
value_type operator*() { return deref(index_sequence_for<Iters...>{}); }
value_type operator*() const { return deref(index_sequence_for<Iters...>{}); }
zip_longest_iterator<Iters...> &operator++() {
iterators = tup_inc(index_sequence_for<Iters...>{});
return *this;
}
bool operator==(const zip_longest_iterator<Iters...> &other) const {
return !test(other, index_sequence_for<Iters...>{});
}
};
template <typename... Args> class zip_longest_range {
public:
using iterator =
zip_longest_iterator<decltype(adl_begin(std::declval<Args>()))...>;
using iterator_category = typename iterator::iterator_category;
using value_type = typename iterator::value_type;
using difference_type = typename iterator::difference_type;
using pointer = typename iterator::pointer;
using reference = typename iterator::reference;
private:
std::tuple<Args...> ts;
template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const {
return iterator(std::make_pair(adl_begin(std::get<Ns>(ts)),
adl_end(std::get<Ns>(ts)))...);
}
template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const {
return iterator(std::make_pair(adl_end(std::get<Ns>(ts)),
adl_end(std::get<Ns>(ts)))...);
}
public:
zip_longest_range(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); }
iterator end() const { return end_impl(index_sequence_for<Args...>{}); }
};
} // namespace detail
/// Iterate over two or more iterators at the same time. Iteration continues
/// until all iterators reach the end. The wpi::optional only contains a value
/// if the iterator has not reached the end.
template <typename T, typename U, typename... Args>
detail::zip_longest_range<T, U, Args...> zip_longest(T &&t, U &&u,
Args &&... args) {
return detail::zip_longest_range<T, U, Args...>(
std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
}
/// Iterator wrapper that concatenates sequences together.
///
/// This can concatenate different iterators, even with different types, into
@@ -575,18 +733,20 @@ class concat_iterator
/// Note that something like iterator_range seems nice at first here, but the
/// range properties are of little benefit and end up getting in the way
/// because we need to do mutation on the current iterators.
std::tuple<std::pair<IterTs, IterTs>...> IterPairs;
std::tuple<IterTs...> Begins;
std::tuple<IterTs...> Ends;
/// Attempts to increment a specific iterator.
///
/// Returns true if it was able to increment the iterator. Returns false if
/// the iterator is already at the end iterator.
template <size_t Index> bool incrementHelper() {
auto &IterPair = std::get<Index>(IterPairs);
if (IterPair.first == IterPair.second)
auto &Begin = std::get<Index>(Begins);
auto &End = std::get<Index>(Ends);
if (Begin == End)
return false;
++IterPair.first;
++Begin;
return true;
}
@@ -610,11 +770,12 @@ class concat_iterator
/// dereferences the iterator and returns the address of the resulting
/// reference.
template <size_t Index> ValueT *getHelper() const {
auto &IterPair = std::get<Index>(IterPairs);
if (IterPair.first == IterPair.second)
auto &Begin = std::get<Index>(Begins);
auto &End = std::get<Index>(Ends);
if (Begin == End)
return nullptr;
return &*IterPair.first;
return &*Begin;
}
/// Finds the first non-end iterator, dereferences, and returns the resulting
@@ -641,7 +802,7 @@ public:
/// iterators.
template <typename... RangeTs>
explicit concat_iterator(RangeTs &&... Ranges)
: IterPairs({std::begin(Ranges), std::end(Ranges)}...) {}
: Begins(std::begin(Ranges)...), Ends(std::end(Ranges)...) {}
using BaseT::operator++;
@@ -653,7 +814,7 @@ public:
ValueT &operator*() const { return get(index_sequence_for<IterTs...>()); }
bool operator==(const concat_iterator &RHS) const {
return IterPairs == RHS.IterPairs;
return Begins == RHS.Begins && Ends == RHS.Ends;
}
};
@@ -722,6 +883,19 @@ struct less_second {
}
};
/// \brief Function object to apply a binary function to the first component of
/// a std::pair.
template<typename FuncTy>
struct on_first {
FuncTy func;
template <typename T>
auto operator()(const T &lhs, const T &rhs) const
-> decltype(func(lhs.first, rhs.first)) {
return func(lhs.first, rhs.first);
}
};
// A subset of N3658. More stuff can be added as-needed.
/// Represents a compile-time sequence of integers.
@@ -862,6 +1036,18 @@ void DeleteContainerSeconds(Container &C) {
C.clear();
}
/// Get the size of a range. This is a wrapper function around std::distance
/// which is only enabled when the operation is O(1).
template <typename R>
auto size(R &&Range, typename std::enable_if<
std::is_same<typename std::iterator_traits<decltype(
Range.begin())>::iterator_category,
std::random_access_iterator_tag>::value,
void>::type * = nullptr)
-> decltype(std::distance(Range.begin(), Range.end())) {
return std::distance(Range.begin(), Range.end());
}
/// Provide wrappers to std::for_each which take ranges instead of having to
/// pass begin/end explicitly.
template <typename R, typename UnaryPredicate>
@@ -972,6 +1158,33 @@ auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
return std::lower_bound(adl_begin(Range), adl_end(Range), I);
}
template <typename R, typename ForwardIt, typename Compare>
auto lower_bound(R &&Range, ForwardIt I, Compare C)
-> decltype(adl_begin(Range)) {
return std::lower_bound(adl_begin(Range), adl_end(Range), I, C);
}
/// Provide wrappers to std::upper_bound which take ranges instead of having to
/// pass begin/end explicitly.
template <typename R, typename ForwardIt>
auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
return std::upper_bound(adl_begin(Range), adl_end(Range), I);
}
template <typename R, typename ForwardIt, typename Compare>
auto upper_bound(R &&Range, ForwardIt I, Compare C)
-> decltype(adl_begin(Range)) {
return std::upper_bound(adl_begin(Range), adl_end(Range), I, C);
}
/// Wrapper function around std::equal to detect if all elements
/// in a container are same.
template <typename R>
bool is_splat(R &&Range) {
size_t range_size = size(Range);
return range_size != 0 && (range_size == 1 ||
std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range)));
}
/// Given a range of type R, iterate the entire range and return a
/// SmallVector with elements of the vector. This is useful, for example,
/// when you want to iterate a range and then sort the results.
@@ -993,18 +1206,6 @@ void erase_if(Container &C, UnaryPredicate P) {
C.erase(remove_if(C, P), C.end());
}
/// Get the size of a range. This is a wrapper function around std::distance
/// which is only enabled when the operation is O(1).
template <typename R>
auto size(R &&Range, typename std::enable_if<
std::is_same<typename std::iterator_traits<decltype(
Range.begin())>::iterator_category,
std::random_access_iterator_tag>::value,
void>::type * = nullptr)
-> decltype(std::distance(Range.begin(), Range.end())) {
return std::distance(Range.begin(), Range.end());
}
//===----------------------------------------------------------------------===//
// Extra additions to <memory>
//===----------------------------------------------------------------------===//
@@ -1217,6 +1418,40 @@ auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
Indices{});
}
/// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
/// time. Not meant for use with random-access iterators.
template <typename IterTy>
bool hasNItems(
IterTy &&Begin, IterTy &&End, unsigned N,
typename std::enable_if<
!std::is_same<
typename std::iterator_traits<typename std::remove_reference<
decltype(Begin)>::type>::iterator_category,
std::random_access_iterator_tag>::value,
void>::type * = nullptr) {
for (; N; --N, ++Begin)
if (Begin == End)
return false; // Too few.
return Begin == End;
}
/// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
/// time. Not meant for use with random-access iterators.
template <typename IterTy>
bool hasNItemsOrMore(
IterTy &&Begin, IterTy &&End, unsigned N,
typename std::enable_if<
!std::is_same<
typename std::iterator_traits<typename std::remove_reference<
decltype(Begin)>::type>::iterator_category,
std::random_access_iterator_tag>::value,
void>::type * = nullptr) {
for (; N; --N, ++Begin)
if (Begin == End)
return false; // Too few.
return true;
}
} // end namespace wpi
#endif // LLVM_ADT_STLEXTRAS_H