Minsky
intrusiveMap.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2013
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef INTRUSIVEMAP_H
20 #define INTRUSIVEMAP_H
21 #include <TCL_obj_base.h>
22 #include <TCL_obj_stl.h>
23 #include <set>
24 #include <stdlib.h>
25 
26 namespace minsky
27 {
28  template <class K>
29  struct KeyAssertion
30  {
31  KeyAssertion() {} // why?
32  KeyAssertion(const K& id) {}
33  };
34 
35  template <>
36  struct KeyAssertion<int>
37  {
38  KeyAssertion() {} // why?
39  KeyAssertion(int id) {assert(id>=0);}
40  };
41 
42 #pragma GCC diagnostic push
43  // gcc gets this one wrong
44 #pragma GCC diagnostic ignored "-Wparentheses"
45 
46  template <class Key, class Val>
47  struct IntrusiveWrap: public Val
48  {
49  public:
50  typedef const Key first_type;
52  typedef Val second_type;
53  // Val can access id by declaring a virtual method of this name
54  Key id() const {return first;};
55  IntrusiveWrap(const Key& id, const Val& v=Val()): Val(v), first(id)
57  template <class K, class V>
58  IntrusiveWrap(const std::pair<K,V> x):
59  IntrusiveWrap(x.first,x.second) {}
60  bool operator<(const IntrusiveWrap& x) const {
61  return first<x.first;
62  }
63  IntrusiveWrap& operator=(const Val& v) {
64  Val::operator=(v);
65  return *this;
66  }
68  Val::operator=(v);
69  return *this;
70  }
71  };
72 
73 #pragma GCC diagnostic pop
74 
81  template <class Key, class Val>
82  class IntrusiveMap: public std::set<IntrusiveWrap<Key, Val> >
83  {
84  typedef std::set<IntrusiveWrap<Key, Val> > Super;
85  public:
86  typedef typename Super::const_iterator const_iterator;
87  typedef typename Super::value_type value_type;
88  typedef Key key_type;
89  typedef Val mapped_type;
90 
92  std::set<Key> updateAccess;
93 
94  template <class... A> explicit IntrusiveMap(A... a): Super(std::forward<A>(a)...) {}
95 
96  // iterator class allows for assignment of value portion
97  struct iterator: public Super::const_iterator
98  {
99  iterator() {}
102  return const_cast<value_type&>(Super::const_iterator::operator*());
103  }
105  return &operator*();
106  }
107  const value_type& operator*() const {
108  return const_cast<value_type&>(Super::const_iterator::operator*());
109  }
110  const value_type* operator->() const {
111  return &operator*();
112  }
113  };
114 
115  iterator begin() {return iterator(Super::begin());}
116  const_iterator begin() const {return Super::begin();}
117 
118  iterator end() {return iterator(Super::end());}
119  const_iterator end() const {return Super::end();}
120 
121  iterator find(const Key& k) {
122  updateAccess.insert(k);
123  return iterator(Super::find(value_type(k)));
124  }
125  const_iterator find(const Key& k) const {return Super::find(value_type(k));}
126 
127  size_t count(const Key& k) const {return Super::count(value_type(k));}
128 
129  std::pair<iterator, bool> insert(const value_type& x) {
130  std::pair<const_iterator, bool> p = Super::insert(x);
131  return make_pair(iterator(p.first), p.second);
132  }
133 
134  template <class I1, class I2>
135  void insert(I1 i1, I2 i2) {Super::insert(i1,i2);}
136 
137  void insert(const Key& k, const Val& v)
138  {insert(value_type(k,v));}
139 
140  value_type& operator[](const Key& k) {
141  const_iterator it=find(k);
142  if (it==end())
143  it = Super::insert(value_type(k)).first;
144  return const_cast<value_type&>(*it);
145  }
146 
147  value_type operator[](const Key& k) const {
148  const_iterator it=find(k);
149  if (it==end())
150  return value_type(k);
151  else
152  return *it;
153  }
154 
155  void swap(IntrusiveMap& x) {Super::swap(x);}
156 
157  std::set<Key> keys() const {
158  std::set<Key> r;
159  for (const value_type& i: *this)
160  r.insert(i.id());
161  return r;
162  }
163 
164  };
165 
166  template <class K, class V>
167  struct TrackedIntrusiveMap: public IntrusiveMap<K,V>
168  {
169  const std::set<K>& accessLog() const {return this->updateAccess;}
170  void clearAccessLog() {this->updateAccess.clear();}
171  // returns true if item is in access log
172  bool hasBeenAccessed(K x) {return this->updateAccess.count(x);}
173  template <class... A> TrackedIntrusiveMap(A... a):
174  IntrusiveMap<K,V>(std::forward<A>(a)...) {}
175 
176  };
177 
178 }
179 
180 #ifdef _CLASSDESC
181 #pragma omit TCL_obj minsky::IntrusiveMap
182 #pragma omit pack minsky::IntrusiveMap
183 #pragma omit unpack minsky::IntrusiveMap
184 #endif
185 
186 namespace ecolab
187 {
188  // note: this definition needs to exist before TCL_obj_stl.h is
189  // included FOR THE FIRST TIME, otherwise it is ignored.
190  template <class K, class T>
191  inline void keys_of(const minsky::IntrusiveMap<K,T>& o)
192  {
193  tclreturn r;
194  for (const typename minsky::IntrusiveMap<K,T>::value_type& i: o)
195  r<<i.id();
196  }
197  // ensures IntrusiveMap is treated as map, not a set
198  template <class Key, class Val>
199  struct is_map<minsky::IntrusiveWrap<Key,Val> >: public true_type
200  {
201  static string keys() {return ".#keys";}
202  static string type() {return ".@is_map";}
203  };
204 }
205 
206 namespace classdesc
207 {
208  template <class K, class T>
209  struct is_associative_container<minsky::IntrusiveMap<K,T> >:
210  public std::true_type {};
211 }
212 
213 namespace ecolab
214 {
215  template <class K, class T>
216  struct is_map<minsky::IntrusiveMap<K,T>>: public is_map_map {};
217 }
218 
219 
220 #include <TCL_obj_stl.h>
221 #include <pack_base.h>
222 #include <pack_stl.h>
223 
224 namespace classdesc_access
225 {
226  namespace cd=classdesc;
227 
228  template <class K, class V>
229  struct access_pack<minsky::IntrusiveMap<K, V> >
230  {
231  template <class T>
232  void operator()(cd::pack_t& b, const cd::string& d, T& a)
233  {
234  b<<a.size();
235  for (auto i=a.begin(); i!=a.end(); ++i)
236  {
237  b<<i->id();
238  b<<static_cast<const V&>(*i);
239  }
240  }
241  };
242 
243  template <class K, class V>
244  struct access_unpack<minsky::IntrusiveMap<K, V> >
245  {
246  template <class T, class U>
247  void insert(T& a, const U& v) {a.insert(v);}
248  template <class T, class U>
249  void insert(const T& a, const U& v) {}
250 
251  template <class T>
252  void operator()(cd::pack_t& b, const cd::string& d, T& a)
253  {
254  size_t sz;
255  unpack(b,d,sz);
256  a.clear();
257  for (size_t i=0; i<sz; ++i)
258  {
259  K id;
260  unpack(b,d,id);
261  typename T::value_type v(id);
262  unpack(b,d,static_cast<V&>(v));
263  insert(a, v);
264  }
265  }
266  };
267 
268 }
269 
270 #include "intrusiveMap.cd"
271 #endif
void keys_of(const minsky::IntrusiveMap< K, T > &o)
Definition: intrusiveMap.h:191
const first_type first
Definition: intrusiveMap.h:51
value_type & operator[](const Key &k)
Definition: intrusiveMap.h:140
const_iterator end() const
Definition: intrusiveMap.h:119
void insert(const Key &k, const Val &v)
Definition: intrusiveMap.h:137
Super::const_iterator const_iterator
Definition: intrusiveMap.h:86
void unpack(classdesc::pack_t &, const classdesc::string &, classdesc::ref< ecolab::urand > &)
STL namespace.
iterator(const_iterator it)
Definition: intrusiveMap.h:100
void operator()(cd::pack_t &b, const cd::string &d, T &a)
Definition: intrusiveMap.h:252
size_t count(const Key &k) const
Definition: intrusiveMap.h:127
IntrusiveWrap(const std::pair< K, V > x)
Definition: intrusiveMap.h:58
const value_type & operator*() const
Definition: intrusiveMap.h:107
KeyAssertion(const K &id)
Definition: intrusiveMap.h:32
void operator()(cd::pack_t &b, const cd::string &d, T &a)
Definition: intrusiveMap.h:232
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
const value_type * operator->() const
Definition: intrusiveMap.h:110
const_iterator begin() const
Definition: intrusiveMap.h:116
IntrusiveWrap(const Key &id, const Val &v=Val())
Definition: intrusiveMap.h:55
IntrusiveWrap & operator=(IntrusiveWrap &v)
Definition: intrusiveMap.h:67
std::pair< iterator, bool > insert(const value_type &x)
Definition: intrusiveMap.h:129
std::set< Key > keys() const
Definition: intrusiveMap.h:157
Expr operator*(const NodePtr &x, const Expr &y)
Definition: expr.h:100
std::set< IntrusiveWrap< Key, Val > > Super
Definition: intrusiveMap.h:84
bool operator<(const IntrusiveWrap &x) const
Definition: intrusiveMap.h:60
const_iterator find(const Key &k) const
Definition: intrusiveMap.h:125
iterator find(const Key &k)
Definition: intrusiveMap.h:121
vector< SliceLabelToken, LibCAllocator< SliceLabelToken > > Key
Definition: CSVParser.cc:225
std::set< Key > updateAccess
track writeable access into this Map
Definition: intrusiveMap.h:92
const std::set< K > & accessLog() const
Definition: intrusiveMap.h:169
Super::value_type value_type
Definition: intrusiveMap.h:87
value_type operator[](const Key &k) const
Definition: intrusiveMap.h:147
void insert(I1 i1, I2 i2)
Definition: intrusiveMap.h:135
void swap(IntrusiveMap &x)
Definition: intrusiveMap.h:155
IntrusiveWrap & operator=(const Val &v)
Definition: intrusiveMap.h:63