Minsky: 3.17.0
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 <set>
22 #include <stdlib.h>
23 
24 namespace minsky
25 {
26  template <class K>
27  struct KeyAssertion
28  {
29  KeyAssertion() {} // why?
30  KeyAssertion(const K& id) {}
31  };
32 
33  template <>
34  struct KeyAssertion<int>
35  {
36  KeyAssertion() {} // why?
37  KeyAssertion(int id) {assert(id>=0);}
38  };
39 
40 #pragma GCC diagnostic push
41  // gcc gets this one wrong
42 #pragma GCC diagnostic ignored "-Wparentheses"
43 
44  template <class Key, class Val>
45  struct IntrusiveWrap: public Val
46  {
47  public:
48  typedef const Key first_type;
50  typedef Val second_type;
51  // Val can access id by declaring a virtual method of this name
52  Key id() const {return first;};
53  IntrusiveWrap(const Key& id, const Val& v=Val()): Val(v), first(id)
55  template <class K, class V>
56  IntrusiveWrap(const std::pair<K,V> x):
57  IntrusiveWrap(x.first,x.second) {}
58  bool operator<(const IntrusiveWrap& x) const {
59  return first<x.first;
60  }
61  IntrusiveWrap& operator=(const Val& v) {
62  Val::operator=(v);
63  return *this;
64  }
66  Val::operator=(v);
67  return *this;
68  }
69  };
70 
71 #pragma GCC diagnostic pop
72 
79  template <class Key, class Val>
80  class IntrusiveMap: public std::set<IntrusiveWrap<Key, Val> >
81  {
82  typedef std::set<IntrusiveWrap<Key, Val> > Super;
83  public:
84  typedef typename Super::const_iterator const_iterator;
85  typedef typename Super::value_type value_type;
86  typedef Key key_type;
87  typedef Val mapped_type;
88 
90  std::set<Key> updateAccess;
91 
92  template <class... A> explicit IntrusiveMap(A... a): Super(std::forward<A>(a)...) {}
93 
94  // iterator class allows for assignment of value portion
95  struct iterator: public Super::const_iterator
96  {
97  iterator() {}
100  return const_cast<value_type&>(Super::const_iterator::operator*());
101  }
103  return &operator*();
104  }
105  const value_type& operator*() const {
106  return const_cast<value_type&>(Super::const_iterator::operator*());
107  }
108  const value_type* operator->() const {
109  return &operator*();
110  }
111  };
112 
113  iterator begin() {return iterator(Super::begin());}
114  const_iterator begin() const {return Super::begin();}
115 
116  iterator end() {return iterator(Super::end());}
117  const_iterator end() const {return Super::end();}
118 
119  iterator find(const Key& k) {
120  updateAccess.insert(k);
121  return iterator(Super::find(value_type(k)));
122  }
123  const_iterator find(const Key& k) const {return Super::find(value_type(k));}
124 
125  size_t count(const Key& k) const {return Super::count(value_type(k));}
126 
127  std::pair<iterator, bool> insert(const value_type& x) {
128  std::pair<const_iterator, bool> p = Super::insert(x);
129  return make_pair(iterator(p.first), p.second);
130  }
131 
132  template <class I1, class I2>
133  void insert(I1 i1, I2 i2) {Super::insert(i1,i2);}
134 
135  void insert(const Key& k, const Val& v)
136  {insert(value_type(k,v));}
137 
138  value_type& operator[](const Key& k) {
139  const_iterator it=find(k);
140  if (it==end())
141  it = Super::insert(value_type(k)).first;
142  return const_cast<value_type&>(*it);
143  }
144 
145  value_type operator[](const Key& k) const {
146  const_iterator it=find(k);
147  if (it==end())
148  return value_type(k);
149  else
150  return *it;
151  }
152 
153  void swap(IntrusiveMap& x) {Super::swap(x);}
154 
155  std::set<Key> keys() const {
156  std::set<Key> r;
157  for (const value_type& i: *this)
158  r.insert(i.id());
159  return r;
160  }
161 
162  };
163 
164  template <class K, class V>
165  struct TrackedIntrusiveMap: public IntrusiveMap<K,V>
166  {
167  const std::set<K>& accessLog() const {return this->updateAccess;}
168  void clearAccessLog() {this->updateAccess.clear();}
169  // returns true if item is in access log
170  bool hasBeenAccessed(K x) {return this->updateAccess.count(x);}
171  template <class... A> TrackedIntrusiveMap(A... a):
172  IntrusiveMap<K,V>(std::forward<A>(a)...) {}
173 
174  };
175 
176 }
177 
178 #ifdef _CLASSDESC
179 #pragma omit TCL_obj minsky::IntrusiveMap
180 #pragma omit pack minsky::IntrusiveMap
181 #pragma omit unpack minsky::IntrusiveMap
182 #endif
183 
184 namespace classdesc
185 {
186  template <class K, class T>
187  struct is_associative_container<minsky::IntrusiveMap<K,T> >:
188  public std::true_type {};
189 }
190 
191 #include <pack_base.h>
192 #include <pack_stl.h>
193 
194 namespace classdesc_access
195 {
196  namespace cd=classdesc;
197 
198  template <class K, class V>
199  struct access_pack<minsky::IntrusiveMap<K, V> >
200  {
201  template <class T>
202  void operator()(cd::pack_t& b, const cd::string& d, T& a)
203  {
204  b<<a.size();
205  for (auto i=a.begin(); i!=a.end(); ++i)
206  {
207  b<<i->id();
208  b<<static_cast<const V&>(*i);
209  }
210  }
211  };
212 
213  template <class K, class V>
214  struct access_unpack<minsky::IntrusiveMap<K, V> >
215  {
216  template <class T, class U>
217  void insert(T& a, const U& v) {a.insert(v);}
218  template <class T, class U>
219  void insert(const T& a, const U& v) {}
220 
221  template <class T>
222  void operator()(cd::pack_t& b, const cd::string& d, T& a)
223  {
224  size_t sz;
225  unpack(b,d,sz);
226  a.clear();
227  for (size_t i=0; i<sz; ++i)
228  {
229  K id;
230  unpack(b,d,id);
231  typename T::value_type v(id);
232  unpack(b,d,static_cast<V&>(v));
233  insert(a, v);
234  }
235  }
236  };
237 
238 }
239 
240 #include "intrusiveMap.cd"
241 #endif
const first_type first
Definition: intrusiveMap.h:49
value_type & operator[](const Key &k)
Definition: intrusiveMap.h:138
const_iterator end() const
Definition: intrusiveMap.h:117
void insert(const Key &k, const Val &v)
Definition: intrusiveMap.h:135
Super::const_iterator const_iterator
Definition: intrusiveMap.h:84
STL namespace.
iterator(const_iterator it)
Definition: intrusiveMap.h:98
void operator()(cd::pack_t &b, const cd::string &d, T &a)
Definition: intrusiveMap.h:222
size_t count(const Key &k) const
Definition: intrusiveMap.h:125
IntrusiveWrap(const std::pair< K, V > x)
Definition: intrusiveMap.h:56
const value_type & operator*() const
Definition: intrusiveMap.h:105
KeyAssertion(const K &id)
Definition: intrusiveMap.h:30
void operator()(cd::pack_t &b, const cd::string &d, T &a)
Definition: intrusiveMap.h:202
const value_type * operator->() const
Definition: intrusiveMap.h:108
const_iterator begin() const
Definition: intrusiveMap.h:114
IntrusiveWrap(const Key &id, const Val &v=Val())
Definition: intrusiveMap.h:53
IntrusiveWrap & operator=(IntrusiveWrap &v)
Definition: intrusiveMap.h:65
void unpack(classdesc::pack_t &b, civita::XVector &a)
Definition: schema2.cc:26
std::pair< iterator, bool > insert(const value_type &x)
Definition: intrusiveMap.h:127
std::set< Key > keys() const
Definition: intrusiveMap.h:155
Expr operator*(const NodePtr &x, const Expr &y)
Definition: expr.h:99
std::set< IntrusiveWrap< Key, Val > > Super
Definition: intrusiveMap.h:82
bool operator<(const IntrusiveWrap &x) const
Definition: intrusiveMap.h:58
const_iterator find(const Key &k) const
Definition: intrusiveMap.h:123
iterator find(const Key &k)
Definition: intrusiveMap.h:119
vector< SliceLabelToken, LibCAllocator< SliceLabelToken > > Key
Definition: CSVParser.cc:225
std::set< Key > updateAccess
track writeable access into this Map
Definition: intrusiveMap.h:90
const std::set< K > & accessLog() const
Definition: intrusiveMap.h:167
Super::value_type value_type
Definition: intrusiveMap.h:85
value_type operator[](const Key &k) const
Definition: intrusiveMap.h:145
void insert(I1 i1, I2 i2)
Definition: intrusiveMap.h:133
void swap(IntrusiveMap &x)
Definition: intrusiveMap.h:153
IntrusiveWrap & operator=(const Val &v)
Definition: intrusiveMap.h:61