Changes For Bug 352
[oota-llvm.git] / include / llvm / ADT / STLExtras.h
index 0168bf2624475ae5d50f24b14f57d21087fb7ffe..14b61bc916c33574a105ac63823f170f60cfd708 100644 (file)
@@ -1,4 +1,11 @@
-//===-- STLExtras.h - Useful functions when working with the STL -*- C++ -*--=//
+//===- 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.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_SUPPORT_STL_EXTRAS_H
-#define LLVM_SUPPORT_STL_EXTRAS_H
+#ifndef LLVM_ADT_STLEXTRAS_H
+#define LLVM_ADT_STLEXTRAS_H
 
 #include <functional>
+#include <utility> // for std::pair
+#include "llvm/ADT/iterator"
+
+namespace llvm {
 
 //===----------------------------------------------------------------------===//
 //     Extra additions to <functional>
@@ -42,11 +53,24 @@ struct bitwise_or : public std::binary_function<Ty, Ty, bool> {
   }
 };
 
+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;
+  }
+};
 
 // 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<cfg::Interval>);
+//   for_each(V.begin(), B.end(), deleter<Interval>);
 //
 template <class T> 
 static inline void deleter(T *Ptr) { 
@@ -62,9 +86,6 @@ static inline void deleter(T *Ptr) {
 // mapped_iterator - This is a simple iterator adapter that causes a function to
 // be dereferenced whenever operator* is invoked on the iterator.
 //
-// It turns out that this is disturbingly similar to boost::transform_iterator
-//
-#if 1
 template <class RootIt, class UnaryFunc>
 class mapped_iterator {
   RootIt current;
@@ -75,7 +96,9 @@ public:
   typedef typename std::iterator_traits<RootIt>::difference_type
           difference_type;
   typedef typename UnaryFunc::result_type value_type;
-  typedef typename UnaryFunc::result_type *pointer;
+
+  typedef void pointer;
+  //typedef typename UnaryFunc::result_type *pointer;
   typedef void reference;        // Can't modify value returned by fn
 
   typedef RootIt iterator_type;
@@ -118,28 +141,6 @@ operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
   return mapped_iterator<_Iterator, Func>(X.getCurrent() - N);
 }
 
-#else
-
-// This fails to work, because some iterators are not classes, for example
-// vector iterators are commonly value_type **'s
-template <class RootIt, class UnaryFunc>
-class mapped_iterator : public RootIt {
-  UnaryFunc Fn;
-public:
-  typedef typename UnaryFunc::result_type value_type;
-  typedef typename UnaryFunc::result_type *pointer;
-  typedef void reference;        // Can't modify value returned by fn
-
-  typedef mapped_iterator<RootIt, UnaryFunc> _Self;
-  typedef RootIt super;
-  inline explicit mapped_iterator(const RootIt &I) : super(I) {}
-  inline mapped_iterator(const super &It) : super(It) {}
-
-  inline value_type operator*() const {     // All this work to do 
-    return Fn(super::operator*());   // this little thing
-  }
-};
-#endif
 
 // map_iterator - Provide a convenient way to create mapped_iterators, just like
 // make_pair is useful for creating pairs...
@@ -150,6 +151,43 @@ inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy 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 <algorithm>
 //===----------------------------------------------------------------------===//
@@ -220,4 +258,53 @@ template <class InIt, class OutIt, class Functor>
 inline OutIt mapto(InIt Begin, InIt End, OutIt Dest, Functor F) {
   return copy(map_iterator(Begin, F), map_iterator(End, F), Dest);
 }
+
+
+//===----------------------------------------------------------------------===//
+//     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);
+}
+
+} // End llvm namespace
+
 #endif