00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifndef STLSOFT_INCL_H_STLSOFT
00071 # include "stlsoft.h"
00072 #endif
00073
00074 # ifndef STLSOFT_INCL_H_STLSOFT_SIMPLE_STRING
00075 # include "stlsoft_simple_string.h"
00076 # endif
00077
00078
00079
00080
00081
00082 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_TOKENISER
00083 # include "stlsoft_string_tokeniser.h"
00084 #endif
00085
00086
00087
00088
00089 #ifndef __STLSOFT_COMPILER_IS_WATCOM
00090 # ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00091 # include "stlsoft_iterator.h"
00092 # endif
00093 #endif
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #ifndef _STLSOFT_NO_NAMESPACE
00106 namespace stlsoft
00107 {
00108 #endif
00109
00110
00111
00114
00118
00123
00124
00125
00126
00127
00128 template <ss_typename_param_k T>
00129 inline void call_set_null(T *&pt, void (T::*F)())
00130 {
00131 stlsoft_assert(NULL != pt);
00132
00133 (pt->*F)();
00134
00135 pt = NULL;
00136 }
00137
00138
00139
00140
00141
00143 template <ss_typename_param_k S>
00144 class searchspec_sequence
00145 {
00146 public:
00148 typedef S find_sequence_type;
00150 typedef searchspec_sequence<S> class_type;
00151 private:
00152 typedef searchspec_sequence<S> outer_class_type;
00153 typedef ss_typename_type_k find_sequence_type::traits_type traits_type;
00154 public:
00156 typedef ss_typename_type_k find_sequence_type::char_type char_type;
00158 typedef ss_typename_type_k find_sequence_type::value_type value_type;
00160 typedef ss_typename_type_k find_sequence_type::size_type size_type;
00162 typedef ss_typename_type_k find_sequence_type::const_reference const_reference;
00164 class const_iterator;
00165 private:
00166
00167 typedef basic_simple_string<char_type> string_type;
00168
00169
00170
00171
00172
00173 typedef string_tokeniser<string_type, char> tokeniser_type;
00174
00175 public:
00182 searchspec_sequence(char_type const *searchSpec, char_type delimiter)
00183 : m_rootDir(get_root_dir())
00184 , m_searchSpec(searchSpec)
00185 , m_delimiter(delimiter)
00186 , m_flags(0)
00187 {}
00195 searchspec_sequence(char_type const *searchSpec, char_type delimiter, ss_int_t flags)
00196 : m_rootDir(get_root_dir())
00197 , m_searchSpec(searchSpec)
00198 , m_delimiter(delimiter)
00199 , m_flags(flags)
00200 {}
00206 searchspec_sequence(char_type const *rootDir, char_type const *searchSpec, char_type delimiter)
00207 : m_rootDir(rootDir)
00208 , m_searchSpec(searchSpec)
00209 , m_delimiter(delimiter)
00210 , m_flags(0)
00211 {}
00218 searchspec_sequence(char_type const *rootDir, char_type const *searchSpec, char_type delimiter, ss_int_t flags)
00219 : m_rootDir(rootDir)
00220 , m_searchSpec(searchSpec)
00221 , m_delimiter(delimiter)
00222 , m_flags(flags)
00223 {}
00224
00225 private:
00226 struct search_state
00227 {
00228 string_type m_rootDir;
00229 ss_int_t m_flags;
00230 tokeniser_type m_tokens;
00231 ss_typename_type_k tokeniser_type::const_iterator m_tokensNext;
00232 ss_typename_type_k tokeniser_type::const_iterator m_tokensEnd;
00233 find_sequence_type *m_entries;
00234 ss_typename_type_k find_sequence_type::const_iterator m_entriesNext;
00235 ss_typename_type_k find_sequence_type::const_iterator m_entriesEnd;
00236 ss_sint32_t m_cRefs;
00237
00238 private:
00239 search_state(char_type const *rootDir, char_type const *searchSpec, char_type delimiter, ss_int_t flags)
00240 : m_rootDir(rootDir)
00241 , m_flags(flags)
00242 , m_tokens(searchSpec, delimiter)
00243 , m_tokensNext(m_tokens.begin())
00244 , m_tokensEnd(m_tokens.end())
00245 #if defined(__STLSOFT_COMPILER_IS_VECTORC)
00246 , m_entries(new find_sequence_type(m_rootDir.c_str(), (*m_tokensNext).c_str(), m_flags))
00247 #else
00248 , m_entries(new find_sequence_type(c_str_ptr(m_rootDir), c_str_ptr(*m_tokensNext), m_flags))
00249 #endif
00250 , m_entriesNext(m_entries->begin())
00251 , m_entriesEnd(m_entries->end())
00252 , m_cRefs(1)
00253 {
00254 while(m_entriesNext == m_entriesEnd)
00255 {
00256 ++m_tokensNext;
00257
00258 if(m_tokensNext == m_tokensEnd)
00259 {
00260 break;
00261 }
00262 else
00263 {
00264 stlsoft_assert(NULL != m_entries);
00265
00266 stlsoft_destroy_instance_fn(m_entries);
00267 #if defined(__STLSOFT_COMPILER_IS_VECTORC)
00268 m_entries = new(m_entries) find_sequence_type(m_rootDir.c_str(), (*m_tokensNext).c_str(), m_flags);
00269 #else
00270 m_entries = new(m_entries) find_sequence_type(c_str_ptr(m_rootDir), c_str_ptr(*m_tokensNext), m_flags);
00271 #endif
00272
00273 m_entriesEnd = m_entries->end();
00274 m_entriesNext = m_entries->begin();
00275 }
00276 }
00277 }
00278
00279 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00280 _MSC_VER < 1300
00281 friend class const_iterator;
00282 #endif
00283
00284 public:
00285 static search_state *create(char_type const *rootDir, char_type const *searchSpec, char_type delimiter, ss_int_t flags)
00286 {
00287 search_state *ss = new search_state(rootDir, searchSpec, delimiter, flags);
00288
00289 if(ss->m_tokensNext == ss->m_tokensEnd)
00290 {
00291 delete ss;
00292
00293 ss = NULL;
00294 }
00295
00296 return ss;
00297 }
00298
00299 public:
00300 bool next()
00301 {
00302 if(m_tokensNext == m_tokensEnd)
00303 {
00304 return false;
00305 }
00306
00307 stlsoft_assert(m_tokensNext != m_tokensEnd);
00308 stlsoft_assert(NULL != m_entries || m_tokensNext == m_tokensEnd);
00309
00310
00311
00312
00313
00314
00315 ++m_entriesNext;
00316
00317 while(m_entriesNext == m_entriesEnd)
00318 {
00319 ++m_tokensNext;
00320
00321 if(m_tokensNext == m_tokensEnd)
00322 {
00323 return false;
00324 }
00325 else
00326 {
00327 stlsoft_assert(NULL != m_entries);
00328
00329 stlsoft_destroy_instance_fn(m_entries);
00330 #if defined(__STLSOFT_COMPILER_IS_VECTORC)
00331 m_entries = new(m_entries) find_sequence_type(m_rootDir.c_str(), (*m_tokensNext).c_str(), m_flags);
00332 #else
00333 m_entries = new(m_entries) find_sequence_type(c_str_ptr(m_rootDir), c_str_ptr(*m_tokensNext), m_flags);
00334 #endif
00335
00336 m_entriesEnd = m_entries->end();
00337 m_entriesNext = m_entries->begin();
00338 }
00339 }
00340
00341 return true;
00342 }
00343
00344 void Release()
00345 {
00346 if(0 == --m_cRefs)
00347 {
00348 delete this;
00349 }
00350 }
00351 #if defined(__STLSOFT_COMPILER_IS_GCC)
00352 protected:
00353 #else
00354 private:
00355 #endif
00356 ~search_state()
00357 {
00358 delete m_entries;
00359 }
00360 };
00361
00362 public:
00364 class const_iterator
00365 {
00366 private:
00367 typedef const_iterator class_type;
00368
00369 private:
00370 friend class searchspec_sequence<S>;
00371
00372 const_iterator(char_type const *rootDir, char_type const *searchSpec, char_type delimiter, ss_int_t flags)
00373 : m_searchState(search_state::create(rootDir, searchSpec, delimiter, flags))
00374 {}
00375
00376 public:
00378 const_iterator()
00379 : m_searchState(NULL)
00380 {}
00382 ~const_iterator()
00383 {
00384 if(NULL != m_searchState)
00385 {
00386 m_searchState->Release();
00387 }
00388 }
00389
00391 const_iterator(class_type const &rhs)
00392 : m_searchState(rhs.m_searchState)
00393 {
00394 if(NULL != m_searchState)
00395 {
00396 ++m_searchState->m_cRefs;
00397 }
00398 }
00399
00400 class_type &operator =(class_type const &rhs)
00401 {
00402 if(NULL != m_searchState)
00403 {
00404 m_searchState->Release();
00405 }
00406
00407 m_searchState = rhs.m_searchState;
00408
00409 if(NULL != m_searchState)
00410 {
00411 ++m_searchState->m_cRefs;
00412 }
00413
00414 return *this;
00415 }
00416
00417 public:
00418 class_type &operator ++()
00419 {
00420 stlsoft_assert(NULL != m_searchState);
00421
00422 if(!m_searchState->next())
00423 {
00424 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00425 _MSC_VER < 1300
00426 m_searchState->Release();
00427
00428 m_searchState = NULL;
00429 #else
00430 call_set_null(m_searchState, &search_state::Release);
00431 #endif
00432 }
00433
00434 return *this;
00435 }
00436
00437 class_type operator ++(int)
00438 {
00439 class_type ret(*this);
00440
00441 operator ++();
00442
00443 return ret;
00444 }
00445
00447 const value_type operator *() const
00448 {
00449 stlsoft_assert(NULL != m_searchState);
00450
00451 return *m_searchState->m_entriesNext;
00452 }
00453
00454 ss_bool_t operator ==(class_type const &rhs) const
00455 {
00456
00457 return (NULL == m_searchState) && (NULL == rhs.m_searchState);
00458 }
00459 ss_bool_t operator !=(class_type const &rhs) const
00460 {
00461 return !operator ==(rhs);
00462 }
00463
00464 private:
00465 search_state *m_searchState;
00466 };
00467
00468 public:
00472 const_iterator begin() const
00473 {
00474 #if defined(__STLSOFT_COMPILER_IS_VECTORC)
00475 return const_iterator(m_rootDir.c_str(), (m_searchSpec).c_str(), m_delimiter, m_flags);
00476 #else
00477 return const_iterator(c_str_ptr(m_rootDir), c_str_ptr(m_searchSpec), m_delimiter, m_flags);
00478 #endif
00479 }
00483 const_iterator end() const
00484 {
00485 return const_iterator();
00486 }
00487
00488 public:
00490 ss_bool_t empty() const
00491 {
00492 return begin() == end();
00493 }
00494
00495
00496 private:
00498 static char_type const *get_root_dir()
00499 {
00500 static char_type s_rootDir[2] = { '.', '\0' };
00501
00502 return s_rootDir;
00503 }
00504
00505
00506 private:
00507 string_type m_rootDir;
00508 string_type m_searchSpec;
00509 char_type m_delimiter;
00510 ss_int_t m_flags;
00511 };
00512
00514
00515
00516 template <ss_typename_param_k S>
00517 inline ss_bool_t is_empty(searchspec_sequence<S> const &s)
00518 {
00519 return s.empty();
00520 }
00521
00523
00524
00525 #ifdef STLSOFT_UNITTEST
00526
00527 namespace unittest
00528 {
00529 ss_bool_t test_stlsoft_searchspec_sequence(unittest_reporter *r)
00530 {
00531 ss_bool_t bSuccess = true;
00532
00533 unittest_initialiser init(r, "STLSoft", "searchspec_sequence", __FILE__);
00534
00535 #if 0
00536 if(<<TODO>>)
00537 {
00538 r->report("<<TODO>> failed ", __LINE__);
00539 bSuccess = false;
00540 }
00541 #endif
00542
00543 return bSuccess;
00544 }
00545
00546 unittest_registrar unittest_stlsoft_searchspec_sequence(test_stlsoft_searchspec_sequence);
00547
00548 }
00549
00550 #endif
00551
00553
00554
00555 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00556
00557
00558 #endif
00559
00560
00561
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574