[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Toon-members] tag/tag fn.h
From: |
Gerhard Reitmayr |
Subject: |
[Toon-members] tag/tag fn.h |
Date: |
Wed, 19 Jul 2006 16:20:48 +0000 |
CVSROOT: /cvsroot/toon
Module name: tag
Changes by: Gerhard Reitmayr <gerhard> 06/07/19 16:20:48
Modified files:
tag : fn.h
Log message:
fixed member_iterator_t to work correct with constness and make it much
cleaner
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/tag/tag/fn.h?cvsroot=toon&r1=1.1&r2=1.2
Patches:
Index: fn.h
===================================================================
RCS file: /cvsroot/toon/tag/tag/fn.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- fn.h 19 Jun 2006 10:55:07 -0000 1.1
+++ fn.h 19 Jul 2006 16:20:48 -0000 1.2
@@ -89,6 +89,53 @@
///@ingroup stdpp
//@{
+namespace Internal {
+
+template <class T> struct make_const {
+ typedef const T type;
+};
+
+template <class T> struct make_const<T&> {
+ typedef const T & type;
+};
+
+template <class A, class B>
+struct forward_const {
+ typedef B value_type;
+ enum { CONST = 0 };
+};
+
+template <class A, class B>
+struct forward_const<const A, B> {
+ typedef typename make_const<B>::type value_type;
+ enum { CONST = 1 };
+};
+
+template <class A, class B>
+struct forward_const<A&, B> {
+ typedef B value_type;
+ enum { CONST = 2 };
+};
+
+template <class A, class B>
+struct forward_const<const A&, B> {
+ typedef typename make_const<B>::type value_type;
+ enum { CONST = 3 };
+};
+
+template <class A, class B>
+struct forward_const<A *, B> {
+ typedef B value_type;
+ enum { CONST = 4 };
+};
+
+template <class A, class B>
+struct forward_const<const A *, B> {
+ typedef typename make_const<B>::type value_type;
+ enum { CONST = 5 };
+};
+
+}
/**
An iterator wrapper that returns a member of a struct the wrapped iterator
would point to.
@@ -101,31 +148,88 @@
@endcode
*/
template <typename It, typename m>
-struct member_iterator_t : public It {
- typedef typename std::iterator_traits<It>::value_type Value;
- m Value::*data;
- inline member_iterator_t( m Value::*d ) : data(d) {};
- inline member_iterator_t( const It & it, m Value::*d ) : data(d) { *this
= it; };
+struct member_iterator_t {
+
+ typedef typename It::value_type ParentValue;
+
+ // iterator defines
+ typedef typename It::iterator_category iterator_category;
+ typedef m value_type;
+ typedef typename It::difference_type difference_type;
+ typedef typename Internal::forward_const<typename It::pointer, m
*>::value_type pointer;
+ typedef typename Internal::forward_const<typename It::reference, m
&>::value_type reference;
+
+ It iterator;
+ m ParentValue::*data;
+
+ inline member_iterator_t( m ParentValue::*d ) : data(d) {};
+ inline member_iterator_t( const It & it, m ParentValue::*d ) : data(d) {
iterator = it; };
+
template <typename Other> inline member_iterator_t & operator=(const Other
& other) {
- It::operator=(other);
+ iterator = other;
return *this;
}
inline member_iterator_t & operator=( const member_iterator_t & other){
data = other.data;
- It::operator=(other);
+ iterator = other.iterator;
return *this;
}
- inline m & operator*(void){
- return It::operator*().*data;
+
+ inline member_iterator_t::reference operator*(void) const {
+ return (*iterator).*data;
+ }
+ inline member_iterator_t::reference operator->(void) const {
+ return iterator->*data;
}
- inline m & operator->(void){
- return It::operator->()->*data;
+ inline member_iterator_t::reference operator[](difference_type n) const {
+ return iterator[n].*data;
}
- inline const m & operator*(void) const {
- return It::operator*().*data;
+ inline member_iterator_t & operator++() {
+ ++iterator;
+ return *this;
+ }
+ inline member_iterator_t operator++(int) {
+ member_iterator_t tmp(*this);
+ iterator++;
+ return tmp;
}
- inline const m & operator->(void) const {
- return It::operator->()->*data;
+ inline member_iterator_t & operator--() {
+ --iterator;
+ return *this;
+ }
+ inline member_iterator_t operator--(int) {
+ member_iterator_t tmp(*this);
+ iterator--;
+ return tmp;
+ }
+ inline member_iterator_t & operator+=(difference_type n){
+ iterator+=n;
+ return *this;
+ }
+ inline member_iterator_t & operator-=(difference_type n){
+ iterator-=n;
+ return *this;
+ }
+ template <typename Other>
+ inline difference_type operator-(const Other & other) const {
+ return (iterator - other);
+ }
+ inline difference_type operator-(const member_iterator_t & other) const {
+ return (iterator - other.iterator);
+ }
+ template <typename Other>
+ inline bool operator==(const Other & other) const {
+ return (iterator == other);
+ }
+ inline bool operator==(const member_iterator_t & other) const {
+ return (iterator == other.iterator);
+ }
+ template <typename Other>
+ inline bool operator!=(const Other & other) const {
+ return (iterator != other);
+ }
+ inline bool operator!=(const member_iterator_t & other) const {
+ return (iterator != other.iterator);
}
};
@@ -134,9 +238,14 @@
member iterators as arguments.
@arg it the iterator to wrap, the new member_iterator_t returned will point to
the same position
@arg d the member to wrap
address@hidden
+struct simple { int a; float b; };
+vector<simple> test;
+for_each(member_iterator(test.begin(), &simple::a),
member_iterator(test.end(), &simple::a), ... );
address@hidden
*/
template <typename It, typename m>
-inline struct member_iterator_t<It, m> member_iterator( const It & it, m
std::iterator_traits<It>::value_type::*d ){
+inline struct member_iterator_t<It, m> member_iterator( const It & it, m
It::value_type::*d ){
return member_iterator_t<It, m>(it, d);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Toon-members] tag/tag fn.h,
Gerhard Reitmayr <=