8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
48#if !ALIB_SINGLE_THREADED
57template<
typename T,
bool TStackedThreadValues>
65 #if ALIB_DEBUG_CRITICAL_SECTIONS
71template<
typename T,
bool TStackedThreadValues>
81template<
typename T,
bool TStackedThreadValues>
99 case Scope::ThreadInner:
105 #if !ALIB_SINGLE_THREADED
135 case Scope::Filename:
145 if( actValue !=
nullptr )
154 case Scope::ThreadOuter:
159 #if !ALIB_SINGLE_THREADED
192 default:
ALIB_ERROR(
"ALOX",
"Illegal switch state.") break;
204 if( self.actScope == Scope::Global )
206 oldValue= self.globalStore;
207 if ( cmd == CMD_INSERT )
208 self.globalStore= value;
209 else if ( cmd == CMD_REMOVE )
210 self.globalStore= nullptr;
217 if( self.actScope == Scope::ThreadOuter
218 || self.actScope == Scope::ThreadInner )
221 bool isInner= self.actScope == Scope::ThreadInner;
224 if ( cmd != CMD_INSERT && self.threadStore.Size() == 0 )
228 if ( self.actThreadID == threads::UNDEFINED )
229 self.actThreadID= self.scopeInfo.GetThreadID();
232 ALIB_ASSERT( cmd != CMD_REMOVE,
"ALOX" )
235 auto key = typename ScopeStore<T, true>::ThreadMapKey(isInner, self.actThreadID);
236 auto hash= typename decltype(self.threadStore)::HashType ()( key );
237 if ( cmd == CMD_GET )
239 auto it= self.threadStore.Find( key, hash );
240 if ( it != self.threadStore.end() )
248 self.threadStore.InsertUnique( std::make_pair( key, value), hash );
257 if ( cmd == CMD_INSERT && value ==
nullptr )
260 if ( self.lazyLanguageNode
261 || ( self.actStringTreeNode.IsInvalid() && cmd == CMD_INSERT ) )
262 self.initCursor(
true );
264 oldValue= *self.actStringTreeNode;
265 if ( cmd == CMD_INSERT ) *self.actStringTreeNode= value;
266 else if ( cmd == CMD_REMOVE ) *self.actStringTreeNode=
nullptr;
274 while ( self.walking )
switch( self.actScope )
276 case Scope::ThreadInner:
279 if ( self.walkNextThreadIdx == -2 )
281 self.walkNextThreadIdx= -1;
282 #if !ALIB_SINGLE_THREADED
283 if ( self.threadStore.Size() != 0 )
286 if ( it != self.threadStore.end() )
288 self.walkThreadValues= &it.Mapped();
289 self.walkNextThreadIdx= int( self.walkThreadValues->size() );
296 if ( self.walkNextThreadIdx > 0 )
298 --self.walkNextThreadIdx;
299 return (*self.walkThreadValues)[size_t(self.walkNextThreadIdx)];
303 self.actScope= Scope::Method;
306 if ( self.walkLocalObject !=
nullptr )
307 return self.walkLocalObject;
312 case Scope::Filename:
315 if( self.lazyLanguageNode )
316 self.initCursor(
false );
318 while( self.actStringTreeNode.IsValid() )
320 T actValue= *self.actStringTreeNode;
321 self.actStringTreeNode.GoToParent();
322 if( actValue !=
nullptr )
326 self.actScope= Scope::ThreadOuter;
327 self.walkNextThreadIdx= -2;
331 case Scope::ThreadOuter:
334 if ( self.walkNextThreadIdx == -2 )
336 #if !ALIB_SINGLE_THREADED
337 if ( self.threadStore.Size() != 0 )
340 if ( it != self.threadStore.end() )
342 self.walkThreadValues= &it.Mapped();
343 self.walkNextThreadIdx= int( self.walkThreadValues->size() );
350 if ( self.walkNextThreadIdx > 0 )
352 --self.walkNextThreadIdx;
353 return (*self.walkThreadValues)[size_t(self.walkNextThreadIdx)];
357 self.actScope= Scope::Global;
364 return self.globalStore;
368 default:
ALIB_ERROR(
"ALOX",
"Illegal switch state.") break;
380 if( self.actScope == Scope::Global )
382 oldValue= self.globalStore;
383 if ( cmd == CMD_INSERT ) self.globalStore= value;
384 else if ( cmd == CMD_REMOVE ) self.globalStore= nullptr;
391 if( self.actScope == Scope::ThreadOuter
392 || self.actScope == Scope::ThreadInner )
395 bool isInner= self.actScope == Scope::ThreadInner;
398 if ( cmd != CMD_INSERT && self.threadStore.Size() == 0 )
402 if ( self.actThreadID == threads::UNDEFINED )
403 self.actThreadID= self.scopeInfo.GetThreadID();
407 StdVectorMono<T>* values;
409 values= &self.threadStore.EmplaceIfNotExistent(
410 typename ScopeStore<T, true>::ThreadMapKey(isInner, self.actThreadID),
411 self.threadStore.GetAllocator() ).first.Mapped();
415 if ( cmd == CMD_GET )
416 return ( values->size() > 0) ? (*values)[ values->size() -1 ] :
nullptr;
419 if ( cmd == CMD_INSERT )
421 values->emplace_back( value );
426 if ( cmd == CMD_REMOVE && values->size() > 0)
429 if ( value == nullptr )
431 oldValue= values->back();
437 for (
auto rem= values->begin() ; rem != values->end(); ++rem )
438 if ( (*rem) == value )
442 values->erase( rem );
453 if ( cmd == CMD_INSERT && value ==
nullptr )
456 if ( self.lazyLanguageNode
457 || ( self.actStringTreeNode.IsInvalid() && cmd == CMD_INSERT ) )
458 self.initCursor(
true );
460 oldValue= *self.actStringTreeNode;
461 if ( cmd == CMD_INSERT ) *self.actStringTreeNode= value;
462 else if ( cmd == CMD_REMOVE ) *self.actStringTreeNode=
nullptr;
473template<
typename T,
bool TStackedThreadValues>
482 #if defined( _WIN32 )
494 if ( remainingPath.IsNotEmpty() )
528template<
typename T,
bool TStackedThreadValues>
533#if !ALIB_SINGLE_THREADED
550template class ScopeStore <NString , true>;
553template class ScopeStore <PrefixLogable* , true>;
556template class ScopeStore <SSMap<int>*,
false>;
559template class ScopeStore <SSMap<Box>*,
false>;
threads::ThreadID GetThreadID()
threads::ThreadID actThreadID
Actual thread ID.
Scope actScope
The actual scope of a walk.
TLanguageStore languageStore
StringTree to store data for language-related scopes (path,source,method).
T globalStore
The value of the global scope.
void initCursor(bool create)
ALIB_DLL ScopeStore(ScopeInfo &scopeInfo, MonoAllocator &monoAllocator)
bool lazyLanguageNode
Flag used to lazily create the key to language-related scope values.
HashMap< MonoAllocator, ThreadMapKey, TThreadMapValue, BoolThreadIDHash > threadStore
std::pair< bool, threads::ThreadID > ThreadMapKey
Key type for the thread store.
TLanguageStore::Cursor actStringTreeNode
The actual language related scope's map node.
int walkNextThreadIdx
The next value of a walk during Scope::ThreadInner/Outer.
T walkLocalObject
The 'local object' returned by a walk after Scope::ThreadInner and before Scope::Method.
ALIB_DLL ~ScopeStore()
Destructor.
ALIB_DLL void InitWalk(Scope startScope, const T localObject)
ALIB_DLL void InitAccess(Scope scope, int pathLevel, threads::ThreadID threadID)
bool walking
Indicates if currently a scope walk is active.
int actPathLevel
The path level when using access methods.
ScopeInfo & scopeInfo
ScopeInfo of 'our' lox.
TThreadMapValue * walkThreadValues
The list of values of Scope::ThreadOuter/Inner during a walk.
ALIB_DLL integer SearchAndReplace(TChar needle, TChar replacement, integer startIdx=0, integer endIdx=strings::MAX_LEN)
TAString & _(const TAppendable &src)
#define IF_ALIB_THREADS(...)
#define ALIB_ASSERT(cond, domain)
#define ALIB_ERROR(domain,...)
#define ALIB_SINGLE_THREADED
integer ThreadID
The ALib thread identifier type.
LocalString< 512 > String512
Type alias name for TLocalString<character,512>.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
T doWalk(ScopeStore< T, TStackedThreadValues > &self)