From 18d64ede9a4aee9dd66fde04e6ff8ffcae0c9925 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 21 Jun 2001 05:25:51 +0000 Subject: [PATCH] New header file defined with neeto utilities put in one place git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Tools/STLExtras.h | 163 +++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 include/llvm/Tools/STLExtras.h diff --git a/include/llvm/Tools/STLExtras.h b/include/llvm/Tools/STLExtras.h new file mode 100644 index 00000000000..525f6a014b6 --- /dev/null +++ b/include/llvm/Tools/STLExtras.h @@ -0,0 +1,163 @@ +//===-- STLExtras.h - Useful functions when working with the STL --*- C++ -*--=// +// +// 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_TOOLS_STL_EXTRAS_H +#define LLVM_TOOLS_STL_EXTRAS_H + +#include + +//===----------------------------------------------------------------------===// +// Extra additions to +//===----------------------------------------------------------------------===// + +// 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 mapped_iterator { + RootIt current; +public: + typedef typename iterator_traits::iterator_category + iterator_category; + typedef typename iterator_traits::difference_type + difference_type; + typedef typename UnaryFunc::result_type value_type; + typedef typename UnaryFunc::result_type *pointer; + typedef void reference; // Can't modify value returned by fn + + typedef RootIt iterator_type; + typedef mapped_iterator _Self; + + inline RootIt &getCurrent() const { return current; } + + inline explicit mapped_iterator(const RootIt &I) : current(I) {} + inline mapped_iterator(const mapped_iterator &It) : current(It.current) {} + + inline value_type operator*() const { // All this work to do this + return UnaryFunc()(*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 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 +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); +} + +#else + +// This fails to work, because some iterators are not classes, for example +// vector iterators are commonly value_type **'s +template +class mapped_iterator : public RootIt { +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 _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 UnaryFunc(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... +// +template +inline mapped_iterator map_iterator(const ItTy &I, FuncTy F) { + return mapped_iterator(I); +} + + + +//===----------------------------------------------------------------------===// +// Extra additions to +//===----------------------------------------------------------------------===// + +// reduce - Reduce a sequence values into a single value, given an initial +// value and an operator. +// +template +ValueType reduce(InputIt First, InputIt Last, Function Func, ValueType Value) { + for ( ; First != Last; ++First) + Value = Func(*First, Value); + return Value; +} + +#if 1 // This is likely to be more efficient + +// reduce_apply - Reduce the result of applying a function to each value in a +// sequence, given an initial value, an operator, a function, and a sequence. +// +template +ValueType reduce_apply(InputIt First, InputIt Last, Function Func, + ValueType Value, TransFunc XForm) { + for ( ; First != Last; ++First) + Value = Func(XForm(*First), Value); + return Value; +} + +#else // This is arguably more elegant + +// reduce_apply - Reduce the result of applying a function to each value in a +// sequence, given an initial value, an operator, a function, and a sequence. +// +template +ValueType reduce_apply2(InputIt First, InputIt Last, Function Func, + ValueType Value, TransFunc XForm) { + return reduce(map_iterator(First, XForm), + map_iterator(Last, XForm), + Func, Value); +} +#endif + + + +//===----------------------------------------------------------------------===// +// Extra additions to +//===----------------------------------------------------------------------===// + +// bitwise_or - This is a simple functor that applys operator| on its two +// arguments to get a boolean result. +// +template +struct bitwise_or : public binary_function { + bool operator()(const Ty& left, const Ty& right) const { + return left | right; + } +}; + +#endif