//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_ADT_SMALLVECTOR_H
#define LLVM_ADT_SMALLVECTOR_H
+#include "llvm/ADT/iterator"
#include <algorithm>
-#include <iterator>
#include <memory>
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+ // Work around flawed VC++ implementation of std::uninitialized_copy. Define
+ // additional overloads so that elements with pointer types are recognized as
+ // scalars and not objects, causing bizarre type conversion errors.
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+#else
+// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
+// is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
namespace llvm {
/// SmallVectorImpl - This class consists of common code factored out of the
public:
// Default ctor - Initialize to empty.
SmallVectorImpl(unsigned N)
- : Begin((T*)&FirstEl), End((T*)&FirstEl), Capacity((T*)&FirstEl+N) {
+ : Begin(reinterpret_cast<T*>(&FirstEl)),
+ End(reinterpret_cast<T*>(&FirstEl)),
+ Capacity(reinterpret_cast<T*>(&FirstEl)+N) {
}
~SmallVectorImpl() {
// If this wasn't grown from the inline copy, deallocate the old space.
if (!isSmall())
- delete[] (char*)Begin;
+ delete[] reinterpret_cast<char*>(Begin);
}
typedef size_t size_type;
typedef T* iterator;
typedef const T* const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
typedef T& reference;
typedef const T& const_reference;
bool empty() const { return Begin == End; }
size_type size() const { return End-Begin; }
-
+
+ // forward iterator creation methods.
iterator begin() { return Begin; }
const_iterator begin() const { return Begin; }
-
iterator end() { return End; }
const_iterator end() const { return End; }
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
reference operator[](unsigned idx) {
return Begin[idx];
}
destroy_range(Begin+N, End);
End = Begin+N;
} else if (N > size()) {
- if (Begin+N > Capacity)
+ if (unsigned(Capacity-Begin) < N)
grow(N);
construct_range(End, Begin+N, T());
End = Begin+N;
destroy_range(Begin+N, End);
End = Begin+N;
} else if (N > size()) {
- if (Begin+N > Capacity)
+ if (unsigned(Capacity-Begin) < N)
grow(N);
construct_range(End, Begin+N, NV);
End = Begin+N;
void assign(unsigned NumElts, const T &Elt) {
clear();
- if (Begin+NumElts > Capacity)
+ if (unsigned(Capacity-Begin) < NumElts)
grow(NumElts);
End = Begin+NumElts;
construct_range(Begin, End, Elt);
const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
+ bool operator==(const SmallVectorImpl &RHS) const {
+ if (size() != RHS.size()) return false;
+ for (T *This = Begin, *That = RHS.Begin, *End = Begin+size();
+ This != End; ++This, ++That)
+ if (*This != *That)
+ return false;
+ return true;
+ }
+ bool operator!=(const SmallVectorImpl &RHS) const { return !(*this == RHS); }
+
private:
/// isSmall - Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
bool isSmall() const {
- return (void*)Begin == (void*)&FirstEl;
+ return reinterpret_cast<const void*>(Begin) ==
+ reinterpret_cast<const void*>(&FirstEl);
}
/// grow - double the size of the allocated memory, guaranteeing space for at
void destroy_range(T *S, T *E) {
while (S != E) {
- E->~T();
--E;
+ E->~T();
}
}
};
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template <typename T>
void SmallVectorImpl<T>::grow(unsigned MinSize) {
- unsigned CurCapacity = Capacity-Begin;
- unsigned CurSize = size();
+ unsigned CurCapacity = unsigned(Capacity-Begin);
+ unsigned CurSize = unsigned(size());
unsigned NewCapacity = 2*CurCapacity;
if (NewCapacity < MinSize)
NewCapacity = MinSize;
// If this wasn't grown from the inline copy, deallocate the old space.
if (!isSmall())
- delete[] (char*)Begin;
+ delete[] reinterpret_cast<char*>(Begin);
Begin = NewElts;
End = NewElts+CurSize;
// If we already have sufficient space, assign the common elements, then
// destroy any excess.
- unsigned RHSSize = RHS.size();
- unsigned CurSize = size();
+ unsigned RHSSize = unsigned(RHS.size());
+ unsigned CurSize = unsigned(size());
if (CurSize >= RHSSize) {
// Assign common elements.
- iterator NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+ iterator NewEnd;
+ if (RHSSize)
+ NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+ else
+ NewEnd = Begin;
// Destroy excess elements.
destroy_range(NewEnd, End);
SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
}
+ explicit SmallVector(unsigned Size, const T &Value = T())
+ : SmallVectorImpl<T>(NumTsAvailable) {
+ this->reserve(Size);
+ while (Size--)
+ push_back(Value);
+ }
+
template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
append(S, E);
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
- operator=(RHS);
+ if (!RHS.empty())
+ operator=(RHS);
}
const SmallVector &operator=(const SmallVector &RHS) {