ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
scopestore.inl
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_alox of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALOX_DETAIL_SCOPE
9#define HPP_ALOX_DETAIL_SCOPE 1
10
11#if !defined(HPP_ALIB_LOX_PROPPERINCLUDE)
12# error "ALib sources with ending '.inl' must not be included from outside."
13#endif
14
15#if !defined (HPP_ALOX_DETAIL_DOMAIN)
17#endif
18
19#if !defined(HPP_ALIB_MONOMEM_STRINGTREE)
21#endif
22
23#if !defined (HPP_ALIB_MONOMEM_HASHMAP)
25#endif
26
27#if !defined (_GLIBCXX_MAP) && !defined(_MAP_)
28# include <map>
29#endif
30
31namespace alib { namespace lox { namespace detail {
32
33// forward declarations
34class ScopeInfo;
35class PrefixLogable;
36
37
38/** ************************************************************************************************
39 * Static axiomatic methods on value types stored in class \b ScopeStore.
40 * \note This is a pure internal helper class. Documentation may be limited.
41 **************************************************************************************************/
42template<typename T>
44{
45 public:
46
47 /** ********************************************************************************************
48 * Static method to retrieve a value representing 'null' for the template type.
49 * @return The value representing null.
50 **********************************************************************************************/
52 static T NullValue();
53
54 /** ********************************************************************************************
55 * Returns true if the value is representing 'null'.
56 * @param value The object to test for 'null'.
57 * @returns \c true if the value is representing 'null', \c false otherwise.
58 **********************************************************************************************/
60 static bool IsNull( T value );
61
62 /** ********************************************************************************************
63 * Compares two template values.
64 * @param first First value.
65 * @param second Second value.
66 * @returns \c true if objects are equal, \c false otherwise.
67 **********************************************************************************************/
69 static bool AreEqual( T first, T second );
70
71}; // ScopeStoreType
72
73
74// forwards
75template<typename T, bool TStackedThreadValues>
76class ScopeStore;
77
78/**
79 * A helper class that has two specializations to implement different versions of methods
80 * \alib{lox::detail;ScopeStore::Walk} and
81 * \alib{lox::detail;ScopeStore::access} for each boolean value of template argument
82 * \p{TStackedThreadValues}.<br>
83 *
84 * @tparam T The stored object type.
85 * @tparam TStackedThreadValues If true, values stored for thread scopes will be always replaced
86 * instead of appended.
87 * This is for example \c false for <em>Log Data</em> and
88 * <em>Log Once</em> and \c true for <em>Scope Domains</em>
89 * and <em>Prefix Logables</em>.
90 */
91template<typename T, bool TStackedThreadValues>
93{
94 /** Implements \alib{lox::detail;ScopeStore::Walk} with two specializations.
95 * @param self The \b ScopeStore that invoked us.
96 * @return The result as specified in \alib{lox::detail;ScopeStore::Walk}.
97 */
99
100 /** Implements \alib{lox::detail;ScopeStore::access} with two specializations.
101 * @param self The \b ScopeStore that invoked us.
102 * @param cmd Parameter \p{cmd} of the original method.
103 * @param value Parameter \p{value} of the original method.
104 * @return The result as specified in \alib{lox::detail;ScopeStore::access}.
105 */
106 T doAccess( ScopeStore<T, TStackedThreadValues>& self, int cmd, T value );
107};
108
109#if !defined(ALIB_DOX)
110// specializations for true/false of TStackedThreadValues
111template<typename T > struct ScopeStoreHelper<T, false>
112{
113 T doWalk ( ScopeStore<T, false>& self );
114 T doAccess( ScopeStore<T, false>& self, int cmd, T value );
115};
116
117template<typename T > struct ScopeStoreHelper<T, true>
118{
119 T doWalk ( ScopeStore<T, true>& self );
120 T doAccess( ScopeStore<T, true>& self, int cmd, T value );
121};
122#endif
123
124/** ************************************************************************************************
125 * This class is responsible for scope-related functionality of class Lox.
126 * \note This is a pure internal helper class. Documentation may be limited.
127 * @tparam T The stored object type.
128 * @tparam TStackedThreadValues If true, values stored for thread scopes will be always replaced
129 * instead of appended.
130 * This is for example \c false for <em>Log Data</em> and
131 * <em>Log Once</em> and \c true for <em>Scope Domains</em>
132 * and <em>Prefix Logables</em>.
133 **************************************************************************************************/
134template<typename T, bool TStackedThreadValues>
136{
137 #if !defined(ALIB_DOX)
138 friend struct ScopeStoreHelper<T, TStackedThreadValues>;
139 #endif
140
141 public:
142 /**
143 * Alias name for the string tree template used for storing language-related data.
144 * The language store uses a \c StringTree with a monotonic allocator.
145 * This does not lead to memory leaks, because during the life-time of a \b %Lox objects
146 * are only added, but never deleted. If a value is unset, the node is not deleted but
147 * set to a \e nulled value. This makes the language store very memory efficient (and fast).
148 */
150
151 /**
152 * The type of object stored for the thread values. This depends on whether multiple
153 * (a stack of) values can be stored, which is not true for log data and log once, as
154 * those operate with hash maps.
155 */
156 using ThreadMapValueT= ATMP_IF_T_F(TStackedThreadValues,
157 std::vector<T ALIB_COMMA StdContMA<T>>,
158 T );
159
160 /** The value of the global scope. */
162
163 /** \b %StringTree to store data for language-related scopes (path,source,method). */
165
166#if ALIB_THREADS
167 /** Key type for the thread store. */
168 using ThreadMapKey = std::pair<bool,threads::ThreadID>;
169
170 /** Hash functor for <c>std::pair<bool,ThreadID></c>. */
172 {
173 /**
174 * Calculates a hash code.
175 * @param src The object to hash.
176 * @return The hash code.
177 */
178 std::size_t operator()(const std::pair<bool, threads::ThreadID>& src) const
179 {
180 return src.first ? std::size_t( src.second * 282312799l )
181 : std::size_t( src.second * 573292817l ) ^ std::size_t(-1);
182 }
183 };
184
185 /** The inner/outer thread map of values. The boolean value of the key is \c true for
186 * the inner store and \c false for the outer. */
190#endif
191
192
193 // #############################################################################################
194 // Protected fields
195 // #############################################################################################
196 protected:
197
198 /** ScopeInfo of 'our' lox. */
200
201 /** Flag used to lazily create the key to language-related scope values. */
203
204 /** Indicates if currently a scope walk is active. */
206
207 /** The actual scope of a walk. */
209
210 /** The actual language related scope's map node. */
212
213 /** The path level when using access methods. */
215
216#if ALIB_THREADS
217 /** Actual thread ID */
219#endif
220
221 /** The 'local object' returned by a walk after Scope::ThreadInner and before Scope::Method. */
223
224 /** The next value of a walk during \e Scope::ThreadInner/Outer. */
226
227 /** The list of values of \e Scope::ThreadOuter/Inner during a walk. */
229
230 // #############################################################################################
231 // Public interface
232 // #############################################################################################
233 public:
234
235 /** ****************************************************************************************
236 * Constructor
237 * @param scopeInfo The ScopeInfo singleton of 'our' Lox.
238 * @param monoAllocator The monotonic allocator used for the
239 * \alib{monomem;StringTree} needed by member
240 * #languageStore.
241 ******************************************************************************************/
244 monomem::MonoAllocator* monoAllocator );
245
246 /** ****************************************************************************************
247 * Destructor
248 ******************************************************************************************/
250 ~ScopeStore();
251
252 /** ****************************************************************************************
253 * Deletes all data stored and resets containers as the monotonic allocator will be reset
254 * after an invocation to this method as well.
255 *
256 * \note
257 * This method is used only with \alib{lox;Lox::Reset}, which is only provided
258 * to reset a lox in the unit-tests.
259 ******************************************************************************************/
261 void Reset();
262
263 /** ****************************************************************************************
264 * Initializes access methods #Store, #Get and #Remove and has to be invoked prior to
265 * using them
266 * @param scope Scope to use.
267 * @param pathLevel Used only if parameter \p{scope} equals \alib{lox;Scope;Scope::Path}
268 * to reference parent directories. Optional and defaults to \c 0.
269 * @param threadID ID of the associated thread (for thread-related scopes only).
270 * If \alib{threads::UNDEFINED} is given, the ID provided in
271 * \p{scopeInfo} is used.
272 ******************************************************************************************/
274 void InitAccess ( Scope scope, int pathLevel, threads::ThreadID threadID );
275
276 /** ****************************************************************************************
277 * Stores a new value.
278 * @param value The value to set.
279 * @return Returns the previous value stored.
280 ******************************************************************************************/
281 T Store ( T value )
282 {
284 return access( 0, value );
285 }
286
287
288 /** ****************************************************************************************
289 * Removes a value.
290 * @param value The value to remove (must only be given for thread-related \e Scopes).
291 * @return Returns the previous value stored.
292 ******************************************************************************************/
293 T Remove ( T value )
294 {
295 return access( 1, value );
296 }
297
298 /** ****************************************************************************************
299 * Retrieves the value.
300 * @return Returns the current value stored.
301 ******************************************************************************************/
302 T Get ()
303 {
305 }
306
307 /** ****************************************************************************************
308 * Initializes a scope 'walk' by storing the given scope information and
309 * setting fields of our walk 'state-machine' to proper start values.
310 *
311 * @param startScope The \e Scope to start searching for.
312 * @param localObject The 'local object' returned by a walk after Scope::ThreadInner
313 * and before Scope::Method
314 ******************************************************************************************/
316 void InitWalk( Scope startScope, const T localObject );
317
318 /** ****************************************************************************************
319 * Searches next value in the actual scope. While not found, moves walk state to next outer
320 * state and continues there.
321 * @return The next object found in the current or any next outer scope.
322 ******************************************************************************************/
324
325
326
327
328 // #############################################################################################
329 // Internals
330 // #############################################################################################
331 protected:
332 /** ****************************************************************************************
333 * Retrieves and optionally creates an entry in the map that stores language-related
334 * scope information. The result is stored in field #actStringTreeNode.
335 * @param create If \c true, a non-existing entry is created.
336 ******************************************************************************************/
337 void initCursor( bool create );
338
339 /** ****************************************************************************************
340 * Receives, inserts or removes a value.
341 * @param cmd 0= insert, 1= remove, 2= get.
342 * @param value The new value or the one to be removed.
343 * @return Returns the previous value stored.
344 ******************************************************************************************/
345 T access( int cmd, T value ) { return ScopeStoreHelper<T, TStackedThreadValues>()
346 .doAccess( *this, cmd, value ); }
347}; // ScopeStore
348
349
350#if !defined(ALIB_DOX)
351#if !defined(_MSC_VER)
354extern template void ScopeStore<NString ,true> ::Reset ();
358extern template void ScopeStore<NString ,true> ::initCursor (bool);
360
363extern template void ScopeStore<PrefixLogable* ,true> ::Reset ();
367extern template void ScopeStore<PrefixLogable* ,true> ::initCursor (bool);
369
370extern template ScopeStore<std::map<NString, int>* ,false> ::ScopeStore (ScopeInfo&, monomem::MonoAllocator*);
371extern template ScopeStore<std::map<NString, int>* ,false> ::~ScopeStore();
372extern template void ScopeStore<std::map<NString, int>* ,false> ::Reset ();
373extern template void ScopeStore<std::map<NString, int>* ,false> ::InitWalk (Scope,std::map<NString, int>*);
374extern template std::map<NString, int>* ScopeStoreHelper<std::map<NString, int>* ,false> ::doWalk (ScopeStore<std::map<NString, int>*, false>& );
375extern template void ScopeStore<std::map<NString, int>* ,false> ::InitAccess (Scope,int,threads::ThreadID);
376extern template void ScopeStore<std::map<NString, int>* ,false> ::initCursor (bool);
377extern template std::map<NString, int>* ScopeStoreHelper<std::map<NString, int>* ,false> ::doAccess (ScopeStore<std::map<NString, int>*, false>&, int, std::map<NString, int>* );
378
379extern template ScopeStore<std::map<NString, Box>* ,false> ::ScopeStore (ScopeInfo&, monomem::MonoAllocator*);
380extern template ScopeStore<std::map<NString, Box>* ,false> ::~ScopeStore();
381extern template void ScopeStore<std::map<NString, Box>* ,false> ::Reset ();
382extern template void ScopeStore<std::map<NString, Box>* ,false> ::InitWalk (Scope,std::map<NString, Box>*);
383extern template std::map<NString, Box>* ScopeStoreHelper<std::map<NString, Box>* ,false> ::doWalk (ScopeStore<std::map<NString, Box>*, false>& );
384extern template void ScopeStore<std::map<NString, Box>* ,false> ::InitAccess (Scope,int,threads::ThreadID);
385extern template void ScopeStore<std::map<NString, Box>* ,false> ::initCursor (bool);
386extern template std::map<NString, Box>* ScopeStoreHelper<std::map<NString, Box>* ,false> ::doAccess (ScopeStore<std::map<NString, Box>*, false>&, int, std::map<NString, Box>* );
387#endif
388
389template<> inline bool ScopeStoreType<NString > ::AreEqual ( NString first, NString second ) { return first.Equals<false>( second ); }
390template<> inline bool ScopeStoreType<NString > ::IsNull ( NString value ) { return value.IsNull(); }
391template<> inline NString ScopeStoreType<NString > ::NullValue () { return NullNString(); }
392template<> inline bool ScopeStoreType<PrefixLogable* > ::AreEqual ( PrefixLogable* first, PrefixLogable* second ) { return static_cast<Box*>(first)->Call<FEquals>(*second); }
393template<> inline bool ScopeStoreType<PrefixLogable* > ::IsNull ( PrefixLogable* value ) { return value == nullptr; }
394template<> inline PrefixLogable* ScopeStoreType<PrefixLogable* > ::NullValue () { return nullptr; }
395template<> inline bool ScopeStoreType<std::map<NString, int>*> ::AreEqual ( std::map<NString, int>* first, std::map<NString, int>* second ) { return first == second; }
396template<> inline bool ScopeStoreType<std::map<NString, int>*> ::IsNull ( std::map<NString, int>* value ) { return value == nullptr; }
397template<> inline std::map<NString, int>* ScopeStoreType<std::map<NString, int>*> ::NullValue () { return nullptr; }
398template<> inline bool ScopeStoreType<std::map<NString, Box>*> ::AreEqual ( std::map<NString, Box>* first, std::map<NString, Box>* second ) { return first == second; }
399template<> inline bool ScopeStoreType<std::map<NString, Box>*> ::IsNull ( std::map<NString, Box>* value ) { return value == nullptr; }
400template<> inline std::map<NString, Box>* ScopeStoreType<std::map<NString, Box>*> ::NullValue () { return nullptr; }
401
402#endif
403
404
405}}} // namespace [alib::lox::detail]
406
407
408
409#endif // HPP_ALOX_DETAIL_SCOPE
static ALIB_API bool IsNull(T value)
static ALIB_API bool AreEqual(T first, T second)
ALIB_API void InitWalk(Scope startScope, const T localObject)
T access(int cmd, T value)
ATMP_IF_T_F(TStackedThreadValues, std::vector< T ALIB_COMMA StdContMA< T > >, T) ThreadMapValueT
ALIB_API void InitAccess(Scope scope, int pathLevel, threads::ThreadID threadID)
ThreadMapValueT * walkThreadValues
threads::ThreadID actThreadID
HashMap< ThreadMapKey, ThreadMapValueT, BoolThreadIDHash > threadStore
LanguageStoreT::Cursor actStringTreeNode
std::pair< bool, threads::ThreadID > ThreadMapKey
ALIB_API ScopeStore(ScopeInfo &scopeInfo, monomem::MonoAllocator *monoAllocator)
constexpr bool IsNull() const
Definition string.hpp:395
bool Equals(const TString< TChar > &rhs) const
Definition string.hpp:573
#define ATMP_IF_T_F( Cond, T, F)
Definition tmp.hpp:54
#define ALIB_API
Definition alib.hpp:538
#define ALIB_COMMA
Definition alib.hpp:825
#define ALIB_ASSERT(cond)
Definition alib.hpp:983
integer ThreadID
Definition loxpimpl.inl:34
Definition alib.cpp:57
strings::TString< nchar > NString
Type alias in namespace alib.
constexpr NString NullNString()
Definition string.hpp:2510
boxing::Box Box
Type alias in namespace alib.
T doWalk(ScopeStore< T, TStackedThreadValues > &self)
T doAccess(ScopeStore< T, TStackedThreadValues > &self, int cmd, T value)
std::size_t operator()(const std::pair< bool, threads::ThreadID > &src) const