llvm.org GIT mirror llvm / release_21 include / llvm / ADT / STLExtras.h
release_21

Tree @release_21 (Download .tar.gz)

STLExtras.h @release_21

551ccae
9769ab2
b2109ce
 
 
 
9769ab2
b2109ce
18d64ed
 
 
 
 
 
 
 
551ccae
 
18d64ed
 
9bb2188
718cb66
551ccae
18d64ed
d0fde30
 
18d64ed
42e018c
 
 
7b32639
 
 
 
 
 
 
577b15f
9769ab2
577b15f
8765096
577b15f
9769ab2
 
 
577b15f
 
 
 
42e018c
18d64ed
 
 
 
 
 
 
 
 
643afb3
18d64ed
697954c
18d64ed
697954c
18d64ed
 
d063725
 
 
18d64ed
 
 
 
 
8249328
18d64ed
643afb3
 
 
 
18d64ed
9769ab2
643afb3
18d64ed
 
 
 
 
 
 
 
 
 
9769ab2
18d64ed
697954c
18d64ed
 
 
 
 
 
 
 
 
9769ab2
18d64ed
 
 
 
 
 
 
 
 
 
 
643afb3
18d64ed
 
 
bc79471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e292da2
 
 
 
 
 
 
 
 
 
9769ab2
e292da2
 
 
 
 
 
 
 
 
 
 
 
 
 
a3f5f80
 
e292da2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718cb66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0fde30
 
18d64ed
//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains some templates that are useful if you are working with the
// STL at all.
//
// No library is required when using these functinons.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ADT_STLEXTRAS_H
#define LLVM_ADT_STLEXTRAS_H

#include <functional>
#include <utility> // for std::pair
#include <cstring> // for std::size_t
#include "llvm/ADT/iterator"

namespace llvm {

//===----------------------------------------------------------------------===//
//     Extra additions to <functional>
//===----------------------------------------------------------------------===//

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;
  }
};

// deleter - Very very very simple method that is used to invoke operator
// delete on something.  It is used like this:
//
//   for_each(V.begin(), B.end(), deleter<Interval>);
//
template <class T>
static inline void deleter(T *Ptr) {
  delete Ptr;
}



//===----------------------------------------------------------------------===//
//     Extra additions to <iterator>
//===----------------------------------------------------------------------===//

// mapped_iterator - This is a simple iterator adapter that causes a function to
// be dereferenced whenever operator* is invoked on the iterator.
//
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 typename UnaryFunc::result_type *pointer;
  typedef void reference;        // Can't modify value returned by fn

  typedef RootIt iterator_type;
  typedef mapped_iterator<RootIt, UnaryFunc> _Self;

  inline const RootIt &getCurrent() const { return current; }

  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 {   // All this work to do this
    return Fn(*current);         // little change
  }

  _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); }
  _Self& operator+=   (difference_type n) { current += n; return *this; }
  _Self  operator-    (difference_type n) const { return _Self(current - n); }
  _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);
}


// map_iterator - Provide a convenient way to create mapped_iterators, just like
// make_pair is useful for creating pairs...
//
template <class ItTy, class FuncTy>
inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
  return mapped_iterator<ItTy, FuncTy>(I, F);
}


// next/prior - These functions unlike std::advance do not modify the
// passed iterator but return a copy.
//
// next(myIt) returns copy of myIt incremented once
// next(myIt, n) returns copy of myIt incremented n times
// prior(myIt) returns copy of myIt decremented once
// prior(myIt, n) returns copy of myIt decremented n times

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)
{
  std::advance(it, 1);
  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)
{
  std::advance(it, -1);
  return it;
}

//===----------------------------------------------------------------------===//
//     Extra additions to <utility>
//===----------------------------------------------------------------------===//

// tie - this function ties two objects and returns a temporary object
// that is assignable from a std::pair. This can be used to make code
// more readable when using values returned from functions bundled in
// a std::pair. Since an example is worth 1000 words:
//
// typedef std::map<int, int> Int2IntMap;
//
// Int2IntMap myMap;
// Int2IntMap::iterator where;
// bool inserted;
// tie(where, inserted) = myMap.insert(std::make_pair(123,456));
//
// if (inserted)
//   // do stuff
// else
//   // do other stuff

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);
}

//===----------------------------------------------------------------------===//
//     Extra additions to arrays
//===----------------------------------------------------------------------===//

/// Find where an array ends (for ending iterators)
/// This returns a pointer to the byte immediately
/// after the end of an array.
template<class T, std::size_t N>
inline T *array_endof(T (&x)[N]) {
  return x+N;
}

/// Find the length of an array.
template<class T, std::size_t N>
inline size_t array_lengthof(T (&x)[N]) {
  return N;
}

} // End llvm namespace

#endif