Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
defs-registry.hpp
Go to the documentation of this file.
1/*
2 DEFS-REGISTRY.hpp - implementation of the default object store
3
4 Copyright (C)
5 2008, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
38#ifndef LUMIERA_QUERY_DEFS_REGISTRY_H
39#define LUMIERA_QUERY_DEFS_REGISTRY_H
40
41
42#include "lib/p.hpp"
43#include "lib/util.hpp"
44#include "lib/util-foreach.hpp"
46#include "lib/format-string.hpp"
47#include "lib/query-util.hpp"
48#include "common/query.hpp"
49#include "lib/nocopy.hpp"
50
51#include <set>
52#include <vector>
53#include <memory>
54
55
56namespace lumiera{
57namespace query {
58
59 using lib::P;
60 using lib::ClassLock;
61 using std::weak_ptr;
62 using std::string;
63
64 namespace impl {
65
66 namespace {
67 using util::_Fmt;
68
70 _Fmt dumpRecord ("%2i| %64s --> %s\n");
71 }
72
73
75 {
76 virtual ~TableEntry() {};
77 };
78
81 using Table = std::vector< P<TableEntry> >;
82
83
87 template<class TAR>
88 struct Record
89 {
91 weak_ptr<TAR> objRef;
93
94 Record (Query<TAR> const& q, P<TAR> const& obj)
95 : queryKey (q)
96 , objRef (obj)
98 { }
99
100
101 struct Search
102 {
103 Search (P<TAR> const& obj)
104 : obj_(obj) { }
105
106 P<TAR> const& obj_;
107
108 bool
109 operator() (Record const& rec)
110 {
111 P<TAR> storedObj (rec.objRef.lock());
112 return storedObj and (storedObj == obj_);
113 }
114 };
115
116 friend bool
117 operator< (Record one, Record two)
118 {
119 return one.queryKey < two.queryKey;
120 }
121
122 operator string () const { return dumpRecord % degree % queryKey.display() % dumpObj(); }
123 string dumpObj () const { P<TAR> o (objRef.lock()); return o? string(*o):"dead"; }
124 };
125
131 template<class TAR>
132 struct Slot
133 : public TableEntry
134 {
135 using Registry = std::set<Record<TAR>>;
136
138 static size_t index;
139
140 static Registry&
141 access (Table& table)
142 {
143 if ( not index
144 or index > table.size()
145 or not table[index-1])
146 createSlot (table);
147
148 ASSERT (0 < index and index<=table.size() and table[index-1]);
149 Slot* item = static_cast<Slot*> (table[index-1].get());
150 return item->registry;
151 }
152
153 private:
154 static void
156 {
158 if (!index)
159 index = ++maxSlots;
160 if (index > table.size())
161 table.resize (index);
162 table[index-1].reset(new Slot);
163 }
164 };
165
166
167 // static vars to organise one Table Slot per type....
168 template<class TAR>
169 size_t Slot<TAR>::index (0);
170
171
172
173
188 {
190
191 public:
193 template<class TAR>
194 class Iter
195 {
196 friend class DefsRegistry;
198
201
202 Iter (II from, II to)
203 : p(from), i(from), e(to)
204 {
205 if (i!=e) ++i; // p is next to be tested, i always one ahead
206 operator++ ();
207 }
208
209 Iter (II match, II from, II to)
210 : p(match), i(from), e(to)
211 {
212 operator++ (); // init to first element (or to null if empty)
213 }
214
215 P<TAR>
217 {
218 while (!next)
219 {
220 if (p==e) break;
221 next = p->objRef.lock();
222 p = i++;
223 }
224 return next;
225 }
226
227
228 public:
229 P<TAR> operator* () { return ptr; }
230 bool hasNext () { return next or findNext(); }
232 {
233 ptr=findNext();
234 next.reset();
235 return *this;
236 }
237 };
238
248 template<class TAR>
249 Iter<TAR>
250 candidates (Query<TAR> const& query)
251 {
252 P<TAR> dummy;
253 Record<TAR> entry (query, dummy);
254 using Registry = Slot<TAR>::Registry;
255 Registry& registry = Slot<TAR>::access(table_);
256
257 // try to get a possible direct match (same query)
258 auto pos = registry.find (entry);
259 auto end = registry.end();
260
261 if (pos==end)
262 return Iter<TAR> (registry.begin(), end); // just enumerate contents
263 else
264 return Iter<TAR> (pos, registry.begin(), end); // start with direct match
265 }
266
267
275 template<class TAR>
276 bool
277 put (P<TAR> const& obj, Query<TAR> const& query)
278 {
279 Record<TAR> entry (query, obj);
280 using Registry = Slot<TAR>::Registry;
281 using RIter = Registry::iterator;
282
283 Registry& registry = Slot<TAR>::access(table_);
284 RIter pos = registry.lower_bound (entry);
285 if (pos!=registry.end() and
286 pos->queryKey == query)
287 {
288 P<TAR> storedObj (pos->objRef.lock());
289 if (storedObj)
290 return (storedObj == obj);
291 else
292 // use the opportunity to purge the expired entry
293 registry.erase(pos++);
294 }
295 // no existing entry....
296 registry.insert(pos, entry);
297 ENSURE (registry.find (entry) != registry.end());
298 return true;
299 }
300
301
305 template<class TAR>
306 bool
307 forget (P<TAR> const& obj)
308 {
309 using Registry = Slot<TAR>::Registry;
310 using SearchFunc = Record<TAR>::Search;
311
312 Registry& registry = Slot<TAR>::access(table_);
313 return util::remove_if(registry, SearchFunc (obj));
314 }
315
316
320 template<class TAR>
321 string
323 {
324 string res;
326 , [&] (Record<TAR>& entry)
327 {
328 res += string(entry);
329 }
330 );
331 return res;
332 }
333 };
334
335
336
337 } // (End) impl namespace
338
339 using impl::DefsRegistry;
340
341
342}} // namespace lumiera::query
343#endif
A synchronisation protection guard employing a lock scoped to the parameter type as a whole,...
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition p.hpp:77
Wrapper for indexing and ordering.
Definition query.hpp:371
string display() const
Definition query.hpp:399
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition query.hpp:254
used for enumerating solutions
Slot< TAR >::Registry::iterator II
string dump()
helper for diagnostics.
Iter< TAR > candidates(Query< TAR > const &query)
find a sequence of "default" objects possibly matching the query.
bool put(P< TAR > const &obj, Query< TAR > const &query)
register the object as being "default" when searching something similar as designated by the given qu...
bool forget(P< TAR > const &obj)
if this object is registered as "default" in some way, drop the registration.
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
A front-end for using printf-style formatting.
Front-end for printf-style string template interpolation.
unsigned int uint
Definition integral.hpp:29
uint maxSlots(0)
number of different registered Types
std::vector< P< TableEntry > > Table
we maintain an independent defaults registry for every participating kind of object.
Lumiera public interface.
Definition advice.hpp:102
bool remove_if(SET &set, FUN test)
remove all elements fulfilling a given predicate from a (sorted) set.
Definition util.hpp:319
disable_if< can_IterForEach< Container >, FUN > for_each(Container const &coll, FUN doIt)
operate on all elements of a STL container.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Customised refcounting smart pointer.
Utilities to support working with predicate queries.
Basic and generic representation of an internal query.
< Functor searching for a specific object
holding a single "default object" entry
friend bool operator<(Record one, Record two)
Record(Query< TAR > const &q, P< TAR > const &obj)
every new kind of object (Type) creates a new slot in the main Table holding all registered default o...
static void createSlot(Table &table)
static size_t index
where to find this Slot in every Table
static Registry & access(Table &table)
std::set< Record< TAR > > Registry
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Perform operations "for each element" of a collection.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...