You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

623 lines
23 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: winstl/system/environment_sequence.hpp
  3. *
  4. * Purpose: basic_environment_sequence class.
  5. *
  6. * Created: 31st December 2002
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file winstl/system/environment_sequence.hpp
  40. *
  41. * \brief [C++ only] Definition of the winstl::basic_environment_sequence
  42. * class template
  43. * (\ref group__library__system "System" Library).
  44. */
  45. #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE
  46. #define WINSTL_INCL_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define WINSTL_VER_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE_MAJOR 4
  49. # define WINSTL_VER_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE_MINOR 1
  50. # define WINSTL_VER_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE_REVISION 1
  51. # define WINSTL_VER_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE_EDIT 82
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef WINSTL_INCL_WINSTL_H_WINSTL
  57. # include <winstl/winstl.h>
  58. #endif /* !WINSTL_INCL_WINSTL_H_WINSTL */
  59. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  60. # include <stlsoft/util/std/iterator_helper.hpp>
  61. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  62. #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
  63. # include <winstl/system/system_traits.hpp>
  64. #endif /* !WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS */
  65. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
  66. # include <stlsoft/memory/auto_buffer.hpp>
  67. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
  68. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_GENERATORS
  69. # include <stlsoft/util/std/iterator_generators.hpp>
  70. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_GENERATORS */
  71. #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
  72. # include <winstl/memory/processheap_allocator.hpp>
  73. #endif /* !WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR */
  74. #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
  75. # include <stlsoft/collections/util/collections.hpp>
  76. #endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
  77. #ifndef STLSOFT_INCL_ALGORITHM
  78. # define STLSOFT_INCL_ALGORITHM
  79. # include <algorithm>
  80. #endif /* !STLSOFT_INCL_ALGORITHM */
  81. #ifndef _WINSTL_WINDOW_FUNCTIONALS_NO_STD
  82. # ifndef STLSOFT_INCL_FUNCTIONAL
  83. # define STLSOFT_INCL_FUNCTIONAL
  84. # include <functional>
  85. # endif /* !STLSOFT_INCL_FUNCTIONAL */
  86. #else /* ? _WINSTL_WINDOW_FUNCTIONALS_NO_STD */
  87. # error Now need to write that std_binary_function stuff!!
  88. #endif /* _WINSTL_WINDOW_FUNCTIONALS_NO_STD */
  89. /* /////////////////////////////////////////////////////////////////////////
  90. * Namespace
  91. */
  92. #ifndef _WINSTL_NO_NAMESPACE
  93. # if defined(_STLSOFT_NO_NAMESPACE) || \
  94. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  95. /* There is no stlsoft namespace, so must define ::winstl */
  96. namespace winstl
  97. {
  98. # else
  99. /* Define stlsoft::winstl_project */
  100. namespace stlsoft
  101. {
  102. namespace winstl_project
  103. {
  104. # endif /* _STLSOFT_NO_NAMESPACE */
  105. #endif /* !_WINSTL_NO_NAMESPACE */
  106. /* /////////////////////////////////////////////////////////////////////////
  107. * Classes
  108. */
  109. /** \brief STL-like sequence for the system environment variables
  110. *
  111. * \ingroup group__library__system
  112. *
  113. * \param C The character type
  114. *
  115. * \note Even though Win32 treats environment variables in a case-insensitive
  116. * manner, it is possible for the raw environment information (access via the
  117. * GetEnvironmentStrings() function) to contain multiple entries whose names
  118. * differ only by case. Thus, later versions of the sequence class support the
  119. * \c ignoreCase member constant, which is passed by default to the
  120. * constructor, in order to facilitate "normal" Win32 operation while
  121. * supporting all possible modes.
  122. */
  123. template <ss_typename_param_k C>
  124. class basic_environment_sequence
  125. : public stlsoft_ns_qual(stl_collection_tag)
  126. {
  127. /// \name Member Types
  128. /// @{
  129. public:
  130. /// The character type
  131. typedef C char_type;
  132. /// Structure representing the items
  133. struct symbol
  134. {
  135. /// The symbol name
  136. char_type const* name;
  137. /// The symbol value
  138. char_type const* value;
  139. };
  140. /// The value type
  141. typedef symbol value_type;
  142. /// The current parameterisation of the type
  143. typedef basic_environment_sequence<C> class_type;
  144. /// The non-mutable (const) pointer type
  145. typedef value_type const* const_pointer;
  146. /// The non-mutable (const) reference type
  147. typedef value_type const& const_reference;
  148. /// The size type
  149. typedef ws_size_t size_type;
  150. /// The difference type
  151. typedef ws_ptrdiff_t difference_type;
  152. /// The non-mutating (const) iterator type
  153. typedef
  154. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  155. ss_typename_type_k
  156. #endif /* compiler */
  157. stlsoft_ns_qual(pointer_iterator) < value_type
  158. , const_pointer
  159. , const_reference
  160. >::type const_iterator;
  161. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  162. /// The non-mutating (const) reverse iterator type
  163. typedef
  164. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  165. ss_typename_type_k
  166. #endif /* compiler */
  167. stlsoft_ns_qual(const_reverse_iterator_generator)< const_iterator
  168. , value_type
  169. , const_reference
  170. , const_pointer
  171. , difference_type
  172. >::type const_reverse_iterator;
  173. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  174. /// @}
  175. /// \name Member Constants
  176. /// @{
  177. public:
  178. enum
  179. {
  180. showHidden = 0x0001 //!< Include the hidden environment variables (those beginning with '=') in the sequence
  181. , noSort = 0x0002 //!< Do not explicitly sort the contents
  182. , ignoreCase = 0x0004 //!< Ignore case in when comparing names / values in find() methods
  183. };
  184. /// @}
  185. // Construction
  186. public:
  187. /// Construct a sequence of the current process's environment entries, according
  188. /// to the given criteria
  189. ///
  190. /// \param flags One or more of the member constants
  191. ss_explicit_k basic_environment_sequence(ws_int_t flags = ignoreCase);
  192. /// Destructor, which releases any resources acquired
  193. ~basic_environment_sequence() stlsoft_throw_0();
  194. /// \name Iteration
  195. /// @{
  196. public:
  197. /// Begins the iteration
  198. ///
  199. /// \return An iterator representing the start of the sequence
  200. const_iterator begin() const;
  201. /// Ends the iteration
  202. ///
  203. /// \return An iterator representing the end of the sequence
  204. const_iterator end() const;
  205. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  206. /// Begins the reverse iteration
  207. ///
  208. /// \return An iterator representing the start of the reverse sequence
  209. const_reverse_iterator rbegin() const;
  210. /// Ends the reverse iteration
  211. ///
  212. /// \return An iterator representing the end of the reverse sequence
  213. const_reverse_iterator rend() const;
  214. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  215. /// Searches for an entry holding the given name
  216. ///
  217. /// \param name The name of the entry. Must not be NULL
  218. const_iterator find(char_type const* name) const;
  219. /// Searches for an entry holding the given name and value
  220. ///
  221. /// \param name The name of the entry. Must not be NULL
  222. /// \param value The value of the entry. Must not be NULL
  223. const_iterator find(char_type const* name, char_type const* value) const;
  224. /// @}
  225. /** \brief Size
  226. * @{
  227. *
  228. * \ingroup group__library__system
  229. */
  230. public:
  231. /// Returns the number of elements in the enviroment sequence
  232. size_type size() const;
  233. /// Indicates whether the enviroment sequence is empty
  234. ws_bool_t empty() const;
  235. /// @}
  236. // Accessors
  237. public:
  238. /// Returns the name-value item for the given index
  239. value_type operator [](size_type index) const;
  240. // TODO: Add ARV to this class
  241. // Implementation
  242. private:
  243. typedef stlsoft_ns_qual(auto_buffer_old)< char_type
  244. , processheap_allocator<char_type>
  245. > environment_buffer_type;
  246. typedef stlsoft_ns_qual(auto_buffer_old)< symbol
  247. , processheap_allocator<symbol>
  248. > symbols_buffer_type;
  249. static ws_size_t calc_items_(char_type const* p, char_type const** q, ws_int_t flags);
  250. static void prepare_items_(symbols_buffer_type &symbols, environment_buffer_type &environment, char_type *p, char_type *q, ws_int_t flags);
  251. private:
  252. static ws_int_t compare_strings_(char_type const* s1, char_type const* s2, ws_int_t flags);
  253. public:
  254. /// A function class that compares environment symbols for the basic_environment_sequence class
  255. // [[synesis:class:binary-functor: compare_symbol]]
  256. struct compare_symbol
  257. : stlsoft_ns_qual_std(binary_function)<symbol, symbol, ws_bool_t>
  258. // , stlsoft_ns_qual(base_property)<ws_bool_t, 0>
  259. {
  260. public:
  261. ss_explicit_k compare_symbol(ws_bool_t bIgnoreCase = true)
  262. : m_bIgnoreCase(bIgnoreCase)
  263. // , stlsoft_ns_qual(base_property)<ws_bool_t, 0>(b
  264. {}
  265. public:
  266. /// Function call operator, which returns \c true if \c lhs is lexicographically less than \c rhs
  267. ws_bool_t operator ()(symbol const& lhs, symbol const& rhs)
  268. {
  269. return compare_strings_(lhs.name, rhs.name, m_bIgnoreCase ? ignoreCase : 0) < 0;
  270. }
  271. private:
  272. ws_bool_t m_bIgnoreCase;
  273. };
  274. friend struct compare_symbol; // This is needed by Borland, CodeWarrior, DMC++ and Visual C++
  275. private:
  276. static ws_int_t validate_flags_(ws_int_t flags);
  277. static char_type const* get_environment_strings_();
  278. static void free_environment_strings_(char_type *);
  279. private:
  280. const ws_int_t m_flags; // The flags as specified to the ctor
  281. C const *m_p; // Pointer to the start of the raw environment block
  282. C const *m_q; // Pointer to the (one off the) end of the raw environment block
  283. symbols_buffer_type m_symbols; // Array of symbols representing the parsed environment block
  284. environment_buffer_type m_environment; // The editable (and edited) copy of the environment block
  285. // Not to be implemented
  286. private:
  287. basic_environment_sequence(class_type const&);
  288. class_type const& operator =(class_type const&);
  289. };
  290. /* /////////////////////////////////////////////////////////////////////////
  291. * Typedefs for commonly encountered types
  292. */
  293. /** \brief Specialisation of the basic_environment_sequence template for the ANSI character type \c char
  294. *
  295. * \ingroup group__library__system
  296. */
  297. typedef basic_environment_sequence<ws_char_a_t> environment_sequence_a;
  298. /** \brief Specialisation of the basic_environment_sequence template for the Unicode character type \c wchar_t
  299. *
  300. * \ingroup group__library__system
  301. */
  302. typedef basic_environment_sequence<ws_char_w_t> environment_sequence_w;
  303. /** \brief Specialisation of the basic_environment_sequence template for the Win32 character type \c TCHAR
  304. *
  305. * \ingroup group__library__system
  306. */
  307. typedef basic_environment_sequence<TCHAR> environment_sequence;
  308. ////////////////////////////////////////////////////////////////////////////
  309. // Implementation
  310. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  311. template <ss_typename_param_k C>
  312. inline /* static */ ss_typename_type_ret_k basic_environment_sequence<C>::size_type basic_environment_sequence<C>::calc_items_(ss_typename_type_k basic_environment_sequence<C>::char_type const* p, ss_typename_type_k basic_environment_sequence<C>::char_type const** q, ws_int_t flags)
  313. {
  314. size_type c;
  315. char_type const* v;
  316. for(c = 0, v = p;; ++p)
  317. {
  318. if(*p == 0) // End of an environment variable?
  319. {
  320. if( showHidden == (showHidden & flags) ||
  321. '=' != v[0])
  322. {
  323. ++c;
  324. }
  325. v = p + 1;
  326. if(*(p + 1) == 0) // End of all environment variable
  327. {
  328. *q = p + 1;
  329. break;
  330. }
  331. }
  332. }
  333. return c;
  334. }
  335. template <ss_typename_param_k C>
  336. inline /* static */ void basic_environment_sequence<C>::prepare_items_(ss_typename_type_k basic_environment_sequence<C>::symbols_buffer_type &symbols, ss_typename_type_k basic_environment_sequence<C>::environment_buffer_type &environment, ss_typename_type_k basic_environment_sequence<C>::char_type *p, ss_typename_type_k basic_environment_sequence<C>::char_type* q, ws_int_t flags)
  337. {
  338. ss_typename_type_k environment_buffer_type::iterator env_begin = environment.begin();
  339. ss_typename_type_k symbols_buffer_type::iterator sym_begin = symbols.begin();
  340. char_type* begin = p;
  341. char_type *const end = q;
  342. char_type* last_src = begin;
  343. char_type* last_dest = &*env_begin; // Need this because may be using VC7.0 style pointer iterators
  344. // This loop does two things in one go (for efficiency).
  345. //
  346. // Firstly, it copies the source (which is read-only) to the m_environment
  347. // buffer.
  348. //
  349. // Secondly, it processes the source, and adjusts the m_symbols and
  350. // m_environment contents accordingly.
  351. for(; begin != end;)
  352. {
  353. *env_begin = *begin;
  354. if(*begin == 0)
  355. {
  356. const ws_bool_t bHidden = ('=' == last_dest[0]);
  357. sym_begin->name = last_dest;
  358. for(; last_src != begin; ++last_src, ++last_dest)
  359. {
  360. if( *last_src == '=' &&
  361. ( !bHidden ||
  362. sym_begin->name != last_dest))
  363. {
  364. *last_dest = '\0';
  365. // ++last_src;
  366. ++last_dest;
  367. break;
  368. }
  369. }
  370. sym_begin->value = last_dest;
  371. last_src = ++begin;
  372. last_dest = &*++env_begin;
  373. if( showHidden == (showHidden & flags) ||
  374. !bHidden)
  375. {
  376. ++sym_begin;
  377. }
  378. }
  379. else
  380. {
  381. ++begin;
  382. ++env_begin;
  383. }
  384. }
  385. if(0 == (noSort & flags))
  386. {
  387. winstl_ns_qual_std(sort)(symbols.begin(), symbols.end(), compare_symbol());
  388. }
  389. }
  390. template <ss_typename_param_k C>
  391. inline /* static */ ws_int_t basic_environment_sequence<C>::validate_flags_(ws_int_t flags)
  392. {
  393. const ws_int_t validFlags = 0
  394. | showHidden
  395. | noSort
  396. | ignoreCase
  397. | 0;
  398. WINSTL_MESSAGE_ASSERT("Specification of unrecognised/unsupported flags", flags == (flags & validFlags));
  399. STLSOFT_SUPPRESS_UNUSED(validFlags);
  400. return flags;
  401. }
  402. STLSOFT_TEMPLATE_SPECIALISATION
  403. inline /* static */ basic_environment_sequence<ws_char_a_t>::char_type const* basic_environment_sequence<ws_char_a_t>::get_environment_strings_()
  404. {
  405. return static_cast<ws_char_a_t const*>(::GetEnvironmentStringsA());
  406. }
  407. STLSOFT_TEMPLATE_SPECIALISATION
  408. inline /* static */ basic_environment_sequence<ws_char_w_t>::char_type const* basic_environment_sequence<ws_char_w_t>::get_environment_strings_()
  409. {
  410. return static_cast<ws_char_w_t const*>(::GetEnvironmentStringsW());
  411. }
  412. STLSOFT_TEMPLATE_SPECIALISATION
  413. inline /* static */ void basic_environment_sequence<ws_char_a_t>::free_environment_strings_(basic_environment_sequence<ws_char_a_t>::char_type *s)
  414. {
  415. ::FreeEnvironmentStringsA(s);
  416. }
  417. STLSOFT_TEMPLATE_SPECIALISATION
  418. inline /* static */ void basic_environment_sequence<ws_char_w_t>::free_environment_strings_(basic_environment_sequence<ws_char_w_t>::char_type *s)
  419. {
  420. ::FreeEnvironmentStringsW(s);
  421. }
  422. STLSOFT_TEMPLATE_SPECIALISATION
  423. inline /* static */ ws_int_t basic_environment_sequence<ws_char_a_t>::compare_strings_(ws_char_a_t const* s1, ws_char_a_t const* s2, ws_int_t flags)
  424. {
  425. typedef system_traits<ws_char_a_t> traits_t;
  426. return (ignoreCase & flags) ? traits_t::str_compare_no_case(s1, s2) : traits_t::str_compare(s1, s2);
  427. }
  428. STLSOFT_TEMPLATE_SPECIALISATION
  429. inline /* static */ ws_int_t basic_environment_sequence<ws_char_w_t>::compare_strings_(ws_char_w_t const* s1, ws_char_w_t const* s2, ws_int_t flags)
  430. {
  431. typedef system_traits<ws_char_w_t> traits_t;
  432. return (ignoreCase & flags) ? traits_t::str_compare_no_case(s1, s2) : traits_t::str_compare(s1, s2);
  433. }
  434. template <ss_typename_param_k C>
  435. inline /* ss_explicit_k */ basic_environment_sequence<C>::basic_environment_sequence(ws_int_t flags)
  436. : m_flags(validate_flags_(flags))
  437. , m_p(get_environment_strings_())
  438. , m_symbols(calc_items_(m_p, &m_q, m_flags))
  439. , m_environment(static_cast<ss_size_t>(m_q - m_p))
  440. {
  441. prepare_items_(m_symbols, m_environment, const_cast<char_type*>(m_p), const_cast<char_type*>(m_q), flags);
  442. }
  443. template <ss_typename_param_k C>
  444. inline basic_environment_sequence<C>::~basic_environment_sequence() stlsoft_throw_0()
  445. {
  446. // The documentation for FreeEnvironmentStrings does not explicitly state
  447. // that it is legal to free a null string, so we must do the test.
  448. if(0 != m_p)
  449. {
  450. free_environment_strings_(const_cast<char_type*>(m_p));
  451. }
  452. }
  453. template <ss_typename_param_k C>
  454. inline ss_typename_type_ret_k basic_environment_sequence<C>::const_iterator basic_environment_sequence<C>::begin() const
  455. {
  456. return &*m_symbols.begin();
  457. }
  458. template <ss_typename_param_k C>
  459. inline ss_typename_type_ret_k basic_environment_sequence<C>::const_iterator basic_environment_sequence<C>::end() const
  460. {
  461. return &*m_symbols.end();
  462. }
  463. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  464. template <ss_typename_param_k C>
  465. inline ss_typename_type_ret_k basic_environment_sequence<C>::const_reverse_iterator basic_environment_sequence<C>::rbegin() const
  466. {
  467. return const_reverse_iterator(end());
  468. }
  469. template <ss_typename_param_k C>
  470. inline ss_typename_type_ret_k basic_environment_sequence<C>::const_reverse_iterator basic_environment_sequence<C>::rend() const
  471. {
  472. return const_reverse_iterator(begin());
  473. }
  474. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  475. template <ss_typename_param_k C>
  476. inline ss_typename_type_ret_k basic_environment_sequence<C>::const_iterator basic_environment_sequence<C>::find(ss_typename_type_k basic_environment_sequence<C>::char_type const* name) const
  477. {
  478. const_iterator b = this->begin();
  479. const_iterator e = this->end();
  480. for(; b != e; ++b)
  481. {
  482. if(0 == compare_strings_(name, (*b).name, m_flags))
  483. {
  484. break;
  485. }
  486. }
  487. return b;
  488. }
  489. template <ss_typename_param_k C>
  490. inline ss_typename_type_ret_k basic_environment_sequence<C>::const_iterator basic_environment_sequence<C>::find(ss_typename_type_k basic_environment_sequence<C>::char_type const* name, ss_typename_type_k basic_environment_sequence<C>::char_type const* value) const
  491. {
  492. const_iterator b = this->begin();
  493. const_iterator e = this->end();
  494. for(; b != e; ++b)
  495. {
  496. if( 0 == compare_strings_(name, (*b).name, m_flags) &&
  497. ( NULL == value ||
  498. 0 == compare_strings_(value, (*b).value, m_flags)))
  499. {
  500. break;
  501. }
  502. }
  503. return b;
  504. }
  505. template <ss_typename_param_k C>
  506. inline ss_typename_type_ret_k basic_environment_sequence<C>::size_type basic_environment_sequence<C>::size() const
  507. {
  508. return m_symbols.size();
  509. }
  510. template <ss_typename_param_k C>
  511. inline ws_bool_t basic_environment_sequence<C>::empty() const
  512. {
  513. return size() == 0;
  514. }
  515. template <ss_typename_param_k C>
  516. inline ss_typename_type_ret_k basic_environment_sequence<C>::value_type basic_environment_sequence<C>::operator [](ss_typename_type_k basic_environment_sequence<C>::size_type index) const
  517. {
  518. WINSTL_MESSAGE_ASSERT("index access out of range in basic_environment_sequence", index < size() + 1); // Has to be +1, since legitimate to take address of one-past-the-end
  519. return m_symbols.data()[index];
  520. }
  521. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  522. ////////////////////////////////////////////////////////////////////////////
  523. // Unit-testing
  524. #ifdef STLSOFT_UNITTEST
  525. # include "./unittest/environment_sequence_unittest_.h"
  526. #endif /* STLSOFT_UNITTEST */
  527. /* ////////////////////////////////////////////////////////////////////// */
  528. #ifndef _WINSTL_NO_NAMESPACE
  529. # if defined(_STLSOFT_NO_NAMESPACE) || \
  530. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  531. } // namespace winstl
  532. # else
  533. } // namespace winstl_project
  534. } // namespace stlsoft
  535. # endif /* _STLSOFT_NO_NAMESPACE */
  536. #endif /* !_WINSTL_NO_NAMESPACE */
  537. /* ////////////////////////////////////////////////////////////////////// */
  538. #endif /* WINSTL_INCL_WINSTL_SYSTEM_HPP_ENVIRONMENT_SEQUENCE */
  539. /* ///////////////////////////// end of file //////////////////////////// */