[cfe-commits] [patch] TransformIterator (motivating use case in Clang)
Douglas Gregor
dgregor at apple.com
Tue May 15 09:19:10 PDT 2012
On May 6, 2012, at 7:02 PM, David Blaikie wrote:
> This patch adds an iterator much like boost's transform_iterator
> (without some extra bells & whistles) for use in some changes I'd like
> to make to Clang to correct some misimplemented iterators there.
>
> A few gotchas that could be improved/changed depending on opinions:
> * I may be playing a little loose with the return type of the functor
> (see the example/motivating functor, to_pointer) - the return type
> actually must be a reference, though the result_type provides the
> underlying value type, not the reference type. If this is violated
> Clang will emit a warning, but I could make it more robust with a
> compile time assertion in the TransformIterator that the result_type
> is actually a reference type, and strip that off to provide the
> value_type of the TransformIterator.
It's much more correct for the value and reference types of the iterator type to be, e.g.,
typedef typename Functor::result_type reference;
typedef typename remove_reference<reference>::type value_type;
> * I realize adding pointer-yness back onto an iterator over references
> when the underlying data structure (in the Clang patch you can see
> this situation) is a sequence of pointers may be a bit overkill -
> though the alternatives are writing different algorithms in the two
> cases where I've used TransformIterator, or having the decl_iterator
> iterate over pointers (in which case I should probably change the
> other iterators I've modified to iterate over pointers for symmetry).
diff --git include/clang/AST/DeclBase.h include/clang/AST/DeclBase.h
index 6aef681..0a16ea5 100644
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -1175,17 +1175,18 @@ public:
Decl *Current;
public:
- typedef Decl* value_type;
- typedef Decl* reference;
- typedef Decl* pointer;
+ typedef Decl value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
Since we tend to traffic in declaration pointers, not references, it's really beneficial to have value_type be Decl*. Of course, it's fine for the reference type to be Decl* as well.
> At some point I'll also be looking to add a FilterIterator (& possibly
> a specific Filtering+Transforming iterator, as I'm not sure the
> composition of the two independently will be great for the use case I
> have in mind) as well since that's one of the motivation for tidying
> up these iterators - to pull out the common functionality in the
> specific/filtered_iterators in DeclContext.
+//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===/
Header needs updating.
+ pointer operator->() const {
+ return m_func(*m_iter);
+ }
This isn't going to work; m_func returns a value_type or reference. Dealing with -> is a real pain, because in the general case you need a proxy class.
+// a convenient utility for a common adaptation
+template<typename T>
+struct to_pointer {
+ typedef T * result_type;
+ typedef T argument_type;
+ result_type &operator()(T &t) const {
+ ptr = &t;
+ return ptr;
+ }
+private:
+ mutable T *ptr;
+};
'to_pointer' is a very non-LLVM-y name.
More generally, this particular function object seems like a bad idea. There's nothing wrong with having an iterator type whose reference type is not a true reference, which means that there is no reason to do this little dance with the mutable 'ptr'.
- Doug
More information about the cfe-commits
mailing list