#ifndef LLVM_ADT_STLEXTRAS_H
#define LLVM_ADT_STLEXTRAS_H
#include <cstddef> // for std::size_t
#include <cstdlib> // for qsort
#include <functional>
#include <iterator>
#include <utility> // for std::pair
namespace llvm {
template<class Ty>
struct less_ptr : public std::binary_function<Ty, Ty, bool> {
bool operator()(const Ty* left, const Ty* right) const {
return *left < *right;
}
};
template<class Ty>
struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
bool operator()(const Ty* left, const Ty* right) const {
return *right < *left;
}
};
template <class T>
static inline void deleter(T *Ptr) {
delete Ptr;
}
template <class RootIt, class UnaryFunc>
class mapped_iterator {
RootIt current;
UnaryFunc Fn;
public:
typedef typename std::iterator_traits<RootIt>::iterator_category
iterator_category;
typedef typename std::iterator_traits<RootIt>::difference_type
difference_type;
typedef typename UnaryFunc::result_type value_type;
typedef void pointer;
typedef void reference;
typedef RootIt iterator_type;
typedef mapped_iterator<RootIt, UnaryFunc> _Self;
inline const RootIt &getCurrent() const { return current; }
inline const UnaryFunc &getFunc() const { return Fn; }
inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
: current(I), Fn(F) {}
inline mapped_iterator(const mapped_iterator &It)
: current(It.current), Fn(It.Fn) {}
inline value_type operator*() const { return Fn(*current); }
_Self& operator++() { ++current; return *this; }
_Self& operator--() { --current; return *this; }
_Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
_Self operator--(int) { _Self __tmp = *this; --current; return __tmp; }
_Self operator+ (difference_type n) const {
return _Self(current + n, Fn);
}
_Self& operator+= (difference_type n) { current += n; return *this; }
_Self operator- (difference_type n) const {
return _Self(current - n, Fn);
}
_Self& operator-= (difference_type n) { current -= n; return *this; }
reference operator[](difference_type n) const { return *(*this + n); }
inline bool operator!=(const _Self &X) const { return !operator==(X); }
inline bool operator==(const _Self &X) const { return current == X.current; }
inline bool operator< (const _Self &X) const { return current < X.current; }
inline difference_type operator-(const _Self &X) const {
return current - X.current;
}
};
template <class _Iterator, class Func>
inline mapped_iterator<_Iterator, Func>
operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
const mapped_iterator<_Iterator, Func>& X) {
return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc());
}
template <class ItTy, class FuncTy>
inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
return mapped_iterator<ItTy, FuncTy>(I, F);
}
template <typename ItTy, typename Dist>
inline ItTy next(ItTy it, Dist n)
{
std::advance(it, n);
return it;
}
template <typename ItTy>
inline ItTy next(ItTy it)
{
return ++it;
}
template <typename ItTy, typename Dist>
inline ItTy prior(ItTy it, Dist n)
{
std::advance(it, -n);
return it;
}
template <typename ItTy>
inline ItTy prior(ItTy it)
{
return --it;
}
namespace
{
template <typename T1, typename T2>
struct tier {
typedef T1 &first_type;
typedef T2 &second_type;
first_type first;
second_type second;
tier(first_type f, second_type s) : first(f), second(s) { }
tier& operator=(const std::pair<T1, T2>& p) {
first = p.first;
second = p.second;
return *this;
}
};
}
template <typename T1, typename T2>
inline tier<T1, T2> tie(T1& f, T2& s) {
return tier<T1, T2>(f, s);
}
template<class T, std::size_t N>
inline T *array_endof(T (&x)[N]) {
return x+N;
}
template<class T, std::size_t N>
inline size_t array_lengthof(T (&)[N]) {
return N;
}
template<typename T>
static inline int array_pod_sort_comparator(const void *P1, const void *P2) {
if (*reinterpret_cast<const T*>(P1) < *reinterpret_cast<const T*>(P2))
return -1;
if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1))
return 1;
return 0;
}
template<typename T>
static int (*get_array_pad_sort_comparator(const T &))
(const void*, const void*) {
return array_pod_sort_comparator<T>;
}
template<class IteratorTy>
static inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start),
get_array_pad_sort_comparator(*Start));
}
template<class IteratorTy>
static inline void array_pod_sort(IteratorTy Start, IteratorTy End,
int (*Compare)(const void*, const void*)) {
if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start), Compare);
}
template<typename Container>
void DeleteContainerPointers(Container &C) {
for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
delete *I;
C.clear();
}
template<typename Container>
void DeleteContainerSeconds(Container &C) {
for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
delete I->second;
C.clear();
}
}
#endif