TooN Algorithm Library - tag  0.2
fn.h
Go to the documentation of this file.
1 #ifndef TAG_FN_H
2 #define TAG_FN_H
3 
4 #include <functional>
5 #include <iterator>
6 
7 namespace std {
11 template <class Arg1, class Arg2, class Result>
12 struct binary_function<Arg1, Arg2&, Result> {
13  typedef Arg1 first_argument_type;
14  typedef Arg2 second_argument_type;
15  typedef Result result_type;
16 };
17 }
18 
19 namespace tag {
20 
24 
25 
26 template <typename A, typename m>
27 struct mem_data_ref_t : std::unary_function<A &, m &> {
28  m A::*data;
29  inline mem_data_ref_t( m A::*d ) : data(d) {};
30  inline m & operator()(A & instance) const {
31  return instance.*data;
32  }
33 };
34 
35 template <typename A, typename m>
36 struct const_mem_data_ref_t : std::unary_function<const A &, const m &> {
37  const m A::*data;
38  inline const_mem_data_ref_t( const m A::*d ) : data(d) {};
39  inline const m & operator()(const A & instance) const {
40  return instance.*data;
41  }
42 };
43 
44 template <typename A, typename m>
45 inline struct mem_data_ref_t<A,m> mem_data_ref( m A::*data ){
46  return mem_data_ref_t<A,m>(data);
47 }
48 
49 template <typename A, typename m>
50 inline struct const_mem_data_ref_t<A,m> const_mem_data_ref( const m A::*data ){
52 }
53 
54 template <typename A, typename m>
55 struct mem_data_t : std::unary_function<A *, m &> {
56  m A::*data;
57  inline mem_data_t( m A::*d ) : data(d) {};
58  inline m & operator()(A * instance) const {
59  return instance->*data;
60  }
61 };
62 
63 template <typename A, typename m>
64 struct const_mem_data_t : std::unary_function<const A *, const m &> {
65  const m A::*data;
66  inline const_mem_data_t(const m A::*d ) : data(d) {};
67  inline const m & operator()(const A * instance) const {
68  return instance->*data;
69  }
70 };
71 
72 template <typename A, typename m>
73 inline struct mem_data_t<A,m> mem_data( m A::*data ){
74  return mem_data_t<A,m>(data);
75 }
76 
77 template <typename A, typename m>
78 inline struct const_mem_data_t<A,m> const_mem_data( const m A::*data ){
80 }
81 
82 template <typename G, typename F>
83 struct bind_t : std::unary_function<typename F::argument_type, typename G::result_type> {
84  const F & f;
85  const G & g;
86  inline bind_t( const F & f_, const G & g_) :f(f_), g(g_) {};
87  inline typename G::result_type operator()( typename F::argument_type a) const {
88  return g(f(a));
89  }
90 };
91 
92 template <typename G, typename F>
93 inline struct bind_t<G,F> bind( const G & g, const F & f ){
94  return bind_t<G,F>(f,g);
95 }
96 
98 
102 
103 
104 namespace Internal {
105 
106 template <class T> struct make_const {
107  typedef const T type;
108 };
109 
110 template <class T> struct make_const<T&> {
111  typedef const T & type;
112 };
113 
114 template <class A, class B>
116  typedef B value_type;
117  enum { CONST = 0 };
118 };
119 
120 template <class A, class B>
121 struct forward_const<const A, B> {
122  typedef typename make_const<B>::type value_type;
123  enum { CONST = 1 };
124 };
125 
126 template <class A, class B>
127 struct forward_const<A&, B> {
128  typedef B value_type;
129  enum { CONST = 2 };
130 };
131 
132 template <class A, class B>
133 struct forward_const<const A&, B> {
134  typedef typename make_const<B>::type value_type;
135  enum { CONST = 3 };
136 };
137 
138 template <class A, class B>
139 struct forward_const<A *, B> {
140  typedef B value_type;
141  enum { CONST = 4 };
142 };
143 
144 template <class A, class B>
145 struct forward_const<const A *, B> {
146  typedef typename make_const<B>::type value_type;
147  enum { CONST = 5 };
148 };
149 
150 }
151 
162 template <typename It, typename m>
164 
165  typedef typename std::iterator_traits<It>::value_type ParentValue;
166 
167  // iterator defines
168  typedef typename std::iterator_traits<It>::iterator_category iterator_category;
169  typedef m value_type;
170  typedef typename std::iterator_traits<It>::difference_type difference_type;
173 
176 
177  inline member_iterator_t( m ParentValue::*d ) : data(d) {};
178  inline member_iterator_t( const It & it, m ParentValue::*d ) : data(d) { iterator = it; };
179 
180  template <typename Other> inline member_iterator_t & operator=(const Other & other) {
181  iterator = other;
182  return *this;
183  }
185  data = other.data;
186  iterator = other.iterator;
187  return *this;
188  }
189 
190  inline reference operator*(void) const {
191  return (*iterator).*data;
192  }
193  inline reference operator->(void) const {
194  return iterator->*data;
195  }
196 
197  inline reference operator*(void) {
198  return (*iterator).*data;
199  }
200  inline reference operator->(void) {
201  return iterator->*data;
202  }
203 
204 
206  return iterator[n].*data;
207  }
209  ++iterator;
210  return *this;
211  }
213  member_iterator_t tmp(*this);
214  iterator++;
215  return tmp;
216  }
218  --iterator;
219  return *this;
220  }
222  member_iterator_t tmp(*this);
223  iterator--;
224  return tmp;
225  }
227  iterator+=n;
228  return *this;
229  }
231  iterator-=n;
232  return *this;
233  }
234  template <typename Other>
235  inline difference_type operator-(const Other & other) const {
236  return (iterator - other);
237  }
238  inline difference_type operator-(const member_iterator_t & other) const {
239  return (iterator - other.iterator);
240  }
241  template <typename Other>
242  inline bool operator==(const Other & other) const {
243  return (iterator == other);
244  }
245  inline bool operator==(const member_iterator_t & other) const {
246  return (iterator == other.iterator);
247  }
248  template <typename Other>
249  inline bool operator!=(const Other & other) const {
250  return (iterator != other);
251  }
252  inline bool operator!=(const member_iterator_t & other) const {
253  return (iterator != other.iterator);
254  }
255 };
256 
268 template <typename It, typename m>
269 inline struct member_iterator_t<It, m> member_const_iterator( const It & it, m std::iterator_traits<It>::value_type::*d ){
270  return member_iterator_t<It, m>(it, d);
271 }
272 
273 /*
274 helper function to simplify the use of @ref member_iterator_t wrapper. This is useful for passing
275 member iterators as arguments.
276 @arg it the iterator to wrap, the new member_iterator_t returned will point to the same position
277 @arg d the member to wrap
278 @code
279 struct simple { int a; float b; };
280 vector<simple> test;
281 fill(member_iterator(test.begin(), &simple::a), member_iterator(test.end(), &simple::a), 0 );
282 @endcode
283 */
284 
285 template <typename It, typename m>
286 inline struct member_iterator_t<It, m> member_iterator(It it, m std::iterator_traits<It>::value_type::*d ){
287  return member_iterator_t<It, m>(it, d);
288 }
289 
290 
292 
293 }
294 
295 #endif // TAG_FN_H