Scroom  0.14
bookkeepingimpl.hh
Go to the documentation of this file.
1 /*
2  * Scroom - Generic viewer for 2D data
3  * Copyright (C) 2009-2022 Kees-Jan Dijkzeul
4  *
5  * SPDX-License-Identifier: LGPL-2.1
6  */
7 
8 #pragma once
9 
10 #include <stdexcept>
11 #include <utility>
12 
13 namespace Scroom::Bookkeeping
14 {
15  namespace Detail
16  {
18  {
19  public:
21  : Scroom::Bookkeeping::Token(t)
22  {
23  }
24 
26  {
27  add(rhs);
28  return *this;
29  }
30 
32  {
33  add(rhs);
34  return *this;
35  }
36 
38  {
39  merge(rhs);
40  return *this;
41  }
42 
44  {
45  merge(rhs);
46  return *this;
47  }
48  };
49 
50  class TokenImpl
51  {
52  public:
53  using Ptr = boost::shared_ptr<TokenImpl>;
54 
55  public:
56  void add(const Stuff& s) { l.push_back(s); }
57 
58  void add(const StuffList& l_) { l.insert(l.end(), l_.begin(), l_.end()); }
59 
60  void merge(StuffList& l_) { l.splice(l.end(), l_); }
61 
62  void merge(Ptr& rhs) { merge(rhs->l); }
63 
64  public:
66 
67  protected:
68  TokenImpl() = default;
69 
70  private:
72  };
73 
74  template <typename K, typename V>
75  class MapTokenImpl : public TokenImpl
76  {
77  public:
78  using Ptr = boost::shared_ptr<MapTokenImpl<K, V>>;
79 
80  private:
81  boost::weak_ptr<Scroom::Bookkeeping::MapBase<K, V>> map;
83  K k;
84 
85  protected:
86  MapTokenImpl(boost::shared_ptr<Scroom::Bookkeeping::MapBase<K, V>> map_, K k_)
87  : map(map_)
88  , k(std::move(k_))
89  {
90  }
91 
92  MapTokenImpl(const MapTokenImpl&) = delete;
93  MapTokenImpl(MapTokenImpl&&) = delete;
94  MapTokenImpl operator=(const MapTokenImpl&) = delete;
96 
97  public:
99  {
100  boost::shared_ptr<Scroom::Bookkeeping::MapBase<K, V>> const m = map.lock();
101  if(m)
102  {
103  m->remove(k, t);
104  }
105  }
106 
107  public:
109  {
110  Ptr const t = Ptr(new MapTokenImpl<K, V>(map, k));
111  t->t = t;
113  }
114  };
115 
116  template <typename V>
117  class ValueType
118  {
119  public:
120  using Ptr = boost::shared_ptr<ValueType<V>>;
121  using WeakPtr = boost::weak_ptr<ValueType<V>>;
122 
123  public:
124  V value;
126 
127  protected:
128  explicit ValueType(V value_)
129  : value(std::move(value_))
130  {
131  }
132 
133  public:
134  static Ptr create(V value) { return Ptr(new ValueType<V>(value)); }
135  };
136 
137  template <typename V>
138  class LValue
139  {
140  public:
141  using VTPtr = typename ValueType<V>::Ptr;
142 
143  private:
145 
146  public:
147  explicit LValue(VTPtr pv_)
148  : pv(std::move(pv_))
149  {
150  }
151 
152  LValue& operator=(const V& v)
153  {
154  pv->value = v;
155  return *this;
156  }
157 
158  explicit operator V() { return pv->value; }
159  };
160  } // namespace Detail
161 
163 
164  inline Token::Token(const boost::shared_ptr<Detail::TokenImpl>& t)
165  : boost::shared_ptr<Detail::TokenImpl>(t)
166  {
167  }
168 
169  inline Token::Token(const boost::weak_ptr<Detail::TokenImpl>& t)
170  : boost::shared_ptr<Detail::TokenImpl>(t)
171  {
172  }
173 
174  inline Token::Token()
175  : boost::shared_ptr<Detail::TokenImpl>(Detail::TokenImpl::create())
176  {
177  }
178 
179  inline Token::Token(const Stuff& s)
180  : boost::shared_ptr<Detail::TokenImpl>(Detail::TokenImpl::create())
181  {
182  get()->add(s);
183  }
184 
185  inline Token::Token(const StuffList& l)
186  : boost::shared_ptr<Detail::TokenImpl>(Detail::TokenImpl::create())
187  {
188  get()->add(l);
189  }
190 
191  inline void Token::add(const Stuff& s) const { get()->add(s); }
192 
193  inline void Token::add(const StuffList& l) const { get()->add(l); }
194 
195  inline void Token::merge(Token& rhs) const { get()->merge(rhs); }
196 
197  inline void Token::merge(StuffList& l) const { get()->merge(l); }
198 
199  inline Detail::TokenAddition Token::operator+(const Stuff& rhs) const { return Detail::TokenAddition(*this) + rhs; }
200 
201  inline Token const& Token::operator+=(const Stuff& rhs) const
202  {
203  add(rhs);
204  return *this;
205  }
206 
208 
209  template <typename K, typename V>
210  inline Token MapBase<K, V>::reserve(const K& k)
211  {
212  boost::mutex::scoped_lock const lock(mut);
213  if(map.end() != map.find(k))
214  {
215  throw std::invalid_argument("Key already exists");
216  }
217 
219  map[k] = pv;
220 
221  Token t = Detail::MapTokenImpl<K, V>::create(shared_from_this<MapBase<K, V>>(), k);
222  t.add(pv);
223  pv->token = t;
224  return t;
225  }
226 
227  template <typename K, typename V>
228  inline Token MapBase<K, V>::reReserve(const K& k)
229  {
230  boost::mutex::scoped_lock const lock(mut);
231  auto i = map.find(k);
232 
233  if(map.end() == i)
234  {
235  map[k] = typename Detail::ValueType<V>::WeakPtr();
236  i = map.find(k);
237  }
238 
239  typename Detail::ValueType<V>::Ptr pv = i->second.lock();
240  if(!pv)
241  {
243  i->second = pv;
244  }
245 
246  Token t(pv->token.lock());
247  if(!t)
248  {
249  t = Detail::MapTokenImpl<K, V>::create(shared_from_this<MapBase<K, V>>(), k);
250  t.add(pv);
251  pv->token = t;
252  }
253 
254  return t;
255  }
256 
257  template <typename K, typename V>
258  inline void MapBase<K, V>::remove(const K& k, const WeakToken& wt)
259  {
260  boost::mutex::scoped_lock const lock(mut);
261  auto i = map.find(k);
262 
263  if(map.end() != i)
264  {
265  typename Detail::ValueType<V>::Ptr const pv = i->second.lock();
266  if(pv)
267  {
268  Token const t(wt.lock());
269  Token const t_orig(pv->token.lock());
270  if(t == t_orig)
271  {
272  map.erase(i);
273  }
274  }
275  else
276  {
277  map.erase(i);
278  }
279  }
280  }
281 
282  template <typename K, typename V>
283  inline void MapBase<K, V>::remove(const K& k)
284  {
285  boost::mutex::scoped_lock lock(mut);
286  typename MapType::iterator i = map.find(k);
287 
288  if(map.end() != i)
289  {
290  map.erase(i);
291  }
292  }
293 
294  template <typename K, typename V>
296  {
297  boost::mutex::scoped_lock const lock(mut);
298  auto i = map.find(k);
299 
300  if(map.end() != i)
301  {
302  typename Detail::ValueType<V>::Ptr const pv = i->second.lock();
303  if(pv)
304  {
305  return Detail::LValue<V>(pv);
306  }
307  }
308 
309  throw std::invalid_argument("Invalid key");
310  }
311 
312  template <typename K, typename V>
313  inline void MapBase<K, V>::set(const K& k, const V& v)
314  {
315  boost::mutex::scoped_lock const lock(mut);
316  auto i = map.find(k);
317 
318  if(map.end() != i)
319  {
320  typename Detail::ValueType<V>::Ptr const pv = i->second.lock();
321  if(pv)
322  {
323  pv->value = v;
324  return;
325  }
326  }
327 
328  throw std::invalid_argument("Invalid key");
329  }
330 
331  template <typename K, typename V>
332  inline V MapBase<K, V>::get(const K& k)
333  {
334  boost::mutex::scoped_lock const lock(mut);
335  auto i = map.find(k);
336 
337  if(map.end() != i)
338  {
339  typename Detail::ValueType<V>::Ptr const pv = i->second.lock();
340  if(pv)
341  {
342  return pv->value;
343  }
344  }
345 
346  throw std::invalid_argument("Invalid key");
347  }
348 
349  template <typename K, typename V>
350  inline std::list<K> MapBase<K, V>::keys() const
351  {
352  boost::mutex::scoped_lock const lock(mut);
353  std::list<K> result;
354  for(const typename MapType::value_type& el: map)
355  {
356  result.push_back(el.first);
357  }
358  return result;
359  }
360 
361  template <typename K, typename V>
362  inline std::list<V> MapBase<K, V>::values() const
363  {
364  boost::mutex::scoped_lock const lock(mut);
365  std::list<V> result;
366  for(const typename MapType::value_type& el: map)
367  {
368  typename Detail::ValueType<V>::Ptr const pv = el.second.lock();
369  if(pv)
370  {
371  result.push_back(pv->value);
372  }
373  }
374  return result;
375  }
376 
378 
379  // template<typename V>
380  // inline void Map<Token, V>::addMe(const Token& k, const V& v)
381  // {
382  // k->add(add(k,v));
383  // }
384  //
385  // template<typename V>
386  // inline void Map<WeakToken, V>::addMe(const WeakToken& k, const V& v)
387  // {
388  // Token K = k.lock();
389  // if(K)
390  // K->add(add(k,v));
391  // else
392  // throw std::invalid_argument("boost::weak_ptr can't be locked");
393  // }
394  //
395  // template<typename V>
396  // inline Token Map<Token, V>::add(const V& v)
397  // {
398  // Token k;
399  // k->add(add(k,v));
400  // return k;
401  // }
402  //
403  // template<typename V>
404  // inline Token Map<WeakToken, V>::add(const V& v)
405  // {
406  // Token k;
407  // k->add(add(k,v));
408  // return k;
409  // }
410  //
411  // template<typename V>
412  // inline Token Map<WeakToken, V>::add(const WeakToken& k, const V& v)
413  // {
414  // return MapBase<WeakToken, V>::add(k,v);
415  // }
416  //
417  // template<typename V>
418  // inline Token Map<Token, V>::add(const Token& k, const V& v)
419  // {
420  // return MapBase<Token, V>::add(k,v);
421  // }
422 
423  template <typename K, typename V>
425  {
426  return Ptr(new Map<K, V>());
427  }
428 
429  // template<typename V>
430  // inline typename Map<Token, V>::Ptr Map<Token, V>::create()
431  // {
432  // return Ptr(new Map<Token, V>());
433  // }
434  //
435  // template<typename V>
436  // inline typename Map<WeakToken, V>::Ptr Map<WeakToken, V>::create()
437  // {
438  // return Ptr(new Map<WeakToken, V>());
439  // }
440 
441 } // namespace Scroom::Bookkeeping
Scroom::Bookkeeping::Detail::LValue
Definition: bookkeeping.hh:34
Scroom::Bookkeeping::Detail::LValue::operator=
LValue & operator=(const V &v)
Definition: bookkeepingimpl.hh:152
Scroom::Bookkeeping::Detail::MapTokenImpl::MapTokenImpl
MapTokenImpl(boost::shared_ptr< Scroom::Bookkeeping::MapBase< K, V >> map_, K k_)
Definition: bookkeepingimpl.hh:86
Scroom::Bookkeeping::Token::merge
void merge(Token &rhs) const
Definition: bookkeepingimpl.hh:195
Scroom::Utils::StuffList
std::list< Stuff > StuffList
Definition: stuff.hh:20
Scroom::Bookkeeping::Detail::MapTokenImpl::create
static Scroom::Bookkeeping::Token create(boost::shared_ptr< Scroom::Bookkeeping::MapBase< K, V >> map, const K &k)
Definition: bookkeepingimpl.hh:108
Scroom::Bookkeeping::Detail::ValueType::WeakPtr
boost::weak_ptr< ValueType< V > > WeakPtr
Definition: bookkeepingimpl.hh:121
Scroom::Bookkeeping::Detail::TokenAddition::operator+=
TokenAddition & operator+=(TokenAddition &rhs)
Definition: bookkeepingimpl.hh:43
Scroom::Bookkeeping::MapBase::set
void set(const K &k, const V &v)
Definition: bookkeepingimpl.hh:313
Scroom::Bookkeeping::Detail::TokenImpl::merge
void merge(StuffList &l_)
Definition: bookkeepingimpl.hh:60
Scroom::Bookkeeping::Detail::TokenAddition::TokenAddition
TokenAddition(const Scroom::Bookkeeping::Token &t)
Definition: bookkeepingimpl.hh:20
Scroom::Bookkeeping::Detail::ValueType::ValueType
ValueType(V value_)
Definition: bookkeepingimpl.hh:128
Scroom::Bookkeeping::Detail::TokenImpl::add
void add(const Stuff &s)
Definition: bookkeepingimpl.hh:56
Scroom::Bookkeeping::MapBase::keys
std::list< K > keys() const
Definition: bookkeepingimpl.hh:350
Scroom
Definition: assertions.hh:14
Scroom::MemoryBlocks::RawPageData::Ptr
boost::shared_ptr< uint8_t > Ptr
Definition: blockallocator.hh:23
Scroom::Bookkeeping::Detail::ValueType::create
static Ptr create(V value)
Definition: bookkeepingimpl.hh:134
Scroom::Bookkeeping::Map
Definition: bookkeeping.hh:82
Scroom::Bookkeeping::Detail::TokenImpl::add
void add(const StuffList &l_)
Definition: bookkeepingimpl.hh:58
Scroom::Bookkeeping::Detail::TokenAddition::operator+=
TokenAddition & operator+=(const Stuff &rhs)
Definition: bookkeepingimpl.hh:31
Scroom::Bookkeeping::MapBase::reserve
Token reserve(const K &k)
Definition: bookkeepingimpl.hh:210
Scroom::Bookkeeping::MapBase::remove
void remove(const K &k)
Definition: bookkeepingimpl.hh:283
Scroom::Bookkeeping::Detail::TokenImpl::Ptr
boost::shared_ptr< TokenImpl > Ptr
Definition: bookkeepingimpl.hh:53
Scroom::Bookkeeping::MapBase::at
Detail::LValue< V > at(const K &k)
Definition: bookkeepingimpl.hh:295
Scroom::Bookkeeping::Detail::ValueType::token
WeakToken token
Definition: bookkeepingimpl.hh:125
Scroom::Bookkeeping::Detail::LValue::LValue
LValue(VTPtr pv_)
Definition: bookkeepingimpl.hh:147
Scroom::Bookkeeping::Detail::MapTokenImpl
Definition: bookkeepingimpl.hh:75
Scroom::Bookkeeping::Detail::TokenImpl::merge
void merge(Ptr &rhs)
Definition: bookkeepingimpl.hh:62
Scroom::Bookkeeping::Detail::MapTokenImpl::~MapTokenImpl
~MapTokenImpl()
Definition: bookkeepingimpl.hh:98
Scroom::Bookkeeping::Token::operator+
Detail::TokenAddition operator+(const Stuff &rhs) const
Definition: bookkeepingimpl.hh:199
Scroom::Bookkeeping::MapBase
Definition: bookkeeping.hh:59
Scroom::Bookkeeping::MapBase::reReserve
Token reReserve(const K &k)
Definition: bookkeepingimpl.hh:228
Scroom::Utils::Stuff
boost::shared_ptr< void > Stuff
Definition: stuff.hh:18
Scroom::Bookkeeping::Detail::MapTokenImpl::map
boost::weak_ptr< Scroom::Bookkeeping::MapBase< K, V > > map
Definition: bookkeepingimpl.hh:81
Scroom::Bookkeeping::Detail::TokenAddition::operator+
TokenAddition & operator+(TokenAddition &rhs)
Definition: bookkeepingimpl.hh:37
Scroom::Bookkeeping::Detail::TokenAddition
Definition: bookkeepingimpl.hh:17
Scroom::Bookkeeping::Detail::MapTokenImpl::t
WeakToken t
Definition: bookkeepingimpl.hh:82
Scroom::Bookkeeping::Detail::ValueType::Ptr
boost::shared_ptr< ValueType< V > > Ptr
Definition: bookkeepingimpl.hh:120
Scroom::Bookkeeping::Detail::TokenAddition::operator+
TokenAddition & operator+(const Stuff &rhs)
Definition: bookkeepingimpl.hh:25
Scroom::Bookkeeping::Detail::TokenImpl
Definition: bookkeepingimpl.hh:50
Scroom::Bookkeeping::MapBase::values
std::list< V > values() const
Definition: bookkeepingimpl.hh:362
Scroom::Bookkeeping::Token::operator+=
Token const & operator+=(const Stuff &rhs) const
Definition: bookkeepingimpl.hh:201
Scroom::Bookkeeping::MapBase::get
V get(const K &k)
Definition: bookkeepingimpl.hh:332
Scroom::Bookkeeping::Detail::ValueType::value
V value
Definition: bookkeepingimpl.hh:124
Scroom::Bookkeeping::Detail::MapTokenImpl::operator=
MapTokenImpl operator=(const MapTokenImpl &)=delete
Detail
Definition: async-deleter.hh:12
Scroom::Bookkeeping::Map::Ptr
boost::shared_ptr< Map< K, V > > Ptr
Definition: bookkeeping.hh:85
Scroom::Bookkeeping::Token::Token
Token()
Definition: bookkeepingimpl.hh:174
Scroom::Bookkeeping::Detail::TokenImpl::l
StuffList l
Definition: bookkeepingimpl.hh:71
Scroom::Bookkeeping::WeakToken
boost::weak_ptr< Detail::TokenImpl > WeakToken
Definition: bookkeeping.hh:56
Scroom::Bookkeeping::Token
Definition: bookkeeping.hh:37
Scroom::Bookkeeping::Detail::LValue::pv
VTPtr pv
Definition: bookkeepingimpl.hh:144
Scroom::Bookkeeping::Detail::MapTokenImpl::k
K k
Definition: bookkeepingimpl.hh:83
Scroom::Bookkeeping::Detail::TokenImpl::create
static Scroom::Bookkeeping::Token create()
Definition: bookkeepingimpl.hh:65
Scroom::Bookkeeping::Detail::LValue::VTPtr
typename ValueType< V >::Ptr VTPtr
Definition: bookkeepingimpl.hh:141
Scroom::Bookkeeping::Detail::MapTokenImpl::Ptr
boost::shared_ptr< MapTokenImpl< K, V > > Ptr
Definition: bookkeepingimpl.hh:78
Scroom::Bookkeeping
Definition: bookkeeping.hh:20
Scroom::Bookkeeping::Token::add
void add(const Stuff &s) const
Definition: bookkeepingimpl.hh:191
Scroom::Bookkeeping::Detail::TokenImpl::TokenImpl
TokenImpl()=default
Scroom::Bookkeeping::Map::create
static Ptr create()
Definition: bookkeepingimpl.hh:424
Scroom::Bookkeeping::Detail::ValueType
Definition: bookkeeping.hh:31
create
void create(NewPresentationInterface *interface)
Definition: loader.cc:175